diff --git a/BUILD.gn b/BUILD.gn index c6b75850..31d7049 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -784,6 +784,16 @@ } } +if ((is_linux || is_win) && enable_remoting && !use_ozone) { + # This group is used for network annotation check test. + group("shipped_binaries") { + deps = [ + "//chrome:chrome", + "//remoting/host:host", + ] + } +} + if (is_fuchsia) { # TODO(https://crbug.com/731217): This can't practically be in //v8 without # duplicating all the Fuchsia running infrastructure there.
diff --git a/DEPS b/DEPS index 6e5dbd4..8e3131a 100644 --- a/DEPS +++ b/DEPS
@@ -116,15 +116,15 @@ # 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': '655a9bc2d20b6879e1a644613899ca05aa6121ad', + 'v8_revision': '2ecd5f54a495900cffb0af290eb2eba39017263c', # 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. - 'swarming_revision': '7f463e66e1c4bb830ef3de9d046aa227d28e1b00', + 'swarming_revision': 'b6e9e23e4e79249bd4f95735205ffb7c3f9f0912', # 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': 'ffdbfa393fcc5185672276f8fb5690e5f423b791', + 'angle_revision': '0e604f9f11071c862b21c2c871c03dc7932d53d9', # 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. @@ -172,7 +172,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '1e54003639e3666dd8abe9b7af69a6c673a96ec0', + 'catapult_revision': 'd11507507daae2e80b82614c6bbf07975e8843b7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -220,7 +220,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': 'f5b4a8eee3646b53640164037057cd46d3cc605b', + 'spv_tools_revision': '101c113f649bc27371370a176043e495001f732f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -236,7 +236,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': '391c8a9224e5bf02690722c06973af8427bdaa6b', + 'dawn_revision': '63997221d7d880d8d1783abe326b90cd95cd92d2', } # Only these hosts are allowed for dependencies in this DEPS file. @@ -512,7 +512,7 @@ 'packages': [ { 'package': 'chromium/third_party/android_tools_bundletool', - 'version': 'version:0.6.2-cr0', + 'version': 'version:0.7.1-cr0', }, ], 'condition': 'checkout_android', @@ -651,7 +651,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '21f7091b9a09cfd8aec19b9a5d4b22a9d662edef', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '44bef83f2be0f01d410f436c519da2987cca5747', 'condition': 'checkout_linux', }, @@ -671,12 +671,12 @@ }, 'src/third_party/custom_tabs_client/src': { - 'url': Var('chromium_git') + '/custom-tabs-client.git' + '@' + 'c813ed8fcc4ece1838dba8dddf6d8ca39d6c6785', + 'url': Var('chromium_git') + '/custom-tabs-client.git' + '@' + '4c092f007199e64798a0c6d48c4a847758392952', 'condition': 'checkout_android', }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '7da982abf99f9feced310f51a9fc058c4ed7baaf', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'e47ac15d93b88d76e38e56054a15dfb916b30112', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -902,7 +902,7 @@ }, 'src/third_party/libvpx/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + '4a8c248744500f9caf00588ca312efce5659e45e', + Var('chromium_git') + '/webm/libvpx.git' + '@' + 'ac3eccdc24bccece5f73ee67b88154f3bf4a4e9a', 'src/third_party/libwebm/source': Var('chromium_git') + '/webm/libwebm.git' + '@' + 'e4931ebc0a816458c18a6734e91a4d1b5acd5c56', @@ -1160,7 +1160,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '5b6cbd789b9b91b4e46dde883c9f2ecb31eddade', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'b6787bcd79f88015b588d5a3b79b82fc47584a3d', + Var('webrtc_git') + '/src.git' + '@' + '44974e143c90ad34b3714e7a2972278fe2cff4af', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1191,7 +1191,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@739d7c2cc95212e0e06937501280f29cc42df70d', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0d23e71a1714b6b2b03c2261d36ff72130010eb6', 'condition': 'checkout_src_internal', }, @@ -1824,6 +1824,17 @@ 'dep_type': 'cipd', }, + 'src/third_party/android_deps/libs/com_google_protobuf_protobuf_lite': { + 'packages': [ + { + 'package': 'chromium/third_party/android_deps/libs/com_google_protobuf_protobuf_lite', + 'version': 'version:3.0.1-cr0', + }, + ], + 'condition': 'checkout_android', + 'dep_type': 'cipd', + }, + 'src/third_party/android_deps/libs/com_squareup_javapoet': { 'packages': [ {
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index 0c21b9a1..5302d57c 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -623,6 +623,8 @@ "browser/net/input_stream_reader.h", "browser/net/token_binding_manager.cc", "browser/net/token_binding_manager.h", + "browser/net_helpers.cc", + "browser/net_helpers.h", "browser/parent_compositor_draw_constraints.cc", "browser/parent_compositor_draw_constraints.h", "browser/parent_output_surface.cc",
diff --git a/android_webview/browser/aw_proxying_url_loader_factory.cc b/android_webview/browser/aw_proxying_url_loader_factory.cc index 6829b4e0..140c47b 100644 --- a/android_webview/browser/aw_proxying_url_loader_factory.cc +++ b/android_webview/browser/aw_proxying_url_loader_factory.cc
@@ -7,6 +7,8 @@ #include <utility> #include "android_webview/browser/aw_contents_client_bridge.h" +#include "android_webview/browser/aw_contents_io_thread_client.h" +#include "android_webview/browser/net_helpers.h" #include "android_webview/browser/renderer_host/auto_login_parser.h" #include "base/strings/stringprintf.h" #include "base/task/post_task.h" @@ -16,6 +18,7 @@ #include "content/public/browser/resource_request_info.h" #include "content/public/browser/web_contents.h" #include "content/public/common/url_utils.h" +#include "net/base/load_flags.h" #include "net/http/http_util.h" namespace android_webview { @@ -68,6 +71,7 @@ void ResumeReadingBodyFromNet() override; private: + std::unique_ptr<AwContentsIoThreadClient> GetIoThreadClient(); void OnRequestError(const network::URLLoaderCompletionStatus& status); // TODO(timvolodine): consider factoring this out of this class. @@ -126,6 +130,8 @@ // TODO(timvolodine): add async check shouldOverrideUrlLoading and // shouldInterceptRequest. + request_.load_flags = GetCacheModeForClient(GetIoThreadClient().get()); + if (!target_loader_ && target_factory_) { network::mojom::URLLoaderClientPtr proxied_client; proxied_client_binding_.Bind(mojo::MakeRequest(&proxied_client)); @@ -315,6 +321,16 @@ target_loader_->ResumeReadingBodyFromNet(); } +std::unique_ptr<AwContentsIoThreadClient> +InterceptedRequest::GetIoThreadClient() { + // |process_id_| == 0 indicates this is a navigation, and so we should use the + // frame_tree_node_id API (with request_.render_frame_id). + return process_id_ + ? AwContentsIoThreadClient::FromID(process_id_, + request_.render_frame_id) + : AwContentsIoThreadClient::FromID(request_.render_frame_id); +} + void InterceptedRequest::OnRequestError( const network::URLLoaderCompletionStatus& status) { target_client_->OnComplete(status);
diff --git a/android_webview/browser/net_helpers.cc b/android_webview/browser/net_helpers.cc new file mode 100644 index 0000000..3ebb56f --- /dev/null +++ b/android_webview/browser/net_helpers.cc
@@ -0,0 +1,35 @@ +// 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/net_helpers.h" + +#include "android_webview/browser/aw_contents_io_thread_client.h" +#include "base/logging.h" +#include "base/macros.h" +#include "net/base/load_flags.h" + +namespace android_webview { + +int GetCacheModeForClient(AwContentsIoThreadClient* client) { + AwContentsIoThreadClient::CacheMode cache_mode = client->GetCacheMode(); + switch (cache_mode) { + case AwContentsIoThreadClient::LOAD_CACHE_ELSE_NETWORK: + // If the resource is in the cache (even if expired), load from cache. + // Otherwise, fall back to network. + return net::LOAD_SKIP_CACHE_VALIDATION; + case AwContentsIoThreadClient::LOAD_NO_CACHE: + // Always load from the network, don't use the cache. + return net::LOAD_BYPASS_CACHE; + case AwContentsIoThreadClient::LOAD_CACHE_ONLY: + // If the resource is in the cache (even if expired), load from cache. Do + // not fall back to the network. + return net::LOAD_ONLY_FROM_CACHE | net::LOAD_SKIP_CACHE_VALIDATION; + default: + // If the resource is in the cache (and is valid), load from cache. + // Otherwise, fall back to network. This is the usual (default) case. + return 0; + } +} + +} // namespace android_webview
diff --git a/android_webview/browser/net_helpers.h b/android_webview/browser/net_helpers.h new file mode 100644 index 0000000..6a82511 --- /dev/null +++ b/android_webview/browser/net_helpers.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 ANDROID_WEBVIEW_BROWSER_NET_HELPERS_H_ +#define ANDROID_WEBVIEW_BROWSER_NET_HELPERS_H_ + +#include <memory> + +namespace android_webview { + +class AwContentsIoThreadClient; + +// Gets the net-layer load_flags which reflect |client|'s cache mode. +int GetCacheModeForClient(AwContentsIoThreadClient* client); + +} // namespace android_webview + +#endif // ANDROID_WEBVIEW_BROWSER_NET_HELPERS_H_
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc index a35c743..6ad95c7 100644 --- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc +++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
@@ -14,6 +14,7 @@ #include "android_webview/browser/aw_resource_context.h" #include "android_webview/browser/aw_safe_browsing_resource_throttle.h" #include "android_webview/browser/net/aw_web_resource_request.h" +#include "android_webview/browser/net_helpers.h" #include "android_webview/browser/renderer_host/auto_login_parser.h" #include "android_webview/common/url_constants.h" #include "base/task/post_task.h" @@ -249,20 +250,9 @@ SetCacheControlFlag( request_, net::LOAD_ONLY_FROM_CACHE | net::LOAD_SKIP_CACHE_VALIDATION); } else { - AwContentsIoThreadClient::CacheMode cache_mode = io_client->GetCacheMode(); - switch (cache_mode) { - case AwContentsIoThreadClient::LOAD_CACHE_ELSE_NETWORK: - SetCacheControlFlag(request_, net::LOAD_SKIP_CACHE_VALIDATION); - break; - case AwContentsIoThreadClient::LOAD_NO_CACHE: - SetCacheControlFlag(request_, net::LOAD_BYPASS_CACHE); - break; - case AwContentsIoThreadClient::LOAD_CACHE_ONLY: - SetCacheControlFlag(request_, net::LOAD_ONLY_FROM_CACHE | - net::LOAD_SKIP_CACHE_VALIDATION); - break; - default: - break; + int cache_mode = GetCacheModeForClient(io_client.get()); + if (cache_mode) { + SetCacheControlFlag(request_, cache_mode); } } return false;
diff --git a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java index 853423c..0422649f 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java +++ b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
@@ -105,9 +105,10 @@ AwContentsClient client = mAwContentsClient.get(); if (client != null) { - // OnPageStarted is not called for fragment navigations. + // OnPageStarted is not called for in-page navigations, which include fragment + // navigations and navigation from history.push/replaceState. // Error page is handled by AwContentsClientBridge.onReceivedError. - if (!isFragmentNavigation && !isErrorPage + if (!isSameDocument && !isErrorPage && AwFeatureList.pageStartedOnCommitEnabled(isRendererInitiated)) { client.getCallbackHelper().postOnPageStarted(url); }
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index dde21b4d..4189360 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -184,6 +184,8 @@ "assistant/model/assistant_interaction_model_observer.h", "assistant/model/assistant_query.cc", "assistant/model/assistant_query.h", + "assistant/model/assistant_query_history.cc", + "assistant/model/assistant_query_history.h", "assistant/model/assistant_response.cc", "assistant/model/assistant_response.h", "assistant/model/assistant_screen_context_model.cc", @@ -663,7 +665,6 @@ "system/bluetooth/bluetooth_feature_pod_controller.h", "system/bluetooth/bluetooth_notification_controller.cc", "system/bluetooth/bluetooth_notification_controller.h", - "system/bluetooth/bluetooth_observer.h", "system/bluetooth/bluetooth_power_controller.cc", "system/bluetooth/bluetooth_power_controller.h", "system/bluetooth/tray_bluetooth_helper.cc", @@ -1626,6 +1627,7 @@ "ash_service_unittest.cc", "assistant/assistant_controller_unittest.cc", "assistant/assistant_screen_context_controller_unittest.cc", + "assistant/model/assistant_query_history_unittest.cc", "assistant/ui/assistant_container_view_unittest.cc", "assistant/util/deep_link_util_unittest.cc", "autoclick/autoclick_drag_event_rewriter_unittest.cc",
diff --git a/ash/app_launch_unittest.cc b/ash/app_launch_unittest.cc index 138d22e3..da7c53d 100644 --- a/ash/app_launch_unittest.cc +++ b/ash/app_launch_unittest.cc
@@ -7,9 +7,12 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/run_loop.h" -#include "services/service_manager/public/cpp/service_test.h" +#include "base/test/scoped_task_environment.h" +#include "services/service_manager/public/cpp/test/test_service.h" +#include "services/service_manager/public/cpp/test/test_service_manager.h" #include "services/ws/public/mojom/constants.mojom.h" #include "services/ws/public/mojom/window_server_test.mojom.h" +#include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ui_base_features.h" #include "ui/views/layout/layout_provider.h" @@ -20,17 +23,24 @@ std::move(callback).Run(); } -class AppLaunchTest : public service_manager::test::ServiceTest { +class AppLaunchTest : public testing::Test { public: - AppLaunchTest() : ServiceTest("ash_unittests") {} + AppLaunchTest() + : test_service_( + test_service_manager_.RegisterTestInstance("ash_unittests")) {} ~AppLaunchTest() override = default; + protected: + service_manager::Connector* connector() { return test_service_.connector(); } + private: void SetUp() override { base::CommandLine::ForCurrentProcess()->AppendSwitch("use-test-config"); - ServiceTest::SetUp(); } + base::test::ScopedTaskEnvironment task_environment_; + service_manager::TestServiceManager test_service_manager_; + service_manager::TestService test_service_; views::LayoutProvider layout_provider_; DISALLOW_COPY_AND_ASSIGN(AppLaunchTest);
diff --git a/ash/app_list/app_list_presenter_delegate_unittest.cc b/ash/app_list/app_list_presenter_delegate_unittest.cc index 8487488..7f6273a8 100644 --- a/ash/app_list/app_list_presenter_delegate_unittest.cc +++ b/ash/app_list/app_list_presenter_delegate_unittest.cc
@@ -6,11 +6,18 @@ #include <memory> #include "ash/app_list/model/app_list_view_state.h" +#include "ash/app_list/pagination_model.h" #include "ash/app_list/presenter/app_list_presenter_impl.h" #include "ash/app_list/test/app_list_test_helper.h" +#include "ash/app_list/test/app_list_test_model.h" +#include "ash/app_list/test/app_list_test_view_delegate.h" #include "ash/app_list/views/app_list_main_view.h" #include "ash/app_list/views/app_list_view.h" +#include "ash/app_list/views/apps_container_view.h" +#include "ash/app_list/views/apps_grid_view.h" +#include "ash/app_list/views/contents_view.h" #include "ash/app_list/views/search_box_view.h" +#include "ash/app_list/views/test/apps_grid_view_test_api.h" #include "ash/public/cpp/app_list/app_list_config.h" #include "ash/public/cpp/app_list/app_list_features.h" #include "ash/public/cpp/app_list/app_list_switches.h" @@ -134,6 +141,65 @@ DISALLOW_COPY_AND_ASSIGN(AppListPresenterDelegateTest); }; +// Used to test app_list behavior with a populated apps_grid +class PopulatedAppListTest : public AshTestBase, + public testing::WithParamInterface<bool> { + public: + PopulatedAppListTest() = default; + ~PopulatedAppListTest() override = default; + + void SetUp() override { + app_list::AppListView::SetShortAnimationForTesting(true); + base::CommandLine::ForCurrentProcess()->AppendSwitch( + keyboard::switches::kEnableVirtualKeyboard); + AshTestBase::SetUp(); + + // Make the display big enough to hold the app list. + UpdateDisplay("1024x768"); + + app_list_test_delegate_ = + std::make_unique<app_list::test::AppListTestViewDelegate>(); + + app_list_test_model_ = app_list_test_delegate_->GetTestModel(); + } + + void TearDown() override { + AshTestBase::TearDown(); + app_list::AppListView::SetShortAnimationForTesting(false); + } + + protected: + void CreateAndOpenAppList() { + app_list_view_ = new app_list::AppListView(app_list_test_delegate_.get()); + app_list::AppListView::InitParams params; + params.parent = CurrentContext(); + app_list_view_->Initialize(params); + } + + void InitializeAppsGrid() { + if (!app_list_view_) + CreateAndOpenAppList(); + apps_grid_view_ = app_list_view_->app_list_main_view() + ->contents_view() + ->GetAppsContainerView() + ->apps_grid_view(); + apps_grid_test_api_ = + std::make_unique<app_list::test::AppsGridViewTestApi>(apps_grid_view_); + } + gfx::Rect GetItemRectOnCurrentPageAt(int row, int col) const { + DCHECK_GT(app_list_test_model_->top_level_item_list()->item_count(), 0u); + return apps_grid_test_api_->GetItemTileRectOnCurrentPageAt(row, col); + } + + app_list::test::AppListTestModel* app_list_test_model_ = nullptr; + std::unique_ptr<app_list::test::AppsGridViewTestApi> apps_grid_test_api_; + std::unique_ptr<app_list::test::AppListTestViewDelegate> + app_list_test_delegate_; + app_list::AppListView* app_list_view_ = nullptr; // Owned by native widget. + app_list::AppsGridView* apps_grid_view_ = + nullptr; // Owned by |app_list_view_|. +}; + // Instantiate the Boolean which is used to toggle mouse and touch events in // the parameterized tests. INSTANTIATE_TEST_CASE_P(, AppListPresenterDelegateTest, testing::Bool()); @@ -158,6 +224,45 @@ DISALLOW_COPY_AND_ASSIGN(AppListPresenterDelegateNonHomeLauncherTest); }; +TEST_F(PopulatedAppListTest, TappingAppsGridClosesVirtualKeyboard) { + InitializeAppsGrid(); + app_list_test_model_->PopulateApps(2); + gfx::Point between_apps = GetItemRectOnCurrentPageAt(0, 0).right_center(); + gfx::Point empty_space = GetItemRectOnCurrentPageAt(0, 2).CenterPoint(); + + ui::GestureEvent tap_between(between_apps.x(), between_apps.y(), 0, + base::TimeTicks(), + ui::GestureEventDetails(ui::ET_GESTURE_TAP)); + ui::GestureEvent tap_outside(empty_space.x(), empty_space.y(), 0, + base::TimeTicks(), + ui::GestureEventDetails(ui::ET_GESTURE_TAP)); + + // Manually show the virtual keyboard. + auto* const keyboard_controller = keyboard::KeyboardController::Get(); + keyboard_controller->ShowKeyboard(true /* locked */); + ASSERT_TRUE(keyboard::WaitUntilShown()); + + // Touch the apps_grid outside of any apps + apps_grid_view_->OnGestureEvent(&tap_outside); + // Expect that the event is ignored here and allowed to propogate to app_list + EXPECT_FALSE(tap_outside.handled()); + // Hit the app_list with the same event + app_list_view_->OnGestureEvent(&tap_outside); + // Expect that the event is handled and the keyboard is closed. + EXPECT_TRUE(tap_outside.handled()); + EXPECT_FALSE(keyboard_controller->IsKeyboardVisible()); + + // Reshow the VKeyboard + keyboard_controller->ShowKeyboard(true); + ASSERT_TRUE(keyboard::WaitUntilShown()); + + // Touch the apps_grid between two apps + apps_grid_view_->OnGestureEvent(&tap_between); + // Expect the event to be handled in the grid, and the keyboard to be closed. + EXPECT_TRUE(tap_between.handled()); + EXPECT_FALSE(keyboard_controller->IsKeyboardVisible()); +} + // Tests that app list hides when focus moves to a normal window. TEST_F(AppListPresenterDelegateTest, HideOnFocusOut) { GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
diff --git a/ash/app_list/views/app_list_item_view.cc b/ash/app_list/views/app_list_item_view.cc index 26037c9d..e0e44c9 100644 --- a/ash/app_list/views/app_list_item_view.cc +++ b/ash/app_list/views/app_list_item_view.cc
@@ -407,7 +407,12 @@ void AppListItemView::SetItemName(const base::string16& display_name, const base::string16& full_name) { - title_->SetText(display_name); + if (is_folder_ && display_name.empty()) { + title_->SetText(ui::ResourceBundle::GetSharedInstance().GetLocalizedString( + IDS_APP_LIST_FOLDER_NAME_PLACEHOLDER)); + } else { + title_->SetText(display_name); + } tooltip_text_ = display_name == full_name ? base::string16() : full_name;
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 9ca94f4..03ca02f 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -1047,8 +1047,10 @@ if (!contents_view_->app_list_view()->IsHomeLauncherEnabledInTabletMode() && (event->type() == ui::ET_GESTURE_TAP || event->type() == ui::ET_GESTURE_LONG_PRESS)) { - if (EventIsBetweenOccupiedTiles(event)) + if (EventIsBetweenOccupiedTiles(event)) { + contents_view_->app_list_view()->CloseKeyboardIfVisible(); event->SetHandled(); + } return; }
diff --git a/ash/app_list/views/apps_grid_view_unittest.cc b/ash/app_list/views/apps_grid_view_unittest.cc index e76366a..0e7d587 100644 --- a/ash/app_list/views/apps_grid_view_unittest.cc +++ b/ash/app_list/views/apps_grid_view_unittest.cc
@@ -592,6 +592,29 @@ EXPECT_FALSE(apps_container_view->IsInFolderView()); } +TEST_F(AppsGridViewTest, TapsBetweenAppsWontCloseAppList) { + model_->PopulateApps(2); + gfx::Point between_apps = GetItemRectOnCurrentPageAt(0, 0).right_center(); + gfx::Point empty_space = GetItemRectOnCurrentPageAt(0, 2).CenterPoint(); + + ui::GestureEvent tap_between(between_apps.x(), between_apps.y(), 0, + base::TimeTicks(), + ui::GestureEventDetails(ui::ET_GESTURE_TAP)); + ui::GestureEvent tap_outside(empty_space.x(), empty_space.y(), 0, + base::TimeTicks(), + ui::GestureEventDetails(ui::ET_GESTURE_TAP)); + + // Taps between apps should be handled to prevent them from going into + // app_list + apps_grid_view_->OnGestureEvent(&tap_between); + EXPECT_TRUE(tap_between.handled()); + + // Taps outside of occupied tiles should not be handled, that they may close + // the app_list + apps_grid_view_->OnGestureEvent(&tap_outside); + EXPECT_FALSE(tap_outside.handled()); +} + TEST_F(AppsGridViewTest, PageResetAfterOpenFolder) { const size_t kTotalItems = kMaxFolderPages * kMaxFolderItemsPerPage; model_->CreateAndPopulateFolderWithApps(kTotalItems);
diff --git a/ash/ash_service_unittest.cc b/ash/ash_service_unittest.cc index 67e32c48..23a34f3a 100644 --- a/ash/ash_service_unittest.cc +++ b/ash/ash_service_unittest.cc
@@ -12,11 +12,14 @@ #include "base/bind.h" #include "base/macros.h" #include "base/run_loop.h" -#include "services/service_manager/public/cpp/service_test.h" +#include "base/test/scoped_task_environment.h" +#include "services/service_manager/public/cpp/test/test_service.h" +#include "services/service_manager/public/cpp/test/test_service_manager.h" #include "services/ws/public/cpp/property_type_converters.h" #include "services/ws/public/mojom/window_manager.mojom.h" #include "services/ws/public/mojom/window_tree.mojom.h" #include "services/ws/public/mojom/window_tree_constants.mojom.h" +#include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/env.h" #include "ui/aura/mus/property_converter.h" @@ -66,24 +69,32 @@ DISALLOW_COPY_AND_ASSIGN(WindowTreeClientDelegate); }; -class AshServiceTest : public service_manager::test::ServiceTest { +class AshServiceTest : public testing::Test { public: - AshServiceTest() : service_manager::test::ServiceTest("ash_unittests") {} + AshServiceTest() + : test_service_( + test_service_manager_.RegisterTestInstance("ash_unittests")) {} ~AshServiceTest() override = default; // service_manager::test::ServiceTest: void SetUp() override { - service_manager::test::ServiceTest::SetUp(); aura::test::EnvTestHelper().SetMode(aura::Env::Mode::MUS); } + void TearDown() override { // Unset the screen installed by the test. display::Screen::SetScreenInstance(nullptr); - service_manager::test::ServiceTest::TearDown(); aura::test::EnvTestHelper().SetMode(aura::Env::Mode::LOCAL); } + protected: + service_manager::Connector* connector() { return test_service_.connector(); } + private: + base::test::ScopedTaskEnvironment task_environment_; + service_manager::TestServiceManager test_service_manager_; + service_manager::TestService test_service_; + DISALLOW_COPY_AND_ASSIGN(AshServiceTest); };
diff --git a/ash/assistant/assistant_interaction_controller.cc b/ash/assistant/assistant_interaction_controller.cc index bf0ac72..e4009fa 100644 --- a/ash/assistant/assistant_interaction_controller.cc +++ b/ash/assistant/assistant_interaction_controller.cc
@@ -120,7 +120,7 @@ } assistant_controller_->ui_controller()->ShowUi(AssistantSource::kDeepLink); - StartTextInteraction(query.value()); + StartTextInteraction(query.value(), /*allow_tts=*/false); } void AssistantInteractionController::OnUiModeChanged(AssistantUiMode ui_mode) { @@ -203,6 +203,28 @@ StartMetalayerInteraction(/*region=*/rect); } +void AssistantInteractionController::OnCommittedQueryChanged( + const AssistantQuery& assistant_query) { + std::string query; + switch (assistant_query.type()) { + case AssistantQueryType::kText: { + const auto* assistant_text_query = + static_cast<const AssistantTextQuery*>(&assistant_query); + query = assistant_text_query->text(); + break; + } + case AssistantQueryType::kVoice: { + const auto* assistant_voice_query = + static_cast<const AssistantVoiceQuery*>(&assistant_query); + query = assistant_voice_query->high_confidence_speech(); + break; + } + case AssistantQueryType::kNull: + break; + } + model_.query_history().Add(query); +} + void AssistantInteractionController::OnInteractionStateChanged( InteractionState interaction_state) { if (interaction_state != InteractionState::kActive) @@ -369,7 +391,13 @@ } // Otherwise, we will submit a simple text query using the suggestion text. - StartTextInteraction(suggestion->text); + // Note that a text query originating from a suggestion chip will carry + // forward the allowance/forbiddance of TTS from the previous response. This + // is because suggestion chips pressed after a voice query should continue to + // return TTS, as really the text interaction is just a continuation of the + // user's preceding voice interaction. + StartTextInteraction(suggestion->text, /*allow_tts=*/model_.response() && + model_.response()->has_tts()); } void AssistantInteractionController::OnSuggestionsResponse( @@ -497,7 +525,7 @@ void AssistantInteractionController::OnDialogPlateContentsCommitted( const std::string& text) { DCHECK(!text.empty()); - StartTextInteraction(text); + StartTextInteraction(text, /*allow_tts=*/false); } bool AssistantInteractionController::HasUnprocessedPendingResponse() { @@ -581,12 +609,13 @@ } void AssistantInteractionController::StartTextInteraction( - const std::string text) { + const std::string text, + bool allow_tts) { StopActiveInteraction(false); model_.SetPendingQuery(std::make_unique<AssistantTextQuery>(text)); - assistant_->SendTextQuery(text); + assistant_->StartTextInteraction(text, allow_tts); } void AssistantInteractionController::StartVoiceInteraction() {
diff --git a/ash/assistant/assistant_interaction_controller.h b/ash/assistant/assistant_interaction_controller.h index 72e7606..8dd7b9c 100644 --- a/ash/assistant/assistant_interaction_controller.h +++ b/ash/assistant/assistant_interaction_controller.h
@@ -67,6 +67,7 @@ void OnInteractionStateChanged(InteractionState interaction_state) override; void OnInputModalityChanged(InputModality input_modality) override; void OnMicStateChanged(MicState mic_state) override; + void OnCommittedQueryChanged(const AssistantQuery& query) override; void OnResponseChanged( const std::shared_ptr<AssistantResponse>& response) override; @@ -116,7 +117,7 @@ void StartMetalayerInteraction(const gfx::Rect& region); void StartScreenContextInteraction(); - void StartTextInteraction(const std::string text); + void StartTextInteraction(const std::string text, bool allow_tts); void StartVoiceInteraction(); void StopActiveInteraction(bool cancel_conversation);
diff --git a/ash/assistant/model/assistant_interaction_model.h b/ash/assistant/model/assistant_interaction_model.h index 272a139f..8417b15 100644 --- a/ash/assistant/model/assistant_interaction_model.h +++ b/ash/assistant/model/assistant_interaction_model.h
@@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "ash/assistant/model/assistant_query_history.h" #include "base/macros.h" #include "base/observer_list.h" @@ -119,6 +120,12 @@ // Updates the speech level in dB. void SetSpeechLevel(float speech_level_db); + // Returns the reference to query history. + AssistantQueryHistory& query_history() { return query_history_; } + + // Returns the const reference to query history. + const AssistantQueryHistory& query_history() const { return query_history_; } + private: void NotifyInteractionStateChanged(); void NotifyInputModalityChanged(); @@ -134,6 +141,7 @@ InteractionState interaction_state_ = InteractionState::kInactive; InputModality input_modality_ = InputModality::kKeyboard; MicState mic_state_ = MicState::kClosed; + AssistantQueryHistory query_history_; std::unique_ptr<AssistantQuery> committed_query_; std::unique_ptr<AssistantQuery> pending_query_; std::unique_ptr<AssistantResponse> pending_response_;
diff --git a/ash/assistant/model/assistant_query_history.cc b/ash/assistant/model/assistant_query_history.cc new file mode 100644 index 0000000..80f8806 --- /dev/null +++ b/ash/assistant/model/assistant_query_history.cc
@@ -0,0 +1,61 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/assistant/model/assistant_query_history.h" + +namespace ash { + +AssistantQueryHistory::AssistantQueryHistory(int capacity) + : capacity_(capacity) { + queries_.reserve(capacity); +} + +AssistantQueryHistory::~AssistantQueryHistory() = default; + +std::unique_ptr<AssistantQueryHistory::Iterator> +AssistantQueryHistory::GetIterator() const { + return std::make_unique<AssistantQueryHistory::Iterator>(queries_); +} + +void AssistantQueryHistory::Add(const std::string& query) { + if (query.empty()) + return; + + if (static_cast<int>(queries_.size()) == capacity_) + queries_.pop_front(); + queries_.push_back(query); +} + +AssistantQueryHistory::Iterator::Iterator( + const base::circular_deque<std::string>& queries) + : queries_(queries), cur_pos_(queries_.size()) {} + +AssistantQueryHistory::Iterator::~Iterator() = default; + +base::Optional<std::string> AssistantQueryHistory::Iterator::Next() { + // queries_.size() is of type unsigned int and queries_.size() -1 will + // overflow if it is 0. + if (cur_pos_ + 1 >= queries_.size()) { + cur_pos_ = queries_.size(); + return base::nullopt; + } + cur_pos_++; + return base::make_optional<std::string>(queries_[cur_pos_]); +} + +base::Optional<std::string> AssistantQueryHistory::Iterator::Prev() { + if (queries_.size() == 0) + return base::nullopt; + + if (cur_pos_ != 0) + cur_pos_--; + + return base::make_optional<std::string>(queries_[cur_pos_]); +} + +void AssistantQueryHistory::Iterator::ResetToLast() { + cur_pos_ = queries_.size(); +} + +} // namespace ash
diff --git a/ash/assistant/model/assistant_query_history.h b/ash/assistant/model/assistant_query_history.h new file mode 100644 index 0000000..3688211 --- /dev/null +++ b/ash/assistant/model/assistant_query_history.h
@@ -0,0 +1,62 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_ASSISTANT_MODEL_ASSISTANT_QUERY_HISTORY_H_ +#define ASH_ASSISTANT_MODEL_ASSISTANT_QUERY_HISTORY_H_ + +#include <memory> +#include <string> + +#include "base/containers/circular_deque.h" +#include "base/macros.h" +#include "base/optional.h" + +namespace ash { + +// Caches user query history. +class AssistantQueryHistory { + public: + class Iterator { + public: + Iterator(const base::circular_deque<std::string>& queries); + ~Iterator(); + + // Fetches the next query. If current is already the last query, or there is + // no query in history, returns nullopt. + base::Optional<std::string> Next(); + + // Fetches the previous query. If current is already the first query, return + // the first query. If there is no query in history, returns nullopt. + base::Optional<std::string> Prev(); + + // Resets to the last query. It also makes current iterator valid again if + // new queries are added to the underlying AssistantQueryHistory. + void ResetToLast(); + + private: + const base::circular_deque<std::string>& queries_; + size_t cur_pos_; + + DISALLOW_COPY_AND_ASSIGN(Iterator); + }; + + AssistantQueryHistory(int capacity = 100); + ~AssistantQueryHistory(); + + // Gets the iterator of query history. + std::unique_ptr<Iterator> GetIterator() const; + + // Adds a query to history. If it is empty, ignore it. + void Add(const std::string& query); + + private: + const int capacity_; + base::circular_deque<std::string> queries_; + + DISALLOW_COPY_AND_ASSIGN(AssistantQueryHistory); +}; + +} // namespace ash + +#endif // ASH_ASSISTANT_MODEL_ASSISTANT_QUERY_HISTORY_H_
diff --git a/ash/assistant/model/assistant_query_history_unittest.cc b/ash/assistant/model/assistant_query_history_unittest.cc new file mode 100644 index 0000000..1e4ebaac --- /dev/null +++ b/ash/assistant/model/assistant_query_history_unittest.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 "ash/assistant/model/assistant_query_history.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace ash { + +// Assert that iterator Prev() or Next() does not crash on an empty history. +TEST(AssistantQueryHistory, Empty) { + AssistantQueryHistory history(10); + auto it = history.GetIterator(); + EXPECT_EQ(base::nullopt, it->Next()); + EXPECT_EQ(base::nullopt, it->Prev()); + EXPECT_EQ(base::nullopt, it->Next()); + EXPECT_EQ(base::nullopt, it->Next()); + EXPECT_EQ(base::nullopt, it->Next()); + EXPECT_EQ(base::nullopt, it->Prev()); +} + +TEST(AssistantQueryHistory, Full) { + int size = 3; + AssistantQueryHistory history(size); + // Make more queries than history limit. + for (int i = 0; i <= size; i++) + history.Add(std::to_string(i)); + auto it = history.GetIterator(); + // Assert history only contains last 3 queries. + for (int i = size; i > 0; i--) + EXPECT_EQ(std::to_string(i), it->Prev().value()); + EXPECT_EQ(std::to_string(1), it->Prev().value()); + // Assert that iterate does not pass first query. + EXPECT_EQ(std::to_string(1), it->Prev().value()); + + // Make more queries than history limit again. + for (int i = 0; i <= size; i++) + history.Add(std::to_string(i + 4)); + it->ResetToLast(); + // Assert that history only contains last 3 queries. + for (int i = size; i > 0; i--) + EXPECT_EQ(std::to_string(i + 4), it->Prev()); + EXPECT_EQ(std::to_string(5), it->Prev().value()); + // Assert that iterate does not pass first query. + EXPECT_EQ(std::to_string(5), it->Prev().value()); +} + +TEST(AssistantQueryHistory, Add) { + AssistantQueryHistory history(10); + auto it = history.GetIterator(); + EXPECT_EQ(base::nullopt, it->Next()); + EXPECT_EQ(base::nullopt, it->Next()); + EXPECT_EQ(base::nullopt, it->Next()); + EXPECT_EQ(base::nullopt, it->Next()); + history.Add("Query01"); + history.Add("Query02"); + it = history.GetIterator(); + EXPECT_EQ(base::nullopt, it->Next()); + EXPECT_EQ("Query02", it->Prev().value()); + EXPECT_EQ("Query01", it->Prev().value()); + EXPECT_EQ("Query01", it->Prev().value()); + EXPECT_EQ("Query02", it->Next().value()); + EXPECT_EQ(base::nullopt, it->Next()); + EXPECT_EQ(base::nullopt, it->Next()); +} + +} // namespace ash
diff --git a/ash/assistant/ui/dialog_plate/dialog_plate.cc b/ash/assistant/ui/dialog_plate/dialog_plate.cc index b009bfd..7fa05ea6 100644 --- a/ash/assistant/ui/dialog_plate/dialog_plate.cc +++ b/ash/assistant/ui/dialog_plate/dialog_plate.cc
@@ -69,7 +69,11 @@ base::Unretained(this)), /*end_animation_callback=*/base::BindRepeating( &DialogPlate::OnAnimationEnded, - base::Unretained(this)))) { + base::Unretained(this)))), + query_history_iterator_(assistant_controller_->interaction_controller() + ->model() + ->query_history() + .GetIterator()) { InitLayout(); // The Assistant controller indirectly owns the view hierarchy to which @@ -109,30 +113,43 @@ bool DialogPlate::HandleKeyEvent(views::Textfield* textfield, const ui::KeyEvent& key_event) { - if (key_event.key_code() != ui::KeyboardCode::VKEY_RETURN) - return false; - if (key_event.type() != ui::EventType::ET_KEY_PRESSED) return false; - // In tablet mode the virtual keyboard should not be sticky, so we hide it - // when committing a query. - if (IsTabletMode()) - textfield_->GetFocusManager()->ClearFocus(); + switch (key_event.key_code()) { + case ui::KeyboardCode::VKEY_RETURN: { + // In tablet mode the virtual keyboard should not be sticky, so we hide it + // when committing a query. + if (IsTabletMode()) + textfield_->GetFocusManager()->ClearFocus(); - const base::StringPiece16& trimmed_text = - base::TrimWhitespace(textfield_->text(), base::TrimPositions::TRIM_ALL); + const base::StringPiece16& trimmed_text = base::TrimWhitespace( + textfield_->text(), base::TrimPositions::TRIM_ALL); - // Only non-empty trimmed text is consider a valid contents commit. Anything - // else will simply result in the DialogPlate being cleared. - if (!trimmed_text.empty()) { - for (DialogPlateObserver& observer : observers_) - observer.OnDialogPlateContentsCommitted(base::UTF16ToUTF8(trimmed_text)); + // Only non-empty trimmed text is consider a valid contents commit. + // Anything else will simply result in the DialogPlate being cleared. + if (!trimmed_text.empty()) { + for (DialogPlateObserver& observer : observers_) + observer.OnDialogPlateContentsCommitted( + base::UTF16ToUTF8(trimmed_text)); + } + + textfield_->SetText(base::string16()); + + return true; + } + case ui::KeyboardCode::VKEY_UP: + case ui::KeyboardCode::VKEY_DOWN: { + DCHECK(query_history_iterator_); + auto opt_query = key_event.key_code() == ui::KeyboardCode::VKEY_UP + ? query_history_iterator_->Prev() + : query_history_iterator_->Next(); + textfield_->SetText(base::UTF8ToUTF16(opt_query.value_or(""))); + return true; + } + default: + return false; } - - textfield_->SetText(base::string16()); - - return true; } void DialogPlate::OnInputModalityChanged(InputModality input_modality) { @@ -219,6 +236,12 @@ } } +void DialogPlate::OnCommittedQueryChanged( + const AssistantQuery& committed_query) { + DCHECK(query_history_iterator_); + query_history_iterator_->ResetToLast(); +} + void DialogPlate::OnUiVisibilityChanged(AssistantVisibility new_visibility, AssistantVisibility old_visibility, AssistantSource source) {
diff --git a/ash/assistant/ui/dialog_plate/dialog_plate.h b/ash/assistant/ui/dialog_plate/dialog_plate.h index 53a0d86..11c9e46 100644 --- a/ash/assistant/ui/dialog_plate/dialog_plate.h +++ b/ash/assistant/ui/dialog_plate/dialog_plate.h
@@ -9,6 +9,7 @@ #include <string> #include "ash/assistant/model/assistant_interaction_model_observer.h" +#include "ash/assistant/model/assistant_query_history.h" #include "ash/assistant/model/assistant_ui_model_observer.h" #include "ash/assistant/ui/dialog_plate/action_view.h" #include "base/macros.h" @@ -87,6 +88,7 @@ // AssistantInteractionModelObserver: void OnInputModalityChanged(InputModality input_modality) override; + void OnCommittedQueryChanged(const AssistantQuery& committed_query) override; // AssistantUiModelObserver: void OnUiVisibilityChanged(AssistantVisibility new_visibility, @@ -120,6 +122,7 @@ views::Textfield* textfield_; // Owned by view hierarchy. std::unique_ptr<ui::CallbackLayerAnimationObserver> animation_observer_; + std::unique_ptr<AssistantQueryHistory::Iterator> query_history_iterator_; base::ObserverList<DialogPlateObserver>::Unchecked observers_;
diff --git a/ash/components/quick_launch/main.cc b/ash/components/quick_launch/main.cc index 4b379b61..83c4d3ef 100644 --- a/ash/components/quick_launch/main.cc +++ b/ash/components/quick_launch/main.cc
@@ -2,14 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/components/quick_launch/quick_launch_application.h" #include "services/service_manager/public/c/main.h" -#include "services/service_manager/public/cpp/service_runner.h" +#include "ash/components/quick_launch/quick_launch_application.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "mojo/public/cpp/system/message_pipe.h" +#include "services/service_manager/public/mojom/service.mojom.h" MojoResult ServiceMain(MojoHandle service_request_handle) { - quick_launch::QuickLaunchApplication* app = - new quick_launch::QuickLaunchApplication; - app->set_running_standalone(true); - service_manager::ServiceRunner runner(app); - return runner.Run(service_request_handle); + base::MessageLoop message_loop; + base::RunLoop run_loop; + quick_launch::QuickLaunchApplication service{ + service_manager::mojom::ServiceRequest(mojo::MakeScopedHandle( + mojo::MessagePipeHandle(service_request_handle)))}; + service.set_running_standalone(true); + service.set_termination_closure(run_loop.QuitClosure()); + run_loop.Run(); + return MOJO_RESULT_OK; }
diff --git a/ash/components/quick_launch/quick_launch_application.cc b/ash/components/quick_launch/quick_launch_application.cc index 166b3ca..97e906a 100644 --- a/ash/components/quick_launch/quick_launch_application.cc +++ b/ash/components/quick_launch/quick_launch_application.cc
@@ -14,11 +14,8 @@ #include "mash/public/mojom/launchable.mojom.h" #include "services/catalog/public/mojom/catalog.mojom.h" #include "services/catalog/public/mojom/constants.mojom.h" -#include "services/service_manager/public/c/main.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/service.h" -#include "services/service_manager/public/cpp/service_context.h" -#include "services/service_manager/public/cpp/service_runner.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" #include "ui/views/background.h" @@ -155,7 +152,9 @@ } // namespace -QuickLaunchApplication::QuickLaunchApplication() = default; +QuickLaunchApplication::QuickLaunchApplication( + service_manager::mojom::ServiceRequest request) + : service_binding_(this, std::move(request)) {} QuickLaunchApplication::~QuickLaunchApplication() { if (window_) @@ -164,21 +163,21 @@ void QuickLaunchApplication::Quit() { window_ = nullptr; - context()->QuitNow(); + Terminate(); } void QuickLaunchApplication::OnStart() { // If AuraInit was unable to initialize there is no longer a peer connection. // The ServiceManager is in the process of shutting down, however we haven't - // been notified yet. Close our ServiceContext and shutdown. + // been notified yet. We just self-terminate in this case. views::AuraInit::InitParams params; - params.connector = context()->connector(); - params.identity = context()->identity(); + params.connector = service_binding_.GetConnector(); + params.identity = service_binding_.identity(); params.register_path_provider = running_standalone_; params.use_accessibility_host = true; aura_init_ = views::AuraInit::Create(params); if (!aura_init_) { - context()->QuitNow(); + Terminate(); return; } @@ -186,10 +185,12 @@ ash::ash_client::Init(); catalog::mojom::CatalogPtr catalog; - context()->connector()->BindInterface(catalog::mojom::kServiceName, &catalog); + service_binding_.GetConnector()->BindInterface(catalog::mojom::kServiceName, + &catalog); window_ = views::Widget::CreateWindowWithContextAndBounds( - new QuickLaunchUI(this, context()->connector(), std::move(catalog)), + new QuickLaunchUI(this, service_binding_.GetConnector(), + std::move(catalog)), nullptr, gfx::Rect(10, 640, 0, 0)); window_->GetNativeWindow()->GetHost()->window()->SetName("QuickLaunch"); window_->Show();
diff --git a/ash/components/quick_launch/quick_launch_application.h b/ash/components/quick_launch/quick_launch_application.h index 1dfb91d..d7a01c8 100644 --- a/ash/components/quick_launch/quick_launch_application.h +++ b/ash/components/quick_launch/quick_launch_application.h
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/cpp/service_binding.h" namespace views { class AuraInit; @@ -20,7 +21,8 @@ class QuickLaunchApplication : public service_manager::Service { public: - QuickLaunchApplication(); + explicit QuickLaunchApplication( + service_manager::mojom::ServiceRequest request); ~QuickLaunchApplication() override; void Quit(); @@ -34,6 +36,8 @@ const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; + service_manager::ServiceBinding service_binding_; + views::Widget* window_ = nullptr; service_manager::BinderRegistry registry_;
diff --git a/ash/public/cpp/ash_features.cc b/ash/public/cpp/ash_features.cc index 7183df4..805ed0c 100644 --- a/ash/public/cpp/ash_features.cc +++ b/ash/public/cpp/ash_features.cc
@@ -46,6 +46,9 @@ const base::Feature kNotificationScrollBar{"NotificationScrollBar", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kPipRoundedCorners{"PipRoundedCorners", + base::FEATURE_ENABLED_BY_DEFAULT}; + const base::Feature kTrilinearFiltering{"TrilinearFiltering", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -90,6 +93,10 @@ return base::FeatureList::IsEnabled(kNotificationScrollBar); } +bool IsPipRoundedCornersEnabled() { + return base::FeatureList::IsEnabled(kPipRoundedCorners); +} + bool IsTrilinearFilteringEnabled() { static bool use_trilinear_filtering = base::FeatureList::IsEnabled(kTrilinearFiltering);
diff --git a/ash/public/cpp/ash_features.h b/ash/public/cpp/ash_features.h index 96b16001..8bbf838 100644 --- a/ash/public/cpp/ash_features.h +++ b/ash/public/cpp/ash_features.h
@@ -63,6 +63,9 @@ // Enables notification scroll bar in UnifiedSystemTray. ASH_PUBLIC_EXPORT extern const base::Feature kNotificationScrollBar; +// Enables rounded corners for the Picture-in-picture window. +ASH_PUBLIC_EXPORT extern const base::Feature kPipRoundedCorners; + // Enables trilinear filtering. ASH_PUBLIC_EXPORT extern const base::Feature kTrilinearFiltering; @@ -91,6 +94,8 @@ ASH_PUBLIC_EXPORT bool IsNotificationScrollBarEnabled(); +ASH_PUBLIC_EXPORT bool IsPipRoundedCornersEnabled(); + ASH_PUBLIC_EXPORT bool IsTrilinearFilteringEnabled(); ASH_PUBLIC_EXPORT bool IsViewsLoginEnabled();
diff --git a/ash/public/interfaces/shell_test_api.mojom b/ash/public/interfaces/shell_test_api.mojom index c4c0b17..bab9b461 100644 --- a/ash/public/interfaces/shell_test_api.mojom +++ b/ash/public/interfaces/shell_test_api.mojom
@@ -16,11 +16,14 @@ // controller. In tablet mode, enables the virtual keyboard. EnableVirtualKeyboard() => (); - // Tells the SplitViewController to snap the given window to the left. - // The client name is used to find the client's WindowTree. - SnapWindowInSplitView(string client_name, uint64 window_id) => (); + // Tells the SplitViewController to snap the given window to the left or + // right. The client name is used to find the client's WindowTree. + SnapWindowInSplitView(string client_name, uint64 window_id, bool left) => (); // Fullscreens the active window, as if the user had pressed the hardware // fullscreen button. ToggleFullscreen() => (); + + // Enters or exits overview mode. + ToggleOverviewMode() => (); };
diff --git a/ash/shelf/shelf.cc b/ash/shelf/shelf.cc index 23910e7..7a28a41 100644 --- a/ash/shelf/shelf.cc +++ b/ash/shelf/shelf.cc
@@ -45,7 +45,7 @@ event, static_cast<aura::Window*>(event->target())); } void OnGestureEvent(ui::GestureEvent* event) override { - shelf_layout_manager_->ProcessGestureEventOnWindow( + shelf_layout_manager_->ProcessGestureEventOfAutoHideShelf( event, static_cast<aura::Window*>(event->target())); } @@ -95,6 +95,10 @@ shelf_widget_.reset(); } +bool Shelf::IsVisible() const { + return shelf_layout_manager_->IsVisible(); +} + aura::Window* Shelf::GetWindow() { return shelf_widget_->GetNativeWindow(); }
diff --git a/ash/shelf/shelf.h b/ash/shelf/shelf.h index 7a21553..0c4c2c2 100644 --- a/ash/shelf/shelf.h +++ b/ash/shelf/shelf.h
@@ -59,6 +59,11 @@ return shelf_layout_manager_; } + // Returns true if the shelf is visible. Shelf can be visible in 1) + // SHELF_VISIBLE or 2) SHELF_AUTO_HIDE but in SHELF_AUTO_HIDE_SHOWN. See + // details in ShelfLayoutManager::IsVisible. + bool IsVisible() const; + ShelfWidget* shelf_widget() { return shelf_widget_.get(); } // Returns the window showing the shelf.
diff --git a/ash/shelf/shelf_button.cc b/ash/shelf/shelf_button.cc index c446ff9..d0951b1d 100644 --- a/ash/shelf/shelf_button.cc +++ b/ash/shelf/shelf_button.cc
@@ -605,16 +605,20 @@ void ShelfButton::OnGestureEvent(ui::GestureEvent* event) { switch (event->type()) { case ui::ET_GESTURE_TAP_DOWN: - AddState(STATE_HOVERED); - drag_timer_.Start( - FROM_HERE, base::TimeDelta::FromMilliseconds(kDragTimeThresholdMs), - base::Bind(&ShelfButton::OnTouchDragTimer, base::Unretained(this))); - ripple_activation_timer_.Start( - FROM_HERE, - base::TimeDelta::FromMilliseconds(kInkDropRippleActivationTimeMs), - base::Bind(&ShelfButton::OnRippleTimer, base::Unretained(this))); - GetInkDrop()->AnimateToState(views::InkDropState::ACTION_PENDING); - event->SetHandled(); + if (shelf_view_->shelf()->IsVisible()) { + AddState(STATE_HOVERED); + drag_timer_.Start( + FROM_HERE, base::TimeDelta::FromMilliseconds(kDragTimeThresholdMs), + base::BindRepeating(&ShelfButton::OnTouchDragTimer, + base::Unretained(this))); + ripple_activation_timer_.Start( + FROM_HERE, + base::TimeDelta::FromMilliseconds(kInkDropRippleActivationTimeMs), + base::BindRepeating(&ShelfButton::OnRippleTimer, + base::Unretained(this))); + GetInkDrop()->AnimateToState(views::InkDropState::ACTION_PENDING); + event->SetHandled(); + } break; case ui::ET_GESTURE_END: drag_timer_.Stop();
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 093bdd7..3050b442 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -349,14 +349,23 @@ } } -void ShelfLayoutManager::ProcessGestureEventOnWindow(ui::GestureEvent* event, - aura::Window* target) { +void ShelfLayoutManager::ProcessGestureEventOfAutoHideShelf( + ui::GestureEvent* event, + aura::Window* target) { + const bool is_shelf_window = IsShelfWindow(target); // Skip event processing if shelf widget is fully visible to let the default // event dispatching do its work. - if (IsVisible() || in_shutdown_) + if (IsVisible() || in_shutdown_) { + // Tap outside of the AUTO_HIDE_SHOWN shelf should hide it. + if (!IsShelfWindow(target) && visibility_state() == SHELF_AUTO_HIDE && + state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN && + event->type() == ui::ET_GESTURE_TAP) { + UpdateAutoHideState(); + } return; + } - if (IsShelfWindow(target)) { + if (is_shelf_window) { ui::GestureEvent event_in_screen(*event); gfx::Point location_in_screen(event->location()); ::wm::ConvertPointToScreen(target, &location_in_screen); @@ -394,13 +403,6 @@ if (gesture_drag_status_ != GESTURE_DRAG_IN_PROGRESS && gesture_drag_status_ != GESTURE_DRAG_APPLIST_IN_PROGRESS) { - if ((shelf_->GetVisibilityState() == SHELF_AUTO_HIDE && - shelf_->GetAutoHideState() == SHELF_AUTO_HIDE_HIDDEN) || - shelf_->GetVisibilityState() == SHELF_HIDDEN) { - // Do not allow children to handle events while the shelf is hidden. - return true; - } - return false; }
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h index 3fdb91c..bd4aae2 100644 --- a/ash/shelf/shelf_layout_manager.h +++ b/ash/shelf/shelf_layout_manager.h
@@ -113,9 +113,10 @@ // Updates the auto-hide state for mouse events. void UpdateAutoHideForMouseEvent(ui::MouseEvent* event, aura::Window* target); - // Process the gesture events on |target|. - void ProcessGestureEventOnWindow(ui::GestureEvent* event, - aura::Window* target); + // Called by AutoHideEventHandler to process the gesture events when shelf is + // auto hide. + void ProcessGestureEventOfAutoHideShelf(ui::GestureEvent* event, + aura::Window* target); ShelfVisibilityState visibility_state() const { return state_.visibility_state;
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc index a961b70..e5713a27 100644 --- a/ash/shelf/shelf_layout_manager_unittest.cc +++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -2547,6 +2547,52 @@ EXPECT_FALSE(gesture_handler->window()); } +// Tests that tap outside of the AUTO_HIDE_SHOWN shelf should hide it. +TEST_F(ShelfLayoutManagerTest, TapOutsideOfAutoHideShownShelf) { + views::Widget* widget = CreateTestWidget(); + Shelf* shelf = GetPrimaryShelf(); + ui::test::EventGenerator* generator = GetEventGenerator(); + + shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); + ShelfLayoutManager* layout_manager = GetShelfLayoutManager(); + layout_manager->LayoutShelf(); + EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState()); + EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState()); + + aura::Window* window = widget->GetNativeWindow(); + gfx::Rect window_bounds = window->GetBoundsInScreen(); + gfx::Rect display_bounds = + display::Screen::GetScreen()->GetPrimaryDisplay().bounds(); + const gfx::Point start(display_bounds.bottom_center()); + const gfx::Point end(start + gfx::Vector2d(0, -80)); + const base::TimeDelta kTimeDelta = base::TimeDelta::FromMilliseconds(100); + const int kNumScrollSteps = 4; + // Swipe up to show the auto-hide shelf. + generator->GestureScrollSequence(start, end, kTimeDelta, kNumScrollSteps); + EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + + // Tap outside the window and AUTO_HIDE_SHOWN shelf should hide the shelf. + gfx::Point tap_location = + window_bounds.bottom_right() + gfx::Vector2d(10, 10); + generator->GestureTapAt(tap_location); + EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState()); + + // Swipe up to show the auto-hide shelf again. + generator->GestureScrollSequence(start, end, kTimeDelta, kNumScrollSteps); + EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + + // Tap inside the AUTO_HIDE_SHOWN shelf should not hide the shelf. + gfx::Rect shelf_bounds = GetShelfWidget()->GetWindowBoundsInScreen(); + tap_location = gfx::Point(shelf_bounds.CenterPoint()); + generator->GestureTapAt(tap_location); + EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + + // Tap inside the window should still hide the shelf. + tap_location = window_bounds.origin() + gfx::Vector2d(10, 10); + generator->GestureTapAt(tap_location); + EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState()); +} + class ShelfLayoutManagerKeyboardTest : public AshTestBase { public: ShelfLayoutManagerKeyboardTest() = default;
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index 79f0af5..4c23fb8e 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc
@@ -2130,8 +2130,12 @@ shelf_menu_model_adapter_.reset(); - // Auto-hide or alignment might have changed, but only for this shelf. - shelf_->UpdateVisibilityState(); + const bool is_in_drag = item && ShelfButtonIsInDrag(item->type, source); + // Update the shelf visibility since auto-hide or alignment might have + // changes, but don't update if shelf item is being dragged. Since shelf + // should be kept as visible during shelf item drag even menu is closed. + if (!is_in_drag) + shelf_->UpdateVisibilityState(); } void ShelfView::OnBoundsAnimatorProgressed(views::BoundsAnimator* animator) {
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc index 2c41ca74..f09a3e51 100644 --- a/ash/shelf/shelf_view_unittest.cc +++ b/ash/shelf/shelf_view_unittest.cc
@@ -2085,6 +2085,64 @@ EXPECT_FALSE(shelf_view_->drag_view()); } +// Tests that shelf items in always shown shelf can be dragged through gesture +// events after context menu is shown. +TEST_F(ShelfViewTest, DragAppAfterContextMenuIsShownInAlwaysShownShelf) { + ASSERT_EQ(SHELF_VISIBLE, GetPrimaryShelf()->GetVisibilityState()); + ui::test::EventGenerator* generator = GetEventGenerator(); + const ShelfID first_app_id = AddAppShortcut(); + const ShelfID second_app_id = AddAppShortcut(); + const int last_index = model_->items().size() - 1; + ASSERT_TRUE(last_index >= 0); + + const gfx::Point start = GetButtonCenter(first_app_id); + // Drag the app long enough to ensure the drag can be triggered. + const gfx::Point end(start.x() + 100, start.y()); + generator->set_current_location(start); + + // Add |STATE_DRAGGING| state to emulate the gesture drag after context menu + // is shown. + GetButtonByID(first_app_id)->AddState(ShelfButton::STATE_DRAGGING); + generator->GestureScrollSequence(start, end, + base::TimeDelta::FromMilliseconds(100), 3); + + // |first_add_id| has been moved to the end of the items in the shelf. + EXPECT_EQ(first_app_id, model_->items()[last_index].id); +} + +// Tests that shelf items in AUTO_HIDE_SHOWN shelf can be dragged through +// gesture events after context menu is shown. +TEST_F(ShelfViewTest, DragAppAfterContextMenuIsShownInAutoHideShelf) { + ui::test::EventGenerator* generator = GetEventGenerator(); + const ShelfID first_app_id = AddAppShortcut(); + const ShelfID second_app_id = AddAppShortcut(); + const int last_index = model_->items().size() - 1; + + Shelf* shelf = GetPrimaryShelf(); + std::unique_ptr<views::Widget> widget = CreateTestWidget(); + widget->Show(); + shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); + EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState()); + EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState()); + + shelf->shelf_widget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD); + EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); + + const gfx::Point start = GetButtonCenter(first_app_id); + // Drag the app long enough to ensure the drag can be triggered. + const gfx::Point end = gfx::Point(start.x() + 100, start.y()); + generator->set_current_location(start); + + // Add |STATE_DRAGGING| state to emulate the gesture drag after context menu + // is shown. + GetButtonByID(first_app_id)->AddState(ShelfButton::STATE_DRAGGING); + generator->GestureScrollSequence(start, end, + base::TimeDelta::FromMilliseconds(100), 3); + + // |first_add_id| has been moved to the end of the items in the shelf. + EXPECT_EQ(first_app_id, model_->items()[last_index].id); +} + struct TouchableAppContextMenuTestParams { TouchableAppContextMenuTestParams(bool enable_touchable_app_context_menu, bool context_menu)
diff --git a/ash/shell/content/client/shell_main_delegate.cc b/ash/shell/content/client/shell_main_delegate.cc index 0d4234b..f7f3fda 100644 --- a/ash/shell/content/client/shell_main_delegate.cc +++ b/ash/shell/content/client/shell_main_delegate.cc
@@ -26,9 +26,11 @@ namespace shell { namespace { -std::unique_ptr<service_manager::Service> CreateQuickLaunch() { +std::unique_ptr<service_manager::Service> CreateQuickLaunch( + service_manager::mojom::ServiceRequest request) { logging::SetLogPrefix("quick"); - return std::make_unique<quick_launch::QuickLaunchApplication>(); + return std::make_unique<quick_launch::QuickLaunchApplication>( + std::move(request)); } std::unique_ptr<service_manager::Service> CreateShortcutViewer() { @@ -55,11 +57,6 @@ void RegisterServices(StaticServiceMap* services) override { { service_manager::EmbeddedServiceInfo info; - info.factory = base::BindRepeating(&CreateQuickLaunch); - (*services)[quick_launch::mojom::kServiceName] = info; - } - { - service_manager::EmbeddedServiceInfo info; info.factory = base::BindRepeating(&CreateShortcutViewer); (*services)[shortcut_viewer::mojom::kServiceName] = info; } @@ -75,6 +72,15 @@ } } + std::unique_ptr<service_manager::Service> HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) override { + if (service_name == quick_launch::mojom::kServiceName) + return CreateQuickLaunch(std::move(request)); + + return nullptr; + } + private: DISALLOW_COPY_AND_ASSIGN(ShellContentUtilityClient); };
diff --git a/ash/shell_test_api.cc b/ash/shell_test_api.cc index b23260c..91483180 100644 --- a/ash/shell_test_api.cc +++ b/ash/shell_test_api.cc
@@ -11,6 +11,7 @@ #include "ash/shell.h" #include "ash/system/power/backlights_forced_off_setter.h" #include "ash/system/power/power_button_controller.h" +#include "ash/wm/overview/window_selector_controller.h" #include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/ws/window_service_owner.h" @@ -88,6 +89,7 @@ void ShellTestApi::SnapWindowInSplitView(const std::string& client_name, ws::Id window_id, + bool left, SnapWindowInSplitViewCallback cb) { auto* window_service = shell_->window_service_owner()->window_service(); aura::Window* window = nullptr; @@ -98,8 +100,9 @@ } } DCHECK(window); - shell_->split_view_controller()->SnapWindow(window, - ash::SplitViewController::LEFT); + shell_->split_view_controller()->SnapWindow( + window, + left ? ash::SplitViewController::LEFT : ash::SplitViewController::RIGHT); shell_->split_view_controller()->FlushForTesting(); std::move(cb).Run(); } @@ -109,4 +112,9 @@ std::move(cb).Run(); } +void ShellTestApi::ToggleOverviewMode(ToggleOverviewModeCallback cb) { + shell_->window_selector_controller()->ToggleOverview(); + std::move(cb).Run(); +} + } // namespace ash
diff --git a/ash/shell_test_api.h b/ash/shell_test_api.h index 44a6a879..0b4117c 100644 --- a/ash/shell_test_api.h +++ b/ash/shell_test_api.h
@@ -57,8 +57,10 @@ void EnableVirtualKeyboard(EnableVirtualKeyboardCallback cb) override; void SnapWindowInSplitView(const std::string& client_name, ws::Id window_id, + bool left, SnapWindowInSplitViewCallback cb) override; void ToggleFullscreen(ToggleFullscreenCallback cb) override; + void ToggleOverviewMode(ToggleOverviewModeCallback cb) override; private: Shell* shell_; // not owned
diff --git a/ash/strings/ash_strings_am.xtb b/ash/strings/ash_strings_am.xtb index 051055a..2ac2172 100644 --- a/ash/strings/ash_strings_am.xtb +++ b/ash/strings/ash_strings_am.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">የሙሉ ማያ ገጽ ማጉያ</translation> <translation id="15373452373711364">ትልቅ የመዳፊት ጠቋሚ</translation> <translation id="1550523713251050646">ለተጨማሪ አማራጮች ጠቅ ያድርጉ</translation> -<translation id="1567387640189251553">የእርስዎን የይለፍ ቃል ለመጨረሻ ጊዜ ካስገቡ ወዲህ የተለየ የቁልፍ ሰሌዳ ተገናኝቷል። የእርስዎን የቁልፍ ጭረቶች ለመስረቅ እየሞከረ ሊሆን ይችላል።</translation> <translation id="1570871743947603115">ብሉቱዝን አብራ ወይም አጥፋ። <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">ይህን ተጠቃሚ አስወግድ</translation> <translation id="1621499497873603021">ባትሪ ባዶ እስኪሆን ድረስ የቀረው ጊዜ፣ <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_ar.xtb b/ash/strings/ash_strings_ar.xtb index 14572b7..81a6655 100644 --- a/ash/strings/ash_strings_ar.xtb +++ b/ash/strings/ash_strings_ar.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">مكبّر بملء الشاشة</translation> <translation id="15373452373711364">مؤشر الماوس الكبير</translation> <translation id="1550523713251050646">انقر للحصول على المزيد من الخيارات</translation> -<translation id="1567387640189251553">تم توصيل لوحة مفاتيح مختلفة منذ آخر إدخال لكلمة المرور، وقد يكون ذلك محاولةً لسرقة ضغطات المفاتيح.</translation> <translation id="1570871743947603115">تبديل البلوتوث. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">إزالة هذا المستخدم</translation> <translation id="1621499497873603021">الوقت المتبقي حتى تصبح البطارية فارغة <ph name="TIME_LEFT" /></translation> @@ -79,7 +78,7 @@ <translation id="2220572644011485463">رقم التعريف الشخصي أو كلمة المرور</translation> <translation id="225680501294068881">جارٍ البحث عن أجهزة...</translation> <translation id="2268130516524549846">تم إيقاف البلوتوث</translation> -<translation id="2268813581635650749">خروج الجميع</translation> +<translation id="2268813581635650749">خروج من كل الحسابات</translation> <translation id="2292698582925480719">مقياس العرض</translation> <translation id="2302092602801625023">تتم إدارة هذا الحساب من خلال Family Link</translation> <translation id="2303600792989757991">نظرة عامة لنافذة التبديل</translation>
diff --git a/ash/strings/ash_strings_bg.xtb b/ash/strings/ash_strings_bg.xtb index 17ed640c..f40f6ff 100644 --- a/ash/strings/ash_strings_bg.xtb +++ b/ash/strings/ash_strings_bg.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Лупа за увеличаване на целия екран</translation> <translation id="15373452373711364">Голям курсор на мишката</translation> <translation id="1550523713251050646">Кликнете за още опции</translation> -<translation id="1567387640189251553">Свързана е различна клавиатура, откакто последно въведохте паролата си. Тя може да се опитва да записва кои клавиши натискате.</translation> <translation id="1570871743947603115">Превключване на Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Премахване на този потребител</translation> <translation id="1621499497873603021">Оставащо време до изразходването на батерията: <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_bn.xtb b/ash/strings/ash_strings_bn.xtb index addfd9a..fb2012f9 100644 --- a/ash/strings/ash_strings_bn.xtb +++ b/ash/strings/ash_strings_bn.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">ফুলস্ক্রিন ম্যাগনিফায়ার</translation> <translation id="15373452373711364">বড় মাউস কার্সার</translation> <translation id="1550523713251050646">আরও বিকল্পের জন্য ক্লিক করুন</translation> -<translation id="1567387640189251553">আপনি যখন শেষবার পাসওয়ার্ডটি লিখেছিলেন তার পরে অন্য একটি কীবোর্ডে কানেক্ট করা হয়েছিল। এটি আপনার পাসওয়ার্ড চুরি করার চেষ্টা করতে পারে।</translation> <translation id="1570871743947603115">ব্লুটুথ টগল করুন। <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">এই ব্যবহারকারীকে সরান</translation> <translation id="1621499497873603021">ব্যাটারি শেষ হতে <ph name="TIME_LEFT" /> সময় বাকি আছে</translation>
diff --git a/ash/strings/ash_strings_ca.xtb b/ash/strings/ash_strings_ca.xtb index c159652..b4953590 100644 --- a/ash/strings/ash_strings_ca.xtb +++ b/ash/strings/ash_strings_ca.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Lupa de pantalla completa</translation> <translation id="15373452373711364">Cursor del ratolí gran</translation> <translation id="1550523713251050646">Feu clic per veure més opcions</translation> -<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="1570871743947603115">Activa o desactiva el Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Suprimeix aquest usuari</translation> <translation id="1621499497873603021">Temps que queda fins que no s'esgoti la bateria: <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_cs.xtb b/ash/strings/ash_strings_cs.xtb index a4b344d..d167e28 100644 --- a/ash/strings/ash_strings_cs.xtb +++ b/ash/strings/ash_strings_cs.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Lupa celé obrazovky</translation> <translation id="15373452373711364">Velký kurzor myši</translation> <translation id="1550523713251050646">Kliknutím zobrazíte další možnosti</translation> -<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="1570871743947603115">Přepnout Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Odebrat tohoto uživatele</translation> <translation id="1621499497873603021">Čas zbývající do vybití baterie: <ph name="TIME_LEFT" /></translation> @@ -261,6 +260,7 @@ <translation id="5571066253365925590">Rozhraní Bluetooth aktivováno</translation> <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Hlasovou odezvu vypnete stisknutím kláves Ctrl + Alt + Z.</translation> +<translation id="5626283214046138476">Platnost vašeho dozorovaného uživatelského účtu brzy vyprší.</translation> <translation id="5648021990716966815">Konektor mikrofonu</translation> <translation id="5669267381087807207">Probíhá aktivace</translation> <translation id="5673434351075758678">Po synchronizaci nastavení se oznámení změní z jazyka <ph name="FROM_LOCALE" /> na jazyk <ph name="TO_LOCALE" />.</translation>
diff --git a/ash/strings/ash_strings_da.xtb b/ash/strings/ash_strings_da.xtb index bca7c438..f9efc08 100644 --- a/ash/strings/ash_strings_da.xtb +++ b/ash/strings/ash_strings_da.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Forstørrelse af fuld skærm</translation> <translation id="15373452373711364">Stor musemarkør</translation> <translation id="1550523713251050646">Klik for at se flere muligheder</translation> -<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="1570871743947603115">Slå Bluetooth til eller fra. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Fjern denne bruger</translation> <translation id="1621499497873603021">Tid tilbage, indtil batteriet er tomt, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_de.xtb b/ash/strings/ash_strings_de.xtb index b9efd881..e57cce7 100644 --- a/ash/strings/ash_strings_de.xtb +++ b/ash/strings/ash_strings_de.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Vollbildlupe</translation> <translation id="15373452373711364">Großer Cursor</translation> <translation id="1550523713251050646">Für weitere Optionen klicken</translation> -<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="1570871743947603115">Bluetooth aktivieren/deaktivieren. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Diesen Nutzer entfernen</translation> <translation id="1621499497873603021">Verbleibende Akku-Laufzeit: <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_el.xtb b/ash/strings/ash_strings_el.xtb index 935677f..308f715 100644 --- a/ash/strings/ash_strings_el.xtb +++ b/ash/strings/ash_strings_el.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Μεγεθυντικός φακός πλήρους οθόνης</translation> <translation id="15373452373711364">Μεγάλος δείκτης ποντικιού</translation> <translation id="1550523713251050646">Κάντε κλικ για περισσότερες επιλογές</translation> -<translation id="1567387640189251553">Συνδέθηκε διαφορετικό πληκτρολόγιο από την τελευταία φορά που εισαγάγατε τον κωδικό πρόσβασής σας. Μπορεί να επιχειρεί να υποκλέψει τα πατήματα πλήκτρων σας.</translation> <translation id="1570871743947603115">Εναλλαγή Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Κατάργηση αυτού του χρήστη</translation> <translation id="1621499497873603021">Χρόνος που απομένει μέχρι να αδειάσει η μπαταρία, <ph name="TIME_LEFT" /></translation> @@ -261,6 +260,7 @@ <translation id="5571066253365925590">Το Bluetooth έχει ενεργοποιηθεί</translation> <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Πιέστε Ctrl + Alt + Z, για να απενεργοποιήσετε τα εκφωνημένα σχόλια.</translation> +<translation id="5626283214046138476">Ο λογαριασμός εποπτευόμενου χρήστη σας θα λήξει σύντομα.</translation> <translation id="5648021990716966815">Υποδοχή μικροφώνου</translation> <translation id="5669267381087807207">Ενεργοποίηση</translation> <translation id="5673434351075758678">Από "<ph name="FROM_LOCALE" />" σε "<ph name="TO_LOCALE" />" μετά τον συγχρονισμό των ρυθμίσεων.</translation>
diff --git a/ash/strings/ash_strings_en-GB.xtb b/ash/strings/ash_strings_en-GB.xtb index f36f377..32048fc3 100644 --- a/ash/strings/ash_strings_en-GB.xtb +++ b/ash/strings/ash_strings_en-GB.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Full-screen magnifier</translation> <translation id="15373452373711364">Large mouse cursor</translation> <translation id="1550523713251050646">Click for more options</translation> -<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="1570871743947603115">Toggle Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Remove this user</translation> <translation id="1621499497873603021">Time left until battery is empty, <ph name="TIME_LEFT" /></translation> @@ -261,6 +260,7 @@ <translation id="5571066253365925590">Bluetooth enabled</translation> <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> <translation id="5600837773213129531">Press Ctrl + Alt + Z to disable spoken feedback.</translation> +<translation id="5626283214046138476">Your supervised user account is expiring soon.</translation> <translation id="5648021990716966815">Mic jack</translation> <translation id="5669267381087807207">Activating</translation> <translation id="5673434351075758678">From '<ph name="FROM_LOCALE" />' to '<ph name="TO_LOCALE" />' after syncing your settings.</translation>
diff --git a/ash/strings/ash_strings_es-419.xtb b/ash/strings/ash_strings_es-419.xtb index 76f640d..c379d84 100644 --- a/ash/strings/ash_strings_es-419.xtb +++ b/ash/strings/ash_strings_es-419.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Lupa de pantalla completa</translation> <translation id="15373452373711364">Cursor del mouse grande</translation> <translation id="1550523713251050646">Haz clic para obtener más opciones</translation> -<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="1570871743947603115">Activar o desactivar Bluetooth: <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Eliminar este usuario</translation> <translation id="1621499497873603021">Tiempo restante hasta que se agote la batería: <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_es.xtb b/ash/strings/ash_strings_es.xtb index 804b842..d58aa3d 100644 --- a/ash/strings/ash_strings_es.xtb +++ b/ash/strings/ash_strings_es.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Lupa de pantalla completa</translation> <translation id="15373452373711364">Cursor del ratón grande</translation> <translation id="1550523713251050646">Haz clic aquí para obtener más opciones</translation> -<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="1570871743947603115">Activa o desactiva el Bluetooth. <ph name="STATE_TEXT" />.</translation> <translation id="1608626060424371292">Eliminar este usuario</translation> <translation id="1621499497873603021">Tiempo restante hasta que se agote la batería: <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_et.xtb b/ash/strings/ash_strings_et.xtb index 157b056..ddc148a8 100644 --- a/ash/strings/ash_strings_et.xtb +++ b/ash/strings/ash_strings_et.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Täisekraani luup</translation> <translation id="15373452373711364">Suur hiirekursor</translation> <translation id="1550523713251050646">Klõpsake lisavalikute nägemiseks</translation> -<translation id="1567387640189251553">Pärast parooli viimast sisestamist on ühendatud teine klaviatuur. See võib üritada varastada teie klahvivajutusi.</translation> <translation id="1570871743947603115">Lülitab Bluetoothi sisse või välja. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Eemalda see kasutaja</translation> <translation id="1621499497873603021">Aku tühjenemiseni on aega <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_fa.xtb b/ash/strings/ash_strings_fa.xtb index ea3149a..ea8f69d 100644 --- a/ash/strings/ash_strings_fa.xtb +++ b/ash/strings/ash_strings_fa.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">ذرهبین تمامصفحه</translation> <translation id="15373452373711364">نشانگر موشواره بزرگ</translation> <translation id="1550523713251050646">برای گزینههای بیشتر کلیک کنید</translation> -<translation id="1567387640189251553">بعد از آخرین باری که گذرواژهتان را وارد کردید، صفحهکلید دیگری متصل شده است. ممکن است تلاش کند ضربهکلیدهای شما را به سرقت ببرد.</translation> <translation id="1570871743947603115">روشن/خاموش کردن بلوتوث. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">حذف این کاربر</translation> <translation id="1621499497873603021">زمان باقیمانده تا خالیشدن شارژ باتری، <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_fi.xtb b/ash/strings/ash_strings_fi.xtb index 7152630..7af77c4 100644 --- a/ash/strings/ash_strings_fi.xtb +++ b/ash/strings/ash_strings_fi.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Koko näytön suurennus</translation> <translation id="15373452373711364">Suuri hiiren osoitin</translation> <translation id="1550523713251050646">Näet lisävaihtoehtoja klikkaamalla tätä.</translation> -<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="1570871743947603115">Ota Bluetooth käyttöön tai poista se käytöstä. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Poista tämä käyttäjä</translation> <translation id="1621499497873603021">Akku on tyhjä <ph name="TIME_LEFT" /> kuluttua</translation>
diff --git a/ash/strings/ash_strings_fil.xtb b/ash/strings/ash_strings_fil.xtb index e6d263d..d049b42 100644 --- a/ash/strings/ash_strings_fil.xtb +++ b/ash/strings/ash_strings_fil.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Fullscreen magnifier</translation> <translation id="15373452373711364">Malaking mouse cursor</translation> <translation id="1550523713251050646">Mag-click para sa higit pang mga opsyon</translation> -<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="1570871743947603115">I-toggle ang Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Alisin ang user na ito</translation> <translation id="1621499497873603021">Natitirang oras bago maubos ang baterya, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_fr.xtb b/ash/strings/ash_strings_fr.xtb index cc95e86..949e1c4 100644 --- a/ash/strings/ash_strings_fr.xtb +++ b/ash/strings/ash_strings_fr.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Loupe plein écran</translation> <translation id="15373452373711364">Grand curseur</translation> <translation id="1550523713251050646">Cliquez pour obtenir plus d'options.</translation> -<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="1570871743947603115">Activer/Désactiver le Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Supprimer cet utilisateur</translation> <translation id="1621499497873603021">Temps restant avant que la batterie ne soit vide : <ph name="TIME_LEFT" />.</translation>
diff --git a/ash/strings/ash_strings_gu.xtb b/ash/strings/ash_strings_gu.xtb index e4ebed5c..141f2c33 100644 --- a/ash/strings/ash_strings_gu.xtb +++ b/ash/strings/ash_strings_gu.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">પૂર્ણસ્ક્રીન મૅગ્નિફાયર</translation> <translation id="15373452373711364">મોટું માઉસ કર્સર</translation> <translation id="1550523713251050646">વધુ વિકલ્પો માટે ક્લિક કરો</translation> -<translation id="1567387640189251553">તમે છેલ્લે પાસવર્ડ દાખલ કર્યો, ત્યાર પછી એક અલગ કીબોર્ડ કનેક્ટ કરવામાં આવ્યું છે. તે તમારા કીસ્ટ્રોકની ચોરી કરવાનો પ્રયાસ કરતું હોઈ શકે છે.</translation> <translation id="1570871743947603115">બ્લૂટૂથ ટૉગલ કરો. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">આ વપરાશકર્તાને દૂર કરો</translation> <translation id="1621499497873603021">બેટરી ખાલી થવામાં બાકી સમય, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_hi.xtb b/ash/strings/ash_strings_hi.xtb index 113694b..29ccadf 100644 --- a/ash/strings/ash_strings_hi.xtb +++ b/ash/strings/ash_strings_hi.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">फ़ुलस्क्रीन पर सामग्री को बड़ा दिखाने की सुविधा</translation> <translation id="15373452373711364">बड़ा माउस कर्सर</translation> <translation id="1550523713251050646">अधिक विकल्पों के लिए क्लिक करें</translation> -<translation id="1567387640189251553">आपके पिछली बार डाले गए पासवर्ड के बाद से एक अलग कीबोर्ड कनेक्ट किया गया है. यह आपके कीस्ट्रोक चुराने की कोशिश कर सकता है.</translation> <translation id="1570871743947603115">ब्लूटूथ टॉगल करें. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">इस उपयोगकर्ता को हटाएं</translation> <translation id="1621499497873603021">बैटरी के खाली होने में शेष समय, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_hr.xtb b/ash/strings/ash_strings_hr.xtb index 8445216..9631378 100644 --- a/ash/strings/ash_strings_hr.xtb +++ b/ash/strings/ash_strings_hr.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Povećalo za cijeli zaslon</translation> <translation id="15373452373711364">Veliki pokazivač miša</translation> <translation id="1550523713251050646">Kliknite za više opcija</translation> -<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="1570871743947603115">Prebacivanje Bluetootha. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Ukloni tog korisnika</translation> <translation id="1621499497873603021">Baterija će se isprazniti za <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_hu.xtb b/ash/strings/ash_strings_hu.xtb index 3bbc9e1e..823cfbe 100644 --- a/ash/strings/ash_strings_hu.xtb +++ b/ash/strings/ash_strings_hu.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Teljes képernyős nagyító</translation> <translation id="15373452373711364">Nagy egérmutató</translation> <translation id="1550523713251050646">Kattintson további lehetőségekért</translation> -<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="1570871743947603115">Bluetooth ki- és bekapcsolása. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Felhasználó eltávolítása</translation> <translation id="1621499497873603021">Akkumulátor lemerüléséig hátralévő idő: <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_id.xtb b/ash/strings/ash_strings_id.xtb index b61ca10..e46769a 100644 --- a/ash/strings/ash_strings_id.xtb +++ b/ash/strings/ash_strings_id.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Kaca pembesar layar penuh</translation> <translation id="15373452373711364">Kursor mouse besar</translation> <translation id="1550523713251050646">Klik untuk opsi lainnya</translation> -<translation id="1567387640189251553">Keyboard yang berbeda telah terhubung sejak Anda terakhir memasukkan sandi. Keyboard tersebut mungkin mencoba mencuri ketukan tombol Anda.</translation> <translation id="1570871743947603115">Alihkan Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Hapus pengguna ini</translation> <translation id="1621499497873603021">Waktu yang tersisa hingga baterai kosong, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_it.xtb b/ash/strings/ash_strings_it.xtb index 6490cd8..de3212a 100644 --- a/ash/strings/ash_strings_it.xtb +++ b/ash/strings/ash_strings_it.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Lente d'ingrandimento a schermo intero</translation> <translation id="15373452373711364">Puntatore del mouse grande</translation> <translation id="1550523713251050646">Fai clic per visualizzare altre opzioni</translation> -<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="1570871743947603115">Attiva/disattiva Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Rimuovi questo utente</translation> <translation id="1621499497873603021">Tempo rimanente all'esaurimento della batteria: <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_iw.xtb b/ash/strings/ash_strings_iw.xtb index 6c0b985..ea9a1e7 100644 --- a/ash/strings/ash_strings_iw.xtb +++ b/ash/strings/ash_strings_iw.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">מגדיל למסך מלא</translation> <translation id="15373452373711364">סמן עכבר גדול</translation> <translation id="1550523713251050646">לחץ לקבלת אפשרויות נוספות</translation> -<translation id="1567387640189251553">חוברה מקלדת אחרת מאז שהזנת את הסיסמה בפעם האחרונה. ייתכן שהיא מנסה לתעד את ההקשות שלך.</translation> <translation id="1570871743947603115">הפעלה או השבתה של Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">הסר את המשתמש הזה</translation> <translation id="1621499497873603021">הזמן שנותר עד להתרוקנות הסוללה, <ph name="TIME_LEFT" /></translation> @@ -81,7 +80,7 @@ <translation id="2268130516524549846">Bluetooth מושבת</translation> <translation id="2268813581635650749">הוצא את כולם</translation> <translation id="2292698582925480719">קנה המידה של התצוגה</translation> -<translation id="2302092602801625023">החשבון הזה מנוהל על-ידי Family Link</translation> +<translation id="2302092602801625023">החשבון הזה מנוהל באמצעות Family Link</translation> <translation id="2303600792989757991">החלף סקירת חלון</translation> <translation id="2339073806695260576">הקשה על לחצן הסטיילוס במדף מאפשרת לכתוב הערות, לצלם את המסך ולהשתמש בסמן הלייזר או בזכוכית המגדלת.</translation> <translation id="2341729377289034582">נעול במצב אנכי</translation>
diff --git a/ash/strings/ash_strings_ja.xtb b/ash/strings/ash_strings_ja.xtb index 764e2cf0..8b79dcec 100644 --- a/ash/strings/ash_strings_ja.xtb +++ b/ash/strings/ash_strings_ja.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">拡大鏡(全画面)</translation> <translation id="15373452373711364">大きいマウス カーソル</translation> <translation id="1550523713251050646">クリックするとその他のオプションが表示されます</translation> -<translation id="1567387640189251553">前回のパスワード入力時以降に別のキーボードが接続されました。キー入力が読み取られる可能性があります。</translation> <translation id="1570871743947603115">Bluetooth を切り替えます。<ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">このユーザーを削除</translation> <translation id="1621499497873603021">バッテリーが空になるまであと: <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_kn.xtb b/ash/strings/ash_strings_kn.xtb index 9c8fd3e..1b1a10f 100644 --- a/ash/strings/ash_strings_kn.xtb +++ b/ash/strings/ash_strings_kn.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">ಪೂರ್ಣಪರದೆ ವರ್ಧಕ</translation> <translation id="15373452373711364">ದೊಡ್ಡ ಮೌಸ್ ಕರ್ಸರ್</translation> <translation id="1550523713251050646">ಇನ್ನಷ್ಟು ಆಯ್ಕೆಗಳಿಗೆ ಕ್ಲಿಕ್ ಮಾಡಿ</translation> -<translation id="1567387640189251553">ನೀವು ಕೊನೆಯ ಬಾರಿ ಪಾಸ್ವರ್ಡ್ ನಮೂದಿಸುವಾಗ ಇದ್ದ ಕೀಬೋರ್ಡ್ಗಿಂತ ಇದು ಭಿನ್ನವಾಗಿದೆ. ನಿಮ್ಮ ಕೀಸ್ಟ್ರೋಕ್ಗಳನ್ನು ಕಳವು ಮಾಡಲು ಇದು ಪ್ರಯತ್ನಿಸುತ್ತಿರಬಹುದು.</translation> <translation id="1570871743947603115">ಬ್ಲೂಟೂತ್ ಟಾಗಲ್ ಮಾಡಿ. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">ಈ ಬಳಕೆದಾರರನ್ನು ತೆಗೆದುಹಾಕಿ</translation> <translation id="1621499497873603021">ಬ್ಯಾಟರಿ ಖಾಲಿ ಆಗುವವರೆಗೆ ಉಳಿದಿರುವ ಸಮಯ, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_ko.xtb b/ash/strings/ash_strings_ko.xtb index e96b32d..3050aa5 100644 --- a/ash/strings/ash_strings_ko.xtb +++ b/ash/strings/ash_strings_ko.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">전체화면 돋보기</translation> <translation id="15373452373711364">큰 마우스 커서</translation> <translation id="1550523713251050646">더 많은 옵션을 확인하려면 클릭하세요.</translation> -<translation id="1567387640189251553">마지막으로 비밀번호를 입력한 후 다른 키보드가 연결되었습니다. 키 입력 내용을 도용하려는 시도일 수 있습니다.</translation> <translation id="1570871743947603115">블루투스를 전환합니다. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">이 사용자 삭제</translation> <translation id="1621499497873603021">남은 배터리 사용 시간은 <ph name="TIME_LEFT" />입니다.</translation> @@ -90,7 +89,7 @@ <translation id="2359808026110333948">계속</translation> <translation id="2365393535144473978">모바일 데이터를 사용 설정하면 블루투스가 사용 설정됩니다.</translation> <translation id="2391579633712104609">180°</translation> -<translation id="239188844683466770">알림 일시중지 전환</translation> +<translation id="239188844683466770">방해 금지 모드 전환</translation> <translation id="2412593942846481727">업데이트 가능</translation> <translation id="2413728805700750528"><ph name="DISPLAY_NAME" />은(는) <ph name="DOMAIN" />에서 관리하는 관리 세션입니다.</translation> <translation id="2416346634399901812"><ph name="NETWORK_NAME" />에 연결됨</translation> @@ -265,7 +264,7 @@ <translation id="5669267381087807207">활성화 중</translation> <translation id="5673434351075758678">설정 동기화 후 ‘<ph name="FROM_LOCALE" />’에서 ‘<ph name="TO_LOCALE" />’(으)로 변경합니다.</translation> <translation id="5691772641933328258">지문을 인식할 수 없음</translation> -<translation id="5710450975648804523">알림 일시중지 사용 중</translation> +<translation id="5710450975648804523">방해 금지 모드 사용 중</translation> <translation id="574392208103952083">보통</translation> <translation id="5744083938413354016">탭 드래그</translation> <translation id="5750765938512549687">블루투스가 사용 중지됨</translation> @@ -319,7 +318,7 @@ <translation id="6490471652906364588">USB-C 기기(오른쪽 포트)</translation> <translation id="6501401484702599040"><ph name="RECEIVER_NAME" />(으)로 화면 전송 중</translation> <translation id="6521655319214113338">필기 입력</translation> -<translation id="6528179044667508675">알림 일시중지</translation> +<translation id="6528179044667508675">방해 금지 모드</translation> <translation id="6537270692134705506">화면 캡처</translation> <translation id="6542521951477560771"><ph name="RECEIVER_NAME" />(으)로 전송 중</translation> <translation id="6585808820553845416">세션이 <ph name="SESSION_TIME_REMAINING" /> 후에 종료됩니다.</translation>
diff --git a/ash/strings/ash_strings_lt.xtb b/ash/strings/ash_strings_lt.xtb index 74b5ac76..89508a50 100644 --- a/ash/strings/ash_strings_lt.xtb +++ b/ash/strings/ash_strings_lt.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Viso ekrano didintuvas</translation> <translation id="15373452373711364">Didelis pelės žymeklis</translation> <translation id="1550523713251050646">Spustelėkite, jei reikia daugiau parinkčių</translation> -<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="1570871743947603115">Perjungti „Bluetooth“. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Pašalinti šį naudotoją</translation> <translation id="1621499497873603021">Laikas, likęs iki akumuliatoriaus išsikrovimo: <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_lv.xtb b/ash/strings/ash_strings_lv.xtb index 05a6c7c8..4ad0c15a 100644 --- a/ash/strings/ash_strings_lv.xtb +++ b/ash/strings/ash_strings_lv.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Pilnekrāna lupa</translation> <translation id="15373452373711364">Liels peles kursors</translation> <translation id="1550523713251050646">Noklikšķiniet, lai skatītu citas iespējas.</translation> -<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="1570871743947603115">Pārslēgt Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Noņemt šo lietotāju</translation> <translation id="1621499497873603021">Atlikušais akumulatora darbības laiks: <ph name="TIME_LEFT" />.</translation>
diff --git a/ash/strings/ash_strings_ml.xtb b/ash/strings/ash_strings_ml.xtb index 1cf0c7e..95e3052 100644 --- a/ash/strings/ash_strings_ml.xtb +++ b/ash/strings/ash_strings_ml.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">പൂർണ്ണസ്ക്രീൻ മാഗ്നിഫയർ</translation> <translation id="15373452373711364">വലിയ മൗസ് കഴ്സർ</translation> <translation id="1550523713251050646">കൂടുതൽ ഓപ്ഷനുകൾക്ക് ക്ലിക്കുചെയ്യുക</translation> -<translation id="1567387640189251553">നിങ്ങൾ അവസാനം പാസ്വേഡ് നൽകിയത് മുതൽ ഒരു വ്യത്യസ്ത കീബോഡ് കണക്റ്റ് ചെയ്തിട്ടുണ്ട്. ഇത് നിങ്ങളുടെ കീസ്ട്രോക്കുകൾ മോഷ്ടിക്കാൻ ശ്രമിച്ചേക്കാം.</translation> <translation id="1570871743947603115">Bluetooth മാറ്റുക. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">ഈ ഉപയോക്താവിനെ നീക്കംചെയ്യുക</translation> <translation id="1621499497873603021">ബാറ്ററി ശൂന്യമാകുന്നതിന് ശേഷിക്കുന്ന സമയം, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_mr.xtb b/ash/strings/ash_strings_mr.xtb index e57923a..7373d42 100644 --- a/ash/strings/ash_strings_mr.xtb +++ b/ash/strings/ash_strings_mr.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">क्षेत्रे भिंग</translation> <translation id="15373452373711364">मोठा माउस कर्सर</translation> <translation id="1550523713251050646">अधिक पर्यायांसाठी क्लिक करा</translation> -<translation id="1567387640189251553">तुम्ही शेवटचा पासवर्ड टाकल्या नंतर वेगळा कीबोर्ड कनेक्ट करण्यात आला आहे. तो कदाचित तुमचे कीस्ट्रोक चोरण्याचा प्रयत्न करत असेल.</translation> <translation id="1570871743947603115">ब्लूटूथ टॉगल करा. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">हा वापरकर्ता काढून टाका</translation> <translation id="1621499497873603021">बॅटरी रिक्त होईपर्यंत शिल्लक वेळ, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_ms.xtb b/ash/strings/ash_strings_ms.xtb index 0c5dd9fb..892ecbb2 100644 --- a/ash/strings/ash_strings_ms.xtb +++ b/ash/strings/ash_strings_ms.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Penggadang skrin penuh</translation> <translation id="15373452373711364">Kursor tetikus besar</translation> <translation id="1550523713251050646">Klik untuk mendapatkan lagi pilihan</translation> -<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="1570871743947603115">Togol Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Alih keluar pengguna ini</translation> <translation id="1621499497873603021">Masa yang tinggal sehingga bateri kosong, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_nl.xtb b/ash/strings/ash_strings_nl.xtb index e3711aae..5c96a30 100644 --- a/ash/strings/ash_strings_nl.xtb +++ b/ash/strings/ash_strings_nl.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Volledig scherm vergroten</translation> <translation id="15373452373711364">Grote muisaanwijzer</translation> <translation id="1550523713251050646">Klik voor meer opties</translation> -<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="1570871743947603115">Bluetooth schakelen. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Deze gebruiker verwijderen</translation> <translation id="1621499497873603021">Resterende tijd totdat de batterij leeg is: <ph name="TIME_LEFT" /></translation> @@ -79,7 +78,7 @@ <translation id="2220572644011485463">Pincode of wachtwoord</translation> <translation id="225680501294068881">Zoeken naar apparaten...</translation> <translation id="2268130516524549846">Bluetooth uitgeschakeld</translation> -<translation id="2268813581635650749">Alle gebruikers uitloggen</translation> +<translation id="2268813581635650749">Uitloggen van alle accounts</translation> <translation id="2292698582925480719">Weergaveschaal</translation> <translation id="2302092602801625023">Dit account wordt beheerd door Family Link</translation> <translation id="2303600792989757991">Overzicht venster in-/uitschakelen</translation> @@ -477,7 +476,7 @@ <translation id="9151726767154816831">Opnieuw opstarten en de functie Powerwash gebruiken om bij te werken</translation> <translation id="9179259655489829027">Met deze functie kun je snel zonder wachtwoord toegang krijgen tot iedere ingelogde gebruiker. Gebruik deze functie alleen met accounts die je vertrouwt.</translation> <translation id="9193626018745640770">Casten naar een onbekende ontvanger</translation> -<translation id="9194617393863864469">Een andere gebruiker inloggen...</translation> +<translation id="9194617393863864469">Als andere gebruiker inloggen...</translation> <translation id="9201131092683066720">De batterij is <ph name="PERCENTAGE" />% vol.</translation> <translation id="9210037371811586452">Samengestelde desktopmodus wordt gesloten</translation> <translation id="9215934040295798075">Achtergrond instellen</translation>
diff --git a/ash/strings/ash_strings_no.xtb b/ash/strings/ash_strings_no.xtb index dda2249..8321a4a7 100644 --- a/ash/strings/ash_strings_no.xtb +++ b/ash/strings/ash_strings_no.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Lupe for hele skjermen</translation> <translation id="15373452373711364">Stor markør</translation> <translation id="1550523713251050646">Klikk for å se flere alternativer</translation> -<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="1570871743947603115">Slå av/på Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Fjern denne brukeren</translation> <translation id="1621499497873603021">Gjenværende tid til batteriet er tomt – <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_pl.xtb b/ash/strings/ash_strings_pl.xtb index e9ab122..2c0399e 100644 --- a/ash/strings/ash_strings_pl.xtb +++ b/ash/strings/ash_strings_pl.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Lupa pełnego ekranu</translation> <translation id="15373452373711364">Duży kursor myszy</translation> <translation id="1550523713251050646">Kliknij, by wyświetlić więcej opcji</translation> -<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="1570871743947603115">Włącz lub wyłącz Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Usuń tego użytkownika</translation> <translation id="1621499497873603021">Czas pozostały do wyczerpania baterii: <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_pt-BR.xtb b/ash/strings/ash_strings_pt-BR.xtb index f8ece33..dd2dbd4 100644 --- a/ash/strings/ash_strings_pt-BR.xtb +++ b/ash/strings/ash_strings_pt-BR.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Lupa de tela cheia</translation> <translation id="15373452373711364">Cursor grande do mouse</translation> <translation id="1550523713251050646">Clique para ver mais opções</translation> -<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="1570871743947603115">Alternar Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Remover este usuário</translation> <translation id="1621499497873603021">O tempo restante até que a bateria se esgote é de <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_pt-PT.xtb b/ash/strings/ash_strings_pt-PT.xtb index 55dc302b..4472491 100644 --- a/ash/strings/ash_strings_pt-PT.xtb +++ b/ash/strings/ash_strings_pt-PT.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Lupa de ecrã inteiro</translation> <translation id="15373452373711364">Cursor do rato grande</translation> <translation id="1550523713251050646">Clicar para obter mais opções</translation> -<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="1570871743947603115">Ativar/desativar Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Remover este utilizador</translation> <translation id="1621499497873603021">Tempo restante até a bateria terminar, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_ro.xtb b/ash/strings/ash_strings_ro.xtb index de11f75..ec9c346 100644 --- a/ash/strings/ash_strings_ro.xtb +++ b/ash/strings/ash_strings_ro.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Lupă de ecran complet</translation> <translation id="15373452373711364">Cursor de mouse mare</translation> <translation id="1550523713251050646">Dă clic pentru mai multe opțiuni</translation> -<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="1570871743947603115">Comută Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Eliminați acest utilizator</translation> <translation id="1621499497873603021">Timp rămas până la descărcarea bateriei: <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_ru.xtb b/ash/strings/ash_strings_ru.xtb index e7a46bf4..b64232a 100644 --- a/ash/strings/ash_strings_ru.xtb +++ b/ash/strings/ash_strings_ru.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Полноэкранная лупа</translation> <translation id="15373452373711364">Большой курсор мыши</translation> <translation id="1550523713251050646">Чтобы изменить источник питания, нажмите здесь.</translation> -<translation id="1567387640189251553">После ввода пароля была подключена другая клавиатура. Это может быть попыткой узнать, какие клавиши вы нажимаете.</translation> <translation id="1570871743947603115">Изменить настройки Bluetooth. <ph name="STATE_TEXT" />.</translation> <translation id="1608626060424371292">Удалить профиль</translation> <translation id="1621499497873603021">Оставшееся время работы от батареи: <ph name="TIME_LEFT" />.</translation>
diff --git a/ash/strings/ash_strings_sk.xtb b/ash/strings/ash_strings_sk.xtb index 0d65af53..ff41bae7 100644 --- a/ash/strings/ash_strings_sk.xtb +++ b/ash/strings/ash_strings_sk.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Lupa celej obrazovky</translation> <translation id="15373452373711364">Veľký kurzor myši</translation> <translation id="1550523713251050646">Kliknutím zobrazíte ďalšie možnosti</translation> -<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="1570871743947603115">Prepnúť Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Odstrániť tohto používateľa</translation> <translation id="1621499497873603021">Čas zostávajúci do vybitia batérie: <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_sl.xtb b/ash/strings/ash_strings_sl.xtb index 89a9c8fe..deb4418 100644 --- a/ash/strings/ash_strings_sl.xtb +++ b/ash/strings/ash_strings_sl.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Celozaslonska lupa</translation> <translation id="15373452373711364">Velik miškin kazalec</translation> <translation id="1550523713251050646">Kliknite za več možnosti</translation> -<translation id="1567387640189251553">Od zadnjega vnosa gesla je bila priklopljena druga tipkovnica, ki morda poskuša beležiti vse, kar natipkate.</translation> <translation id="1570871743947603115">Preklop Bluetootha. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Odstrani tega uporabnika</translation> <translation id="1621499497873603021">Preostali čas do izpraznitve akumulatorja, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_sr.xtb b/ash/strings/ash_strings_sr.xtb index c28b35f..e786ade 100644 --- a/ash/strings/ash_strings_sr.xtb +++ b/ash/strings/ash_strings_sr.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Лупа за цео екран</translation> <translation id="15373452373711364">Велики курсор</translation> <translation id="1550523713251050646">Кликните за више опција</translation> -<translation id="1567387640189251553">Нека друга тастатура је повезана откако сте последњи пут унели лозинку. Можда покушава да украде вашу комбинацију тастера.</translation> <translation id="1570871743947603115">Укључите/искључите Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Уклони овог корисника</translation> <translation id="1621499497873603021">Време које је преостало док се батерија не испразни, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_sv.xtb b/ash/strings/ash_strings_sv.xtb index 0f50fe4..1e8611f 100644 --- a/ash/strings/ash_strings_sv.xtb +++ b/ash/strings/ash_strings_sv.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Helskärmsförstorare</translation> <translation id="15373452373711364">Stor muspekare</translation> <translation id="1550523713251050646">Klicka här för fler alternativ</translation> -<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="1570871743947603115">Aktivera och inaktivera Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Ta bort den här användaren</translation> <translation id="1621499497873603021">Tid som återstår tills batteriet är tomt: <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_sw.xtb b/ash/strings/ash_strings_sw.xtb index c6da85e..27288adb 100644 --- a/ash/strings/ash_strings_sw.xtb +++ b/ash/strings/ash_strings_sw.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Kikuzaji cha skrini nzima</translation> <translation id="15373452373711364">Kishale kikubwa cha kipanya</translation> <translation id="1550523713251050646">Bofya ili upate chaguo zaidi</translation> -<translation id="1567387640189251553">Kibodi tofauti imeunganishwa baada ya tukio lako la hivi karibuni la kuweka nenosiri. Huenda inajaribu kuiba mibofyo yako.</translation> <translation id="1570871743947603115">Washa au uzime Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Ondoa mtumiaji huyu</translation> <translation id="1621499497873603021">Muda unaosalia mpaka betri inapoisha, <ph name="TIME_LEFT" /></translation> @@ -96,7 +95,7 @@ <translation id="2416346634399901812">Umeunganishwa kwenye <ph name="NETWORK_NAME" /></translation> <translation id="2429753432712299108">Kifaa cha Bluetooth cha "<ph name="DEVICE_NAME" />" kinaomba idhini ya kuoanisha. Kabla hujakubali, tafadhali thibitisha kwamba nenosiri hili linaonyeshwa kwenye kifaa hicho: <ph name="PASSKEY" /></translation> <translation id="2482878487686419369">Arifa</translation> -<translation id="2484513351006226581">Gonga <ph name="KEYBOARD_SHORTCUT" /> ili ubadilishe mpangilio wa kibodi.</translation> +<translation id="2484513351006226581">Gusa <ph name="KEYBOARD_SHORTCUT" /> ili ubadilishe mpangilio wa kibodi.</translation> <translation id="2501920221385095727">Vitufe vya kusalia kwa muda</translation> <translation id="2509468283778169019">Caps Lock imewashwa.</translation> <translation id="2532589005999780174">Hali ya juu ya utofautishaji</translation>
diff --git a/ash/strings/ash_strings_ta.xtb b/ash/strings/ash_strings_ta.xtb index 71045154..56260be5 100644 --- a/ash/strings/ash_strings_ta.xtb +++ b/ash/strings/ash_strings_ta.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">முழுத்திரைப் பெரிதாக்கி</translation> <translation id="15373452373711364">பெரிய மவுஸ் இடஞ்சுட்டி</translation> <translation id="1550523713251050646">மேலும் விருப்பங்களுக்குக் கிளிக் செய்யவும்</translation> -<translation id="1567387640189251553">நீங்கள் கடைசியாகக் கடவுச்சொல்லை உள்ளிட்ட பிறகு வேறொரு விசைப்பலகை இணைக்கப்பட்டுள்ளது. அது உங்கள் விசை அழுத்தங்களைத் திருட முயற்சித்துக் கொண்டிருக்கக்கூடும்.</translation> <translation id="1570871743947603115">புளூடூத்தை நிலைமாற்றும். <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">இவரை அகற்று</translation> <translation id="1621499497873603021">இன்னும் <ph name="TIME_LEFT" /> இல் பேட்டரி காலியாகிவிடும்</translation>
diff --git a/ash/strings/ash_strings_te.xtb b/ash/strings/ash_strings_te.xtb index 7a7740d..61efec1 100644 --- a/ash/strings/ash_strings_te.xtb +++ b/ash/strings/ash_strings_te.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">పూర్తి స్క్రీన్ మాగ్నిఫైయర్</translation> <translation id="15373452373711364">పెద్ద మౌస్ కర్సర్</translation> <translation id="1550523713251050646">మరిన్ని ఎంపికల కోసం క్లిక్ చేయండి</translation> -<translation id="1567387640189251553">మీరు మీ పాస్వర్డ్ని చివరిసారిగా నమోదు చేసిన తర్వాత ఒక విభిన్నమైన కీబోర్డ్ కనెక్ట్ చేయబడింది. మీ కీస్ట్రోక్లను దొంగిలించడం కోసం ఇది ప్రయత్నిస్తుండవచ్చు.</translation> <translation id="1570871743947603115">బ్లూటూత్ను టోగుల్ చేయండి. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">ఈ వినియోగదారుని తీసివేయండి</translation> <translation id="1621499497873603021">బ్యాటరీ ఖాళీ కావడానికి మిగిలి ఉన్న సమయం, <ph name="TIME_LEFT" /></translation> @@ -257,7 +256,7 @@ <translation id="5496819745535887422">మీ నిర్వాహకుడు మీ పరికరాన్ని ఉపసంహరిస్తున్నారు. పరికరం మళ్లీ ప్రారంభించినప్పుడు మొత్తం డేటా తొలగించబడుతుంది.</translation> <translation id="553675580533261935">సెషన్ నుండి నిష్క్రమిస్తోంది</translation> <translation id="5537725057119320332">Cast</translation> -<translation id="5548285847212963613">"<ph name="EXTENSION_NAME" />" పొడిగింపు ఈ నెట్వర్క్కు కనెక్ట్ చేయడంలో సహాయపడగలదు.</translation> +<translation id="5548285847212963613">ఈ నెట్వర్క్కు కనెక్ట్ చేయడంలో ఎక్స్టెన్షన్ "<ph name="EXTENSION_NAME" />" సహాయపడగలదు.</translation> <translation id="554893713779400387">డిక్టేషన్ని టోగుల్ చేయి</translation> <translation id="5571066253365925590">Bluetooth ప్రారంభించబడింది</translation> <translation id="5597451508971090205"><ph name="SHORT_WEEKDAY" />, <ph name="DATE" /></translation> @@ -369,7 +368,7 @@ <translation id="743058460480092004">కెమెరా మరియు మైక్రోఫోన్ ఉపయోగంలో ఉన్నాయి.</translation> <translation id="7497767806359279797">భాషను మరియు కీబోర్డ్ను ఎంచుకోండి</translation> <translation id="7510334386202674593">Ctrl+Shift+L</translation> -<translation id="7526573455193969409">నెట్వర్క్ పర్యవేక్షించబడవచ్చు</translation> +<translation id="7526573455193969409">నెట్వర్క్పై పర్యవేక్షణ ఉండవచ్చు</translation> <translation id="7536035074519304529">IP చిరునామా: <ph name="ADDRESS" /></translation> <translation id="7548434653388805669">నిద్రపోయే సమయం</translation> <translation id="7561014039265304140"><ph name="DISPLAY_NAME" /> <ph name="SPECIFIED_RESOLUTION" />కి మద్దతివ్వదు. రిజల్యూషన్ <ph name="FALLBACK_RESOLUTION" />కి మార్చబడింది</translation> @@ -406,7 +405,7 @@ <translation id="7982789257301363584">నెట్వర్క్</translation> <translation id="7984197416080286869">చాలా ఎక్కువ వేలిముద్ర ప్రయత్నాలు చేసారు</translation> <translation id="7994370417837006925">బహుళ సైన్-ఇన్</translation> -<translation id="8000066093800657092">ఏ నెట్వర్క్ లేదు</translation> +<translation id="8000066093800657092">నెట్వర్క్ లేదు</translation> <translation id="8029241286966751120">పూర్తి స్క్రీన్ మాగ్నిఫైయర్ ప్రారంభించబడింది. దాన్ని టోగుల్ ఆఫ్ చేయడానికి మళ్లీ Ctrl+Search+Mని నొక్కండి.</translation> <translation id="8030169304546394654">డిస్కనెక్ట్ చెయ్యబడింది</translation> <translation id="8054466585765276473">బ్యాటరీ సమయాన్ని లెక్కిస్తోంది.</translation>
diff --git a/ash/strings/ash_strings_th.xtb b/ash/strings/ash_strings_th.xtb index b774f5c..afee542 100644 --- a/ash/strings/ash_strings_th.xtb +++ b/ash/strings/ash_strings_th.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">แว่นขยายทั้งหน้าจอ</translation> <translation id="15373452373711364">เคอร์เซอร์เมาส์ขนาดใหญ่</translation> <translation id="1550523713251050646">คลิกเพื่อดูตัวเลือกเพิ่มเติม</translation> -<translation id="1567387640189251553">มีการเชื่อมต่อกับแป้นพิมพ์อื่นหลังจากที่คุณป้อนรหัสผ่านครั้งล่าสุด แป้นพิมพ์นี้อาจพยายามขโมยการกดแป้นพิมพ์ของคุณ</translation> <translation id="1570871743947603115">เปิด/ปิดบลูทูธ <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">ลบผู้ใช้รายนี้</translation> <translation id="1621499497873603021">เวลาที่เหลือกว่าแบตเตอรี่จะหมด, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_tr.xtb b/ash/strings/ash_strings_tr.xtb index 5281d68..e24ae6801 100644 --- a/ash/strings/ash_strings_tr.xtb +++ b/ash/strings/ash_strings_tr.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Tam ekran büyüteci</translation> <translation id="15373452373711364">Büyük fare imleci</translation> <translation id="1550523713251050646">Daha fazla seçenek için tıklayın</translation> -<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="1570871743947603115">Bluetooth'u aç/kapat. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Bu kullanıcıyı kaldır</translation> <translation id="1621499497873603021">Pilin boşalması için kalan süre, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_uk.xtb b/ash/strings/ash_strings_uk.xtb index 2fd843f..e8821fd 100644 --- a/ash/strings/ash_strings_uk.xtb +++ b/ash/strings/ash_strings_uk.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Лупа для всього екрана</translation> <translation id="15373452373711364">Великий курсор миші</translation> <translation id="1550523713251050646">Натисніть, щоб побачити більше опцій</translation> -<translation id="1567387640189251553">Після останнього введення пароля було під’єднано іншу клавіатуру. Можливо, це спроба викрасти введені символи.</translation> <translation id="1570871743947603115">Увімкнути/вимкнути Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Вилучити цього користувача</translation> <translation id="1621499497873603021">До розрядження акумулятора залишилося <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_vi.xtb b/ash/strings/ash_strings_vi.xtb index 6d877c8..07328564 100644 --- a/ash/strings/ash_strings_vi.xtb +++ b/ash/strings/ash_strings_vi.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">Phóng to toàn bộ màn hình</translation> <translation id="15373452373711364">Con trỏ chuột lớn</translation> <translation id="1550523713251050646">Nhấp để xem các tùy chọn khác</translation> -<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="1570871743947603115">Bật/tắt Bluetooth. <ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">Xóa người dùng này</translation> <translation id="1621499497873603021">Thời gian còn lại cho đến khi pin hết, <ph name="TIME_LEFT" /></translation>
diff --git a/ash/strings/ash_strings_zh-CN.xtb b/ash/strings/ash_strings_zh-CN.xtb index 778f7c4..08e1c39e 100644 --- a/ash/strings/ash_strings_zh-CN.xtb +++ b/ash/strings/ash_strings_zh-CN.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">全屏放大镜</translation> <translation id="15373452373711364">大号鼠标光标</translation> <translation id="1550523713251050646">点击即可查看更多选项</translation> -<translation id="1567387640189251553">自从您上次输入密码后,所连接的键盘已被更换。当前连接的键盘可能会试图窃取您的击键操作。</translation> <translation id="1570871743947603115">切换蓝牙设置。<ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">移除此用户</translation> <translation id="1621499497873603021">电池电量将在 <ph name="TIME_LEFT" />后耗尽</translation>
diff --git a/ash/strings/ash_strings_zh-TW.xtb b/ash/strings/ash_strings_zh-TW.xtb index 756ac90..64623a7 100644 --- a/ash/strings/ash_strings_zh-TW.xtb +++ b/ash/strings/ash_strings_zh-TW.xtb
@@ -38,7 +38,6 @@ <translation id="1537254971476575106">全螢幕放大鏡</translation> <translation id="15373452373711364">大型滑鼠游標</translation> <translation id="1550523713251050646">按一下即可查看更多選項</translation> -<translation id="1567387640189251553">自你上次輸入密碼後,裝置已連接其他鍵盤。你的按鍵行為可能會遭到側錄。</translation> <translation id="1570871743947603115">切換藍牙設定。<ph name="STATE_TEXT" /></translation> <translation id="1608626060424371292">移除這位使用者</translation> <translation id="1621499497873603021">電池剩餘使用時間:<ph name="TIME_LEFT" /></translation>
diff --git a/ash/system/bluetooth/bluetooth_feature_pod_controller.cc b/ash/system/bluetooth/bluetooth_feature_pod_controller.cc index adbc3ee..9b8a429 100644 --- a/ash/system/bluetooth/bluetooth_feature_pod_controller.cc +++ b/ash/system/bluetooth/bluetooth_feature_pod_controller.cc
@@ -9,7 +9,6 @@ #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/bluetooth/tray_bluetooth_helper.h" -#include "ash/system/tray/system_tray_notifier.h" #include "ash/system/unified/feature_pod_button.h" #include "ash/system/unified/unified_system_tray_controller.h" #include "base/i18n/number_formatting.h" @@ -22,11 +21,13 @@ BluetoothFeaturePodController::BluetoothFeaturePodController( UnifiedSystemTrayController* tray_controller) : tray_controller_(tray_controller) { - Shell::Get()->system_tray_notifier()->AddBluetoothObserver(this); + Shell::Get()->tray_bluetooth_helper()->AddObserver(this); } BluetoothFeaturePodController::~BluetoothFeaturePodController() { - Shell::Get()->system_tray_notifier()->RemoveBluetoothObserver(this); + auto* helper = Shell::Get()->tray_bluetooth_helper(); + if (helper) + helper->RemoveObserver(this); } FeaturePodButton* BluetoothFeaturePodController::CreateButton() {
diff --git a/ash/system/bluetooth/bluetooth_feature_pod_controller.h b/ash/system/bluetooth/bluetooth_feature_pod_controller.h index 7771f33b..69259c80 100644 --- a/ash/system/bluetooth/bluetooth_feature_pod_controller.h +++ b/ash/system/bluetooth/bluetooth_feature_pod_controller.h
@@ -5,7 +5,7 @@ #ifndef ASH_SYSTEM_BLUETOOTH_BLUETOOTH_FEATURE_POD_CONTROLLER_H_ #define ASH_SYSTEM_BLUETOOTH_BLUETOOTH_FEATURE_POD_CONTROLLER_H_ -#include "ash/system/bluetooth/bluetooth_observer.h" +#include "ash/system/bluetooth/tray_bluetooth_helper.h" #include "ash/system/unified/feature_pod_controller_base.h" #include "base/macros.h" #include "base/strings/string16.h" @@ -16,7 +16,7 @@ // Controller of a feature pod button of bluetooth. class BluetoothFeaturePodController : public FeaturePodControllerBase, - public BluetoothObserver { + public TrayBluetoothHelper::Observer { public: BluetoothFeaturePodController(UnifiedSystemTrayController* tray_controller); ~BluetoothFeaturePodController() override;
diff --git a/ash/system/bluetooth/bluetooth_observer.h b/ash/system/bluetooth/bluetooth_observer.h deleted file mode 100644 index 20fba3e..0000000 --- a/ash/system/bluetooth/bluetooth_observer.h +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_SYSTEM_BLUETOOTH_BLUETOOTH_OBSERVER_H_ -#define ASH_SYSTEM_BLUETOOTH_BLUETOOTH_OBSERVER_H_ - -namespace ash { - -class BluetoothObserver { - public: - virtual ~BluetoothObserver() {} - - // Called when the state of Bluetooth in the system changes. - virtual void OnBluetoothSystemStateChanged() {} - - // Called when a Bluetooth scan has started or stopped. - virtual void OnBluetoothScanStateChanged() {} - - // Called when a device was added, removed, or changed. - virtual void OnBluetoothDeviceListChanged() {} -}; - -} // namespace ash - -#endif // ASH_SYSTEM_BLUETOOTH_BLUETOOTH_OBSERVER_H_
diff --git a/ash/system/bluetooth/tray_bluetooth_helper.cc b/ash/system/bluetooth/tray_bluetooth_helper.cc index febcf5ba..87afc34 100644 --- a/ash/system/bluetooth/tray_bluetooth_helper.cc +++ b/ash/system/bluetooth/tray_bluetooth_helper.cc
@@ -19,6 +19,14 @@ TrayBluetoothHelper::~TrayBluetoothHelper() = default; +void TrayBluetoothHelper::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void TrayBluetoothHelper::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + bool TrayBluetoothHelper::IsBluetoothStateAvailable() { switch (GetBluetoothState()) { case BluetoothSystem::State::kUnsupported: @@ -31,4 +39,19 @@ } } +void TrayBluetoothHelper::NotifyBluetoothSystemStateChanged() { + for (auto& observer : observers_) + observer.OnBluetoothSystemStateChanged(); +} + +void TrayBluetoothHelper::NotifyBluetoothScanStateChanged() { + for (auto& observer : observers_) + observer.OnBluetoothScanStateChanged(); +} + +void TrayBluetoothHelper::NotifyBluetoothDeviceListChanged() { + for (auto& observer : observers_) + observer.OnBluetoothDeviceListChanged(); +} + } // namespace ash
diff --git a/ash/system/bluetooth/tray_bluetooth_helper.h b/ash/system/bluetooth/tray_bluetooth_helper.h index aa3ab97..0410f755 100644 --- a/ash/system/bluetooth/tray_bluetooth_helper.h +++ b/ash/system/bluetooth/tray_bluetooth_helper.h
@@ -42,9 +42,24 @@ // de-virtualize this class and remove its legacy implementation. class TrayBluetoothHelper { public: + class Observer : public base::CheckedObserver { + public: + // Called when the state of Bluetooth in the system changes. + virtual void OnBluetoothSystemStateChanged() {} + + // Called when a Bluetooth scan has started or stopped. + virtual void OnBluetoothScanStateChanged() {} + + // Called when a device was added, removed, or changed. + virtual void OnBluetoothDeviceListChanged() {} + }; + TrayBluetoothHelper(); virtual ~TrayBluetoothHelper(); + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + // Initializes and gets the adapter asynchronously. virtual void Initialize() = 0; @@ -75,6 +90,13 @@ // Returns whether the delegate has initiated a bluetooth discovery session. virtual bool HasBluetoothDiscoverySession() = 0; + protected: + void NotifyBluetoothSystemStateChanged(); + void NotifyBluetoothScanStateChanged(); + void NotifyBluetoothDeviceListChanged(); + + base::ObserverList<Observer> observers_; + private: DISALLOW_COPY_AND_ASSIGN(TrayBluetoothHelper); };
diff --git a/ash/system/bluetooth/tray_bluetooth_helper_experimental.cc b/ash/system/bluetooth/tray_bluetooth_helper_experimental.cc index d543dcc70..8f0e318 100644 --- a/ash/system/bluetooth/tray_bluetooth_helper_experimental.cc +++ b/ash/system/bluetooth/tray_bluetooth_helper_experimental.cc
@@ -84,13 +84,13 @@ void TrayBluetoothHelperExperimental::OnStateChanged( device::mojom::BluetoothSystem::State state) { cached_state_ = state; - Shell::Get()->system_tray_notifier()->NotifyBluetoothSystemStateChanged(); + NotifyBluetoothSystemStateChanged(); } void TrayBluetoothHelperExperimental::OnScanStateChanged( device::mojom::BluetoothSystem::ScanState state) { cached_scan_state_ = state; - Shell::Get()->system_tray_notifier()->NotifyBluetoothScanStateChanged(); + NotifyBluetoothScanStateChanged(); } } // namespace ash
diff --git a/ash/system/bluetooth/tray_bluetooth_helper_legacy.cc b/ash/system/bluetooth/tray_bluetooth_helper_legacy.cc index 83d748d7..e59ca35c 100644 --- a/ash/system/bluetooth/tray_bluetooth_helper_legacy.cc +++ b/ash/system/bluetooth/tray_bluetooth_helper_legacy.cc
@@ -10,7 +10,6 @@ #include "ash/shell.h" #include "ash/system/bluetooth/bluetooth_power_controller.h" #include "ash/system/model/system_tray_model.h" -#include "ash/system/tray/system_tray_notifier.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/metrics/user_metrics.h" @@ -35,10 +34,6 @@ void BluetoothDeviceConnectError( device::BluetoothDevice::ConnectErrorCode error_code) {} -ash::SystemTrayNotifier* GetSystemTrayNotifier() { - return Shell::Get()->system_tray_notifier(); -} - BluetoothDeviceInfo GetBluetoothDeviceInfo(device::BluetoothDevice* device) { BluetoothDeviceInfo info; info.address = device->GetAddress(); @@ -165,34 +160,34 @@ void TrayBluetoothHelperLegacy::AdapterPresentChanged( device::BluetoothAdapter* adapter, bool present) { - GetSystemTrayNotifier()->NotifyBluetoothSystemStateChanged(); + NotifyBluetoothSystemStateChanged(); } void TrayBluetoothHelperLegacy::AdapterPoweredChanged( device::BluetoothAdapter* adapter, bool powered) { - GetSystemTrayNotifier()->NotifyBluetoothSystemStateChanged(); + NotifyBluetoothSystemStateChanged(); } void TrayBluetoothHelperLegacy::AdapterDiscoveringChanged( device::BluetoothAdapter* adapter, bool discovering) { - GetSystemTrayNotifier()->NotifyBluetoothScanStateChanged(); + NotifyBluetoothScanStateChanged(); } void TrayBluetoothHelperLegacy::DeviceAdded(device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { - GetSystemTrayNotifier()->NotifyBluetoothDeviceListChanged(); + NotifyBluetoothDeviceListChanged(); } void TrayBluetoothHelperLegacy::DeviceChanged(device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { - GetSystemTrayNotifier()->NotifyBluetoothDeviceListChanged(); + NotifyBluetoothDeviceListChanged(); } void TrayBluetoothHelperLegacy::DeviceRemoved(device::BluetoothAdapter* adapter, device::BluetoothDevice* device) { - GetSystemTrayNotifier()->NotifyBluetoothDeviceListChanged(); + NotifyBluetoothDeviceListChanged(); } void TrayBluetoothHelperLegacy::OnStartDiscoverySession( @@ -204,7 +199,7 @@ return; VLOG(1) << "Claiming new Bluetooth device discovery session."; discovery_session_ = std::move(discovery_session); - GetSystemTrayNotifier()->NotifyBluetoothScanStateChanged(); + NotifyBluetoothScanStateChanged(); } } // namespace ash
diff --git a/ash/system/bluetooth/unified_bluetooth_detailed_view_controller.cc b/ash/system/bluetooth/unified_bluetooth_detailed_view_controller.cc index ac7e2ca..9eaadb25 100644 --- a/ash/system/bluetooth/unified_bluetooth_detailed_view_controller.cc +++ b/ash/system/bluetooth/unified_bluetooth_detailed_view_controller.cc
@@ -56,15 +56,19 @@ UnifiedSystemTrayController* tray_controller) : detailed_view_delegate_( std::make_unique<UnifiedDetailedViewDelegate>(tray_controller)) { - Shell::Get()->system_tray_notifier()->AddBluetoothObserver(this); + Shell::Get()->tray_bluetooth_helper()->AddObserver(this); } UnifiedBluetoothDetailedViewController:: ~UnifiedBluetoothDetailedViewController() { - Shell::Get()->system_tray_notifier()->RemoveBluetoothObserver(this); // Stop discovering bluetooth devices when exiting BT detailed view. TrayBluetoothHelper* helper = Shell::Get()->tray_bluetooth_helper(); - if (helper && helper->HasBluetoothDiscoverySession()) { + if (!helper) + return; + + helper->RemoveObserver(this); + + if (helper->HasBluetoothDiscoverySession()) { helper->StopBluetoothDiscovering(); } }
diff --git a/ash/system/bluetooth/unified_bluetooth_detailed_view_controller.h b/ash/system/bluetooth/unified_bluetooth_detailed_view_controller.h index 7a01d079..fc952b8 100644 --- a/ash/system/bluetooth/unified_bluetooth_detailed_view_controller.h +++ b/ash/system/bluetooth/unified_bluetooth_detailed_view_controller.h
@@ -7,7 +7,6 @@ #include <memory> -#include "ash/system/bluetooth/bluetooth_observer.h" #include "ash/system/bluetooth/tray_bluetooth_helper.h" #include "ash/system/unified/detailed_view_controller.h" #include "base/macros.h" @@ -23,8 +22,9 @@ class UnifiedSystemTrayController; // Controller of Bluetooth detailed view in UnifiedSystemTray. -class UnifiedBluetoothDetailedViewController : public DetailedViewController, - public BluetoothObserver { +class UnifiedBluetoothDetailedViewController + : public DetailedViewController, + public TrayBluetoothHelper::Observer { public: explicit UnifiedBluetoothDetailedViewController( UnifiedSystemTrayController* tray_controller);
diff --git a/ash/system/tray/system_tray_notifier.cc b/ash/system/tray/system_tray_notifier.cc index c0832905..f7b1e68 100644 --- a/ash/system/tray/system_tray_notifier.cc +++ b/ash/system/tray/system_tray_notifier.cc
@@ -4,7 +4,6 @@ #include "ash/system/tray/system_tray_notifier.h" -#include "ash/system/bluetooth/bluetooth_observer.h" #include "ash/system/ime/ime_observer.h" #include "ash/system/network/network_observer.h" #include "ash/system/screen_security/screen_capture_observer.h" @@ -18,29 +17,6 @@ SystemTrayNotifier::~SystemTrayNotifier() = default; -void SystemTrayNotifier::AddBluetoothObserver(BluetoothObserver* observer) { - bluetooth_observers_.AddObserver(observer); -} - -void SystemTrayNotifier::RemoveBluetoothObserver(BluetoothObserver* observer) { - bluetooth_observers_.RemoveObserver(observer); -} - -void SystemTrayNotifier::NotifyBluetoothSystemStateChanged() { - for (auto& observer : bluetooth_observers_) - observer.OnBluetoothSystemStateChanged(); -} - -void SystemTrayNotifier::NotifyBluetoothScanStateChanged() { - for (auto& observer : bluetooth_observers_) - observer.OnBluetoothScanStateChanged(); -} - -void SystemTrayNotifier::NotifyBluetoothDeviceListChanged() { - for (auto& observer : bluetooth_observers_) - observer.OnBluetoothDeviceListChanged(); -} - void SystemTrayNotifier::AddIMEObserver(IMEObserver* observer) { ime_observers_.AddObserver(observer); }
diff --git a/ash/system/tray/system_tray_notifier.h b/ash/system/tray/system_tray_notifier.h index ad67439..2317d66 100644 --- a/ash/system/tray/system_tray_notifier.h +++ b/ash/system/tray/system_tray_notifier.h
@@ -16,7 +16,6 @@ namespace ash { -class BluetoothObserver; class IMEObserver; class NetworkObserver; class ScreenCaptureObserver; @@ -34,13 +33,6 @@ SystemTrayNotifier(); ~SystemTrayNotifier(); - // Bluetooth. - void AddBluetoothObserver(BluetoothObserver* observer); - void RemoveBluetoothObserver(BluetoothObserver* observer); - void NotifyBluetoothSystemStateChanged(); - void NotifyBluetoothScanStateChanged(); - void NotifyBluetoothDeviceListChanged(); - // Input methods. void AddIMEObserver(IMEObserver* observer); void RemoveIMEObserver(IMEObserver* observer); @@ -77,7 +69,6 @@ void NotifyVirtualKeyboardSuppressionChanged(bool suppressed); private: - base::ObserverList<BluetoothObserver>::Unchecked bluetooth_observers_; base::ObserverList<IMEObserver>::Unchecked ime_observers_; base::ObserverList<NetworkObserver>::Unchecked network_observers_; base::ObserverList<ScreenCaptureObserver>::Unchecked
diff --git a/ash/test/ash_test_suite.cc b/ash/test/ash_test_suite.cc index ee7477c..57aa822 100644 --- a/ash/test/ash_test_suite.cc +++ b/ash/test/ash_test_suite.cc
@@ -16,7 +16,6 @@ #include "ui/base/ui_base_paths.h" #include "ui/base/ui_base_switches.h" #include "ui/compositor/test/context_factories_for_test.h" -#include "ui/gfx/gfx_paths.h" #include "ui/gl/gl_switches.h" #include "ui/gl/test/gl_surface_test_support.h" @@ -36,7 +35,6 @@ gl::GLSurfaceTestSupport::InitializeOneOff(); - gfx::RegisterPathProvider(); ui::RegisterPathProvider(); // Force unittests to run using en-US so if we test against string output,
diff --git a/ash/wallpaper/wallpaper_controller.cc b/ash/wallpaper/wallpaper_controller.cc index 01d3423..a659605f 100644 --- a/ash/wallpaper/wallpaper_controller.cc +++ b/ash/wallpaper/wallpaper_controller.cc
@@ -1139,17 +1139,6 @@ const AccountId account_id = current_user_->account_id; const bool is_ephemeral = current_user_->is_ephemeral; - // Guest user or regular user in ephemeral mode. - if ((is_ephemeral && current_user_->has_gaia_account) || - current_user_->type == user_manager::USER_TYPE_GUEST) { - if (!InitializeUserWallpaperInfo(account_id, is_ephemeral)) - return; - SetDefaultWallpaperImpl(account_id, current_user_->type, - /*show_wallpaper=*/true); - VLOG(1) << "User is ephemeral. Fallback to default wallpaper."; - return; - } - WallpaperInfo info; if (!GetUserWallpaperInfo(account_id, &info, is_ephemeral)) { if (!InitializeUserWallpaperInfo(account_id, is_ephemeral)) @@ -1157,14 +1146,20 @@ GetUserWallpaperInfo(account_id, &info, is_ephemeral); } + // For ephemeral users, the cache is the only place to access their wallpaper + // because it is not saved to disk. If the image doesn't exist in cache, it + // means the user's wallpaper type is default (i.e. the user never sets their + // own wallpaper), and it's a bug if it's not. + // + // For regular users, the image will be read from disk if the cache is not + // hit (e.g. when the first time the wallpaper is shown on login screen). gfx::ImageSkia user_wallpaper; if (GetWallpaperFromCache(account_id, &user_wallpaper)) { ShowWallpaperImage(user_wallpaper, info, /*preview_mode=*/false); return; } - if (info.location.empty()) { - // Uses default wallpaper when file is empty. + if (info.type == DEFAULT) { SetDefaultWallpaperImpl(account_id, current_user_->type, /*show_wallpaper=*/true); return;
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc index 9e107647..79c77290 100644 --- a/ash/wallpaper/wallpaper_controller_unittest.cc +++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -2425,6 +2425,50 @@ controller_->RemoveObserver(&observer); } +// Although ephemeral users' custom wallpapers are not saved to disk, they +// should be kept within the user session. Test for https://crbug.com/825237. +TEST_F(WallpaperControllerTest, ShowWallpaperForEphemeralUser) { + auto initialize_ephemeral_user = [&](const AccountId& account_id) { + mojom::WallpaperUserInfoPtr wallpaper_user_info = + InitializeUser(account_id); + wallpaper_user_info->is_ephemeral = true; + return wallpaper_user_info; + }; + + SimulateUserLogin(kUser1); + // The user doesn't have wallpaper cache in the beginning. + gfx::ImageSkia cached_wallpaper; + EXPECT_FALSE( + controller_->GetWallpaperFromCache(account_id_1, &cached_wallpaper)); + base::FilePath path; + EXPECT_FALSE(controller_->GetPathFromCache(account_id_1, &path)); + + controller_->SetCustomWallpaper( + initialize_ephemeral_user(account_id_1), wallpaper_files_id_1, + file_name_1, WALLPAPER_LAYOUT_CENTER, + CreateImage(640, 480, kWallpaperColor), /*preview_mode=*/false); + RunAllTasksUntilIdle(); + EXPECT_EQ(1, GetWallpaperCount()); + EXPECT_EQ(CUSTOMIZED, controller_->GetWallpaperType()); + EXPECT_EQ(kWallpaperColor, GetWallpaperColor()); + + // The custom wallpaper is cached. + EXPECT_TRUE( + controller_->GetWallpaperFromCache(account_id_1, &cached_wallpaper)); + EXPECT_EQ( + kWallpaperColor, + cached_wallpaper.GetRepresentation(1.0f).GetBitmap().getColor(0, 0)); + EXPECT_TRUE(controller_->GetPathFromCache(account_id_1, &path)); + + // Calling |ShowUserWallpaper| will continue showing the custom wallpaper + // instead of reverting to the default. + controller_->ShowUserWallpaper(initialize_ephemeral_user(account_id_1)); + RunAllTasksUntilIdle(); + EXPECT_EQ(0, GetWallpaperCount()); + EXPECT_EQ(CUSTOMIZED, controller_->GetWallpaperType()); + EXPECT_EQ(kWallpaperColor, GetWallpaperColor()); +} + // A test wallpaper controller client class. class TestWallpaperControllerClient : public mojom::WallpaperControllerClient { public:
diff --git a/ash/wm/pip/pip_window_resizer.cc b/ash/wm/pip/pip_window_resizer.cc index 545c8e8..852ffee0 100644 --- a/ash/wm/pip/pip_window_resizer.cc +++ b/ash/wm/pip/pip_window_resizer.cc
@@ -25,13 +25,13 @@ const float kPipDismissFraction = 0.5f; // TODO(edcourtney): Consider varying the animation duration based on how far // the pip window has to move. -const int kPipSnapToEdgeAnimationDurationMs = 50; +const int kPipSnapToEdgeAnimationDurationMs = 150; // Threshold for considering drag-moving a PIP window to fling in the // direction of movement in GestureEvent velocity units. -const int kPipMovementFlingThresholdSquared = 3000 * 3000; +const int kPipMovementFlingThresholdSquared = 1000 * 1000; // Threshold for considering a swipe off the side of the screen a dismissal // even if less than |kPipDismissFraction| of the PIP window is off-screen. -const int kPipSwipeToDismissFlingThresholdSquared = 2000 * 2000; +const int kPipSwipeToDismissFlingThresholdSquared = 800 * 800; bool IsAtTopOrBottomEdge(const gfx::Rect& bounds, const gfx::Rect& area) { return (bounds.y() < area.y() + kPipDismissSlop && bounds.y() >= area.y()) ||
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index cb83d2f..a091f200 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc
@@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/window_animation_types.h" #include "ash/public/cpp/window_properties.h" #include "ash/public/cpp/window_state_type.h" @@ -736,6 +737,9 @@ } void WindowState::UpdatePipRoundedCorners() { + if (!features::IsPipRoundedCornersEnabled()) + return; + auto* layer = window()->layer(); if (!IsPip()) { // Only remove the mask layer if it is from the existing PIP mask.
diff --git a/base/BUILD.gn b/base/BUILD.gn index c8ad4bf1..1d2115cd 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -732,6 +732,8 @@ "task/cancelable_task_tracker.cc", "task/cancelable_task_tracker.h", "task/common/intrusive_heap.h", + "task/common/operations_controller.cc", + "task/common/operations_controller.h", "task/lazy_task_runner.cc", "task/lazy_task_runner.h", "task/post_task.cc", @@ -2458,6 +2460,7 @@ "system/system_monitor_unittest.cc", "task/cancelable_task_tracker_unittest.cc", "task/common/intrusive_heap_unittest.cc", + "task/common/operations_controller_unittest.cc", "task/lazy_task_runner_unittest.cc", "task/post_task_unittest.cc", "task/scoped_set_task_priority_for_current_thread_unittest.cc", @@ -2901,10 +2904,11 @@ ] } - java_library("jni_processor_annotations_java") { + java_library("jni_java") { supports_android = true java_files = [ "android/java/src/org/chromium/base/annotations/JniStaticNatives.java", + "android/java/src/org/chromium/base/JniStaticTestMocker.java", ] } @@ -2946,6 +2950,7 @@ "android/java/src/org/chromium/base/FileUtils.java", "android/java/src/org/chromium/base/ImportantFileWriterAndroid.java", "android/java/src/org/chromium/base/IntStringCallback.java", + "android/java/src/org/chromium/base/JniStaticTestMocker.java", "android/java/src/org/chromium/base/JNIUtils.java", "android/java/src/org/chromium/base/JavaExceptionReporter.java", "android/java/src/org/chromium/base/JavaHandlerThread.java", @@ -2980,6 +2985,7 @@ "android/java/src/org/chromium/base/annotations/JNIAdditionalImport.java", "android/java/src/org/chromium/base/annotations/JNINamespace.java", "android/java/src/org/chromium/base/annotations/JniIgnoreNatives.java", + "android/java/src/org/chromium/base/annotations/JniStaticNatives.java", "android/java/src/org/chromium/base/annotations/MainDex.java", "android/java/src/org/chromium/base/annotations/NativeCall.java", "android/java/src/org/chromium/base/annotations/NativeClassQualifiedName.java",
diff --git a/base/android/java/src/org/chromium/base/JniStaticTestMocker.java b/base/android/java/src/org/chromium/base/JniStaticTestMocker.java new file mode 100644 index 0000000..73722f7 --- /dev/null +++ b/base/android/java/src/org/chromium/base/JniStaticTestMocker.java
@@ -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. + +package org.chromium.base; + +/** + * Implemented by the TEST_HOOKS field in JNI wrapper classes that are generated + * by the JNI annotation processor. Used in tests for setting the mock + * implementation of a @JniStaticNatives interface. + * @param <T> The @JniStaticNatives annotated interface + */ +public interface JniStaticTestMocker<T> { void setInstanceForTesting(T instance); }
diff --git a/base/android/java/src/org/chromium/base/PackageUtils.java b/base/android/java/src/org/chromium/base/PackageUtils.java index ab554cdc..20285ebe 100644 --- a/base/android/java/src/org/chromium/base/PackageUtils.java +++ b/base/android/java/src/org/chromium/base/PackageUtils.java
@@ -31,6 +31,22 @@ return versionCode; } + /** + * Checks if the app has been installed on the system. + * @return true if the PackageManager reports that the app is installed, false otherwise. + * @param context Any context. + * @param packageName Name of the package to check. + */ + public static boolean isPackageInstalled(Context context, String packageName) { + PackageManager pm = context.getPackageManager(); + try { + pm.getPackageInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + return false; + } + return true; + } + private PackageUtils() { // Hide constructor }
diff --git a/base/android/jni_generator/BUILD.gn b/base/android/jni_generator/BUILD.gn index 6d92eed..03967a13 100644 --- a/base/android/jni_generator/BUILD.gn +++ b/base/android/jni_generator/BUILD.gn
@@ -23,7 +23,6 @@ deps = [ "//base:base_java", - "//base:jni_processor_annotations_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] @@ -32,7 +31,7 @@ android_library("jni_annotation_sample_java") { java_files = [ "java/src/org/chromium/example/jni_generator/SampleForAnnotationProcessor.java" ] deps = [ - "//base:jni_processor_annotations_java", + "//base:base_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] } @@ -96,7 +95,7 @@ annotation_processor_deps = [ "//third_party/auto:auto_service_processor" ] deps = [ - "//base:jni_processor_annotations_java", + "//base:jni_java", "//third_party/android_deps:com_squareup_javapoet_java", "//third_party/auto:auto_service_java", "//third_party/guava:guava_java",
diff --git a/base/android/jni_generator/java/src/org/chromium/jni_generator/JniProcessor.java b/base/android/jni_generator/java/src/org/chromium/jni_generator/JniProcessor.java index 4956c65..cb1b5dbc 100644 --- a/base/android/jni_generator/java/src/org/chromium/jni_generator/JniProcessor.java +++ b/base/android/jni_generator/java/src/org/chromium/jni_generator/JniProcessor.java
@@ -16,9 +16,11 @@ import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; +import org.chromium.base.JniStaticTestMocker; import org.chromium.base.annotations.JniStaticNatives; import java.security.MessageDigest; @@ -297,6 +299,14 @@ * Creates a class spec for an implementation of an @JNINatives annotated interface that will * wrap calls to the NativesClass which contains the actual native method declarations. * + * This class should contain: + * 1. Wrappers for all GEN_JNI static native methods + * 2. A getter that when testing is disabled, will return the native implementation and + * when testing is enabled, will call the mock of the native implementation. + * 3. A field that holds the testNatives instance for when testing is enabled + * 4. A TEST_HOOKS field that implements an anonymous instance of JniStaticTestMocker + * which will set the testNatives implementation when called in tests + * * @param name name of the wrapper class. * @param isPublic if true, a public modifier will be added to this native wrapper. * @param nativeInterface the @JNINatives annotated type that this native wrapper @@ -305,58 +315,18 @@ * */ TypeSpec createNativeWrapperClassSpec(String name, boolean isPublic, TypeElement nativeInterface, Map<String, MethodSpec> methodMap) { + // The wrapper class builder. TypeName nativeInterfaceType = TypeName.get(nativeInterface.asType()); - TypeSpec.Builder builder = TypeSpec.classBuilder(name) + .addSuperinterface(nativeInterfaceType) .addModifiers(Modifier.FINAL) - .addAnnotation(createGeneratedAnnotation()) - .addSuperinterface(nativeInterfaceType); + .addAnnotation(createGeneratedAnnotation()); + if (isPublic) { builder.addModifiers(Modifier.PUBLIC); } - // Holds the test natives target if it is set. - FieldSpec testTarget = FieldSpec.builder(nativeInterfaceType, "testInst") - .addModifiers(Modifier.STATIC) - .build(); - - ParameterSpec testNativesParam = - ParameterSpec.builder(nativeInterfaceType, "testNatives").build(); - - // Target is a field that holds an instance of some NativeInterface. - // Is initialized with an instance of this class. - FieldSpec target = FieldSpec.builder(nativeInterfaceType, "mNatives") - .addModifiers(Modifier.PRIVATE, Modifier.STATIC) - .addModifiers(Modifier.FINAL) - .initializer("new $N()", name) - .build(); - - builder.addField(target); - builder.addField(testTarget); - - // Getter for target or testing instance if flag in GEN_JNI is set. - MethodSpec instanceGetter = - MethodSpec.methodBuilder("get") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .returns(nativeInterfaceType) - .beginControlFlow("if ($T.$N)", NATIVE_CLASS_NAME, NATIVE_TEST_FIELD_NAME) - .addStatement("return $N", testTarget) - .endControlFlow() - .addStatement("return $N", target) - .build(); - - // Sets testTarget to passed in Natives instance. - MethodSpec setInstanceForTesting = - MethodSpec.methodBuilder("setForTesting") - .returns(TypeName.VOID) - .addParameter(testNativesParam) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) - .addStatement("$N = $N", testTarget, testNativesParam) - .build(); - - builder.addMethod(instanceGetter); - builder.addMethod(setInstanceForTesting); - + // Start by adding all the native method wrappers. for (Element enclosed : nativeInterface.getEnclosedElements()) { if (enclosed.getKind() != ElementKind.METHOD) { printError( @@ -376,6 +346,56 @@ builder.addMethod(createNativeWrapperMethod(interfaceMethod, nativesMethod)); } + // Add the testInstance field. + // Holds the test natives target if it is set. + FieldSpec testTarget = FieldSpec.builder(nativeInterfaceType, "testInstance") + .addModifiers(Modifier.PRIVATE, Modifier.STATIC) + .build(); + builder.addField(testTarget); + + // Getter for target or testing instance if flag in GEN_JNI is set. + MethodSpec instanceGetter = + MethodSpec.methodBuilder("get") + .addModifiers(Modifier.PUBLIC, Modifier.STATIC) + .returns(nativeInterfaceType) + .beginControlFlow("if ($T.$N)", NATIVE_CLASS_NAME, NATIVE_TEST_FIELD_NAME) + .addStatement("return $N", testTarget) + .endControlFlow() + .addStatement("return new $N()", name) + .build(); + + builder.addMethod(instanceGetter); + + // Next add TEST_HOOKS to set testInstance... should look like this: + // JniStaticTestMocker<ClassNameJni> TEST_HOOKS = new JniStaticTestMocker<>() { + // @Override + // public static setInstanceForTesting(ClassNameJni instance) { + // testInstance = instance; + // } + // } + MethodSpec testHookMockerMethod = MethodSpec.methodBuilder("setInstanceForTesting") + .addModifiers(Modifier.PUBLIC) + .addAnnotation(Override.class) + .addParameter(nativeInterfaceType, "instance") + .addStatement("$N = instance", testTarget) + .build(); + + // Make the anonymous TEST_HOOK class. + ParameterizedTypeName genericMockerInterface = ParameterizedTypeName.get( + ClassName.get(JniStaticTestMocker.class), ClassName.get(nativeInterface)); + + TypeSpec testHook = TypeSpec.anonymousClassBuilder("") + .addSuperinterface(genericMockerInterface) + .addMethod(testHookMockerMethod) + .build(); + + FieldSpec testHookSpec = + FieldSpec.builder(genericMockerInterface, "TEST_HOOKS") + .addModifiers(Modifier.STATIC, Modifier.PUBLIC, Modifier.FINAL) + .initializer("$L", testHook.toString()) + .build(); + + builder.addField(testHookSpec); return builder.build(); }
diff --git a/base/memory/singleton.h b/base/memory/singleton.h index 1b601a6..87b57919 100644 --- a/base/memory/singleton.h +++ b/base/memory/singleton.h
@@ -219,12 +219,10 @@ typename DifferentiatingType = Type> class Singleton { private: - // Classes using the Singleton<T> pattern should declare a GetInstance() - // method and call Singleton::get() from within that. - friend Type* Type::GetInstance(); - // Classes may also declare a GetInstanceIfExists() method to invoke - // Singleton::GetIfExists(). - friend Type* Type::GetInstanceIfExists(); + // A class T using the Singleton<T> pattern should declare a GetInstance() + // method and call Singleton::get() from within that. T may also declare a + // GetInstanceIfExists() method to invoke Singleton::GetIfExists(). + friend Type; // This class is safe to be constructed and copy-constructed since it has no // member.
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc index d53d5928a..487471835 100644 --- a/base/message_loop/message_loop.cc +++ b/base/message_loop/message_loop.cc
@@ -228,7 +228,7 @@ static_cast<sequence_manager::internal::SequenceManagerImpl*>( backend_.get()); scoped_refptr<sequence_manager::TaskQueue> default_task_queue = - manager->CreateTaskQueue<sequence_manager::TaskQueue>( + manager->CreateTaskQueueWithType<sequence_manager::TaskQueue>( sequence_manager::TaskQueue::Spec("default_tq")); manager->SetTaskRunner(default_task_queue->task_runner()); return default_task_queue;
diff --git a/base/native_library_win.cc b/base/native_library_win.cc index be1c072..8282efc 100644 --- a/base/native_library_win.cc +++ b/base/native_library_win.cc
@@ -109,13 +109,7 @@ } // If LoadLibraryExW API/flags are unavailable or API call fails, try - // LoadLibraryW API. - // TODO(chengx): Currently, if LoadLibraryExW API call fails, LoadLibraryW is - // still tried. We should strictly prefer the LoadLibraryExW over the - // LoadLibraryW if LoadLibraryW is statistically showing no extra benefits. If - // UMA metric shows that FAIL_AND_FAIL is the primary failure mode and/or - // FAIL_AND_SUCCESS is close to zero, we should remove this fallback. - // (http://crbug.com/701944) + // LoadLibraryW API. From UMA, this fallback is necessary for many users. // Switch the current directory to the library directory as the library // may have dependencies on DLLs in this directory. @@ -128,7 +122,6 @@ restore_directory = true; } } - module = ::LoadLibraryW(library_path.value().c_str()); // GetLastError() needs to be called immediately after LoadLibraryW call.
diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc index 2bf2645a..a686652 100644 --- a/base/profiler/stack_sampling_profiler.cc +++ b/base/profiler/stack_sampling_profiler.cc
@@ -680,7 +680,7 @@ // // The wait time should, at most, be only as long as it takes to collect one // sample (~200us) or none at all if sampling has already completed. - ScopedAllowBaseSyncPrimitives allow_wait; + ThreadRestrictions::ScopedAllowWait allow_wait; profiling_inactive_.Wait(); }
diff --git a/base/task/common/operations_controller.cc b/base/task/common/operations_controller.cc new file mode 100644 index 0000000..44fc8d9 --- /dev/null +++ b/base/task/common/operations_controller.cc
@@ -0,0 +1,108 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/task/common/operations_controller.h" +#include "base/logging.h" + +namespace base { +namespace internal { + +OperationsController::OperationsController() { + DETACH_FROM_SEQUENCE(owning_sequence_checker_); +} + +OperationsController::~OperationsController() { +#if DCHECK_IS_ON() + // An OperationsController may only be deleted when it was either not + // accepting operations or after it was shutdown and there are no in flight + // attempts to perform operations. + auto value = state_and_count_.load(); + DCHECK( + ExtractState(value) == State::kRejectingOperations || + (ExtractState(value) == State::kShuttingDown && ExtractCount(value) == 0)) + << value; +#endif +} + +bool OperationsController::StartAcceptingOperations() { + DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_checker_); + // Release semantics are required to ensure that all memory accesses made on + // this thread happen-before any others done on a thread which is later + // allowed to perform an operation. + auto prev_value = state_and_count_.fetch_or(kAcceptingOperationsBitMask, + std::memory_order_release); + + DCHECK_EQ(ExtractState(prev_value), State::kRejectingOperations); + // The count is the number of rejected operations, unwind them now. + auto num_rejected = ExtractCount(prev_value); + DecrementBy(num_rejected); + return num_rejected != 0; +} + +OperationsController::OperationToken OperationsController::TryBeginOperation() { + // Acquire semantics are required to ensure that a thread which is allowed to + // perform an operation sees all the memory side-effects that happened-before + // StartAcceptingOperations(). They're also required so that no operations on + // this thread (e.g. the operation itself) can be reordered before this one. + auto prev_value = state_and_count_.fetch_add(1, std::memory_order_acquire); + + switch (ExtractState(prev_value)) { + case State::kRejectingOperations: + return OperationToken(nullptr); + case State::kAcceptingOperations: + return OperationToken(this); + case State::kShuttingDown: + DecrementBy(1); + return OperationToken(nullptr); + } +} + +void OperationsController::ShutdownAndWaitForZeroOperations() { + DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_checker_); + // Acquire semantics are required to guarantee that all memory side-effects + // made by other threads that were allowed to perform operations are + // synchronized with this thread before it returns from this method. + auto prev_value = state_and_count_.fetch_or(kShuttingDownBitMask, + std::memory_order_acquire); + + switch (ExtractState(prev_value)) { + case State::kRejectingOperations: + // The count is the number of rejected operations, unwind them now. + DecrementBy(ExtractCount(prev_value)); + break; + case State::kAcceptingOperations: + if (ExtractCount(prev_value) != 0) { + shutdown_complete_.Wait(); + } + break; + case State::kShuttingDown: + DCHECK(false) << "Multiple calls to ShutdownAndWaitForZeroOperations()"; + break; + } +} + +OperationsController::State OperationsController::ExtractState(uint32_t value) { + if (value & kShuttingDownBitMask) { + return State::kShuttingDown; + } else if (value & kAcceptingOperationsBitMask) { + return State::kAcceptingOperations; + } else { + return State::kRejectingOperations; + } +} + +void OperationsController::DecrementBy(uint32_t n) { + // Release semantics are required to ensure that no operation on the current + // thread (e.g. the operation itself) can be reordered after this one. + auto prev_value = state_and_count_.fetch_sub(n, std::memory_order_release); + DCHECK_LE(n, ExtractCount(prev_value)) << "Decrement underflow"; + + if (ExtractState(prev_value) == State::kShuttingDown && + ExtractCount(prev_value) == n) { + shutdown_complete_.Signal(); + } +} + +} // namespace internal +} // namespace base \ No newline at end of file
diff --git a/base/task/common/operations_controller.h b/base/task/common/operations_controller.h new file mode 100644 index 0000000..1a1ad915 --- /dev/null +++ b/base/task/common/operations_controller.h
@@ -0,0 +1,162 @@ +// 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_TASK_COMMON_OPERATIONS_CONTROLLER_H_ +#define BASE_TASK_COMMON_OPERATIONS_CONTROLLER_H_ + +#include <atomic> +#include <cstdint> + +#include "base/sequence_checker.h" +#include "base/synchronization/waitable_event.h" + +namespace base { +namespace internal { + +// A lock-free thread-safe controller to manage critical multi-threaded +// operations without locks. +// +// The controller is used to determine if operations are allowed, and to keep +// track of how many are currently active. Users will call TryBeginOperation() +// before starting such operations. If the call succeeds the user can run the +// operation and the controller will keep track of it until the user signals +// that the operation is completed. No operations are allowed before +// StartAcceptingOperations() is called, or after +// ShutdownAndWaitForZeroOperations() is called. +// +// There is no explicit way of telling the controller when an operation is +// completed, instead for convenience TryBeginOperation() will return a RAII +// like object that will do so on destruction. +// +// For example: +// +// OperationsController controller_; +// +// void SetUp() { +// controller_.StartAcceptingOperations(); +// } +// +// void TearDown() { +// controller_.ShutdownAndWaitForZeroOperations(); +// } +// +// void MaybeRunOperation() { +// auto operation_token = controller_.TryBeginOperation(); +// if (operation_token) { +// Process(); +// } +// } +// +// Attention: StartAcceptingOperations() and ShutdownAndWaitForZeroOperations() +// must be called form the same Sequence. +// +// This class is thread-safe (but see attention note above). +class BASE_EXPORT OperationsController { + public: + // The owner of an OperationToken which evaluates to true can safely perform + // an operation while being certain it happens-after + // StartAcceptingOperations() and happens-before + // ShutdownAndWaitForZeroOperations(). Releasing this OperationToken + // relinquishes this right. + // + // This class is thread-safe + class OperationToken { + public: + ~OperationToken() { + if (outer_) + outer_->DecrementBy(1); + } + OperationToken(const OperationToken&) = delete; + OperationToken(OperationToken&& other) { + this->outer_ = other.outer_; + other.outer_ = nullptr; + } + + operator bool() const { return !!outer_; } + + private: + friend class OperationsController; + explicit OperationToken(OperationsController* outer) : outer_(outer) {} + OperationsController* outer_; + }; + + OperationsController(); + + // Users must call ShutdownAndWaitForZeroOperations() before destroying an + // instance of this class if StartAcceptingOperations() was called. + ~OperationsController(); + + OperationsController(const OperationsController&) = delete; + OperationsController& operator=(const OperationsController&) = delete; + + // Starts to accept operations (before this point TryBeginOperation() returns + // an invalid token). Returns true if an attempt to perform an operation was + // made and denied before StartAcceptingOperations() was called. Can be called + // at most once, never after ShutdownAndWaitForZeroOperations(). + // + // Note that if this returns true, the caller may perform an operation to + // replace the ones denied (safe since ShutdownAndWaitForZeroOperations() has + // to be invoked on the same sequence). + bool StartAcceptingOperations(); + + // Returns a RAII like object that implicitly converts to true if operations + // are allowed i.e. if this call happens-after StartAcceptingOperations() and + // happens-before Shutdown(), otherwise the object will convert to false. On + // successful return, this OperationsController will keep track of the + // operation until the returned object goes out of scope. + OperationToken TryBeginOperation(); + + // Prevents further calls to TryBeginOperation() from succeeding and waits for + // all the ongoing operations to complete. + // + // Attention: Can only be called once. + // Attention: Must be called from the same Sequence as + // StartAcceptingOperations() (if called). + void ShutdownAndWaitForZeroOperations(); + + private: + // Atomic representation of the state of this class. We use the upper 2 bits + // to keep track of flag like values and the remainder bits are used as a + // counter. The 2 flags are used to represent 3 different states: + // + // State | AcceptOperations Bit | ShuttingDown Bit + // -------------------------------------------------------------- + // kRejectingOperations | 0 | 0 + // kAcceptingOperations | 1 | 0 + // kShuttingDown | * | 1 + // + // The counter keeps track of the rejected operations when we are in + // the kRejectingOperations state, the number of inflight operations + // otherwise. If the count reaches zero and we are in the shutting down state + // |shutdown_complete_| will be signaled. + static constexpr uint32_t kShuttingDownBitMask = uint32_t{1} << 31; + static constexpr uint32_t kAcceptingOperationsBitMask = uint32_t{1} << 30; + static constexpr uint32_t kFlagsBitMask = + (kShuttingDownBitMask | kAcceptingOperationsBitMask); + static constexpr uint32_t kCountBitMask = ~kFlagsBitMask; + enum class State { + kRejectingOperations, + kAcceptingOperations, + kShuttingDown, + }; + + // Helper methods for the bit fiddling. Pass a |state_and_count_| value to + // extract state or count out of it. + static uint32_t ExtractCount(uint32_t value) { return value & kCountBitMask; } + static State ExtractState(uint32_t value); + + // Decrements the counter by |n| and signals |shutdown_complete_| if needed. + void DecrementBy(uint32_t n); + + std::atomic<uint32_t> state_and_count_{0}; + WaitableEvent shutdown_complete_; + // Verifies that StartAcceptingOperations() and + // ShutdownAndWaitForZeroOperations() are performed on the same sequence. + SEQUENCE_CHECKER(owning_sequence_checker_); +}; + +} // namespace internal +} // namespace base + +#endif // BASE_TASK_COMMON_OPERATIONS_CONTROLLER_H_
diff --git a/base/task/common/operations_controller_unittest.cc b/base/task/common/operations_controller_unittest.cc new file mode 100644 index 0000000..0e110ed1 --- /dev/null +++ b/base/task/common/operations_controller_unittest.cc
@@ -0,0 +1,177 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/task/common/operations_controller.h" + +#include <atomic> +#include <cstdint> +#include <utility> + +#include "base/threading/platform_thread.h" +#include "base/threading/simple_thread.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { +namespace internal { +namespace { + +class ScopedShutdown { + public: + ScopedShutdown(OperationsController* controller) : controller_(*controller) {} + ~ScopedShutdown() { controller_.ShutdownAndWaitForZeroOperations(); } + + private: + OperationsController& controller_; +}; + +TEST(OperationsControllerTest, CanBeDestroyedWithoutWaiting) { + OperationsController controller; +} + +TEST(OperationsControllerTest, CanShutdownIfNotStarted) { + OperationsController controller; + + controller.ShutdownAndWaitForZeroOperations(); +} + +TEST(OperationsControllerTest, FailsToBeginWhenNotStarted) { + OperationsController controller; + + auto operation_token = controller.TryBeginOperation(); + + EXPECT_FALSE(operation_token); +} + +TEST(OperationsControllerTest, CanShutdownAfterTryCallsIfNotStarted) { + OperationsController controller; + auto operation_token = controller.TryBeginOperation(); + ASSERT_FALSE(operation_token); + + controller.ShutdownAndWaitForZeroOperations(); +} + +TEST(OperationsControllerTest, + StartAcceptingOperationsReturnsFalseIfNoRejectedBeginAttempts) { + OperationsController controller; + ScopedShutdown cleanup(&controller); + + EXPECT_FALSE(controller.StartAcceptingOperations()); +} + +TEST(OperationsControllerTest, + StartAcceptingOperationsReturnsTrueIfFailedBeginAttempts) { + OperationsController controller; + ScopedShutdown cleanup(&controller); + + auto operation_token = controller.TryBeginOperation(); + ASSERT_FALSE(operation_token); + + EXPECT_TRUE(controller.StartAcceptingOperations()); +} + +TEST(OperationsControllerTest, SuccesfulBeginReturnsValidScopedObject) { + OperationsController controller; + ScopedShutdown cleanup(&controller); + controller.StartAcceptingOperations(); + + auto operation_token = controller.TryBeginOperation(); + + EXPECT_TRUE(operation_token); +} + +TEST(OperationsControllerTest, BeginFailsAfterShutdown) { + OperationsController controller; + controller.StartAcceptingOperations(); + + controller.ShutdownAndWaitForZeroOperations(); + auto operation_token = controller.TryBeginOperation(); + + EXPECT_FALSE(operation_token); +} + +TEST(OperationsControllerTest, ScopedOperationsControllerIsMoveConstructible) { + OperationsController controller; + ScopedShutdown cleanup(&controller); + + controller.StartAcceptingOperations(); + auto operation_token_1 = controller.TryBeginOperation(); + auto operation_token_2 = std::move(operation_token_1); + + EXPECT_FALSE(operation_token_1); + EXPECT_TRUE(operation_token_2); +} + +// Dummy SimpleThread implementation that periodically begins and ends +// operations until one of them fails. +class TestThread : public SimpleThread { + public: + explicit TestThread(OperationsController* ref_controller, + std::atomic<bool>* started, + std::atomic<int32_t>* thread_counter) + : SimpleThread("TestThread"), + controller_(*ref_controller), + started_(*started), + thread_counter_(*thread_counter) {} + void Run() override { + thread_counter_.fetch_add(1, std::memory_order_relaxed); + while (true) { + PlatformThread::YieldCurrentThread(); + bool was_started = started_.load(std::memory_order_relaxed); + std::vector<OperationsController::OperationToken> tokens; + for (int i = 0; i < 100; ++i) { + tokens.push_back(controller_.TryBeginOperation()); + } + if (!was_started) + continue; + if (std::any_of(tokens.begin(), tokens.end(), + [](const auto& token) { return !token; })) { + break; + } + } + } + + private: + OperationsController& controller_; + std::atomic<bool>& started_; + std::atomic<int32_t>& thread_counter_; +}; + +TEST(OperationsControllerTest, BeginsFromMultipleThreads) { + constexpr int32_t kNumThreads = 10; + for (int32_t i = 0; i < 10; ++i) { + OperationsController ref_controller; + std::atomic<bool> started(false); + std::atomic<int32_t> running_threads(0); + std::vector<std::unique_ptr<TestThread>> threads; + for (int j = 0; j < kNumThreads; ++j) { + threads.push_back(std::make_unique<TestThread>(&ref_controller, &started, + &running_threads)); + threads.back()->Start(); + } + + // Make sure all threads are running. + while (running_threads.load(std::memory_order_relaxed) != kNumThreads) { + PlatformThread::YieldCurrentThread(); + } + + // Wait a bit before starting to try to introduce races. + constexpr TimeDelta kRaceInducingTimeout = TimeDelta::FromMicroseconds(50); + PlatformThread::Sleep(kRaceInducingTimeout); + + ref_controller.StartAcceptingOperations(); + // Signal threads to terminate on TryBeginOperation() failures + started.store(true, std::memory_order_relaxed); + + // Let the test run for a while before shuting down. + PlatformThread::Sleep(TimeDelta::FromMilliseconds(5)); + ref_controller.ShutdownAndWaitForZeroOperations(); + for (const auto& t : threads) { + t->Join(); + } + } +} + +} // namespace +} // namespace internal +} // namespace base
diff --git a/base/task/sequence_manager/sequence_manager.h b/base/task/sequence_manager/sequence_manager.h index 09d04949..daa50b83 100644 --- a/base/task/sequence_manager/sequence_manager.h +++ b/base/task/sequence_manager/sequence_manager.h
@@ -140,12 +140,19 @@ // Must be called on the main thread. // TODO(scheduler-dev): SequenceManager should not create TaskQueues. template <typename TaskQueueType, typename... Args> - scoped_refptr<TaskQueueType> CreateTaskQueue(const TaskQueue::Spec& spec, - Args&&... args) { + scoped_refptr<TaskQueueType> CreateTaskQueueWithType( + const TaskQueue::Spec& spec, + Args&&... args) { return WrapRefCounted(new TaskQueueType(CreateTaskQueueImpl(spec), spec, std::forward<Args>(args)...)); } + // Creates a vanilla TaskQueue rather than a user type derived from it. This + // should be used if you don't wish to sub class TaskQueue. + // Must be called on the main thread. + virtual scoped_refptr<TaskQueue> CreateTaskQueue( + const TaskQueue::Spec& spec) = 0; + // Returns true iff this SequenceManager has no immediate work to do // (tasks with unexpired delay are fine, tasks with zero delay and // expired delay are not).
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc index 750681f..64d9924 100644 --- a/base/task/sequence_manager/sequence_manager_impl.cc +++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -876,6 +876,11 @@ return total; } +scoped_refptr<TaskQueue> SequenceManagerImpl::CreateTaskQueue( + const TaskQueue::Spec& spec) { + return WrapRefCounted(new TaskQueue(CreateTaskQueueImpl(spec), spec)); +} + void SequenceManagerImpl::AddDestructionObserver( MessageLoopCurrent::DestructionObserver* destruction_observer) { main_thread_only().destruction_observers.AddObserver(destruction_observer);
diff --git a/base/task/sequence_manager/sequence_manager_impl.h b/base/task/sequence_manager/sequence_manager_impl.h index 97f63f6..de8bed2 100644 --- a/base/task/sequence_manager/sequence_manager_impl.h +++ b/base/task/sequence_manager/sequence_manager_impl.h
@@ -124,6 +124,8 @@ const char* function_name_crash_key) override; const MetricRecordingSettings& GetMetricRecordingSettings() const override; size_t GetPendingTaskCountForTesting() const override; + scoped_refptr<TaskQueue> CreateTaskQueue( + const TaskQueue::Spec& spec) override; // SequencedTaskSource implementation: Optional<PendingTask> TakeTask() override;
diff --git a/base/task/sequence_manager/sequence_manager_impl_unittest.cc b/base/task/sequence_manager/sequence_manager_impl_unittest.cc index 3fe86c3..d4230b5 100644 --- a/base/task/sequence_manager/sequence_manager_impl_unittest.cc +++ b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
@@ -70,7 +70,7 @@ scoped_refptr<TestTaskQueue> CreateTaskQueue( TaskQueue::Spec spec = TaskQueue::Spec("test")) { - return manager_->CreateTaskQueue<TestTaskQueue>(spec); + return manager_->CreateTaskQueueWithType<TestTaskQueue>(spec); } void CreateTaskQueues(size_t num_queues) { @@ -186,8 +186,8 @@ std::make_unique<MessagePumpDefault>(), &mock_clock_)); // ThreadControllerWithMessagePumpImpl doesn't provide // a default task runner. - default_task_queue_ = - manager_->CreateTaskQueue<TestTaskQueue>(TaskQueue::Spec("default")); + default_task_queue_ = manager_->CreateTaskQueueWithType<TestTaskQueue>( + TaskQueue::Spec("default")); manager_->SetDefaultTaskRunner(default_task_queue_->task_runner()); } @@ -3535,7 +3535,8 @@ EXPECT_TRUE(static_cast<SequenceManagerImpl*>(manager.get()) ->IsBoundToCurrentThread()); scoped_refptr<TaskQueue> default_task_queue = - manager->CreateTaskQueue<TestTaskQueue>(TaskQueue::Spec("default")); + manager->CreateTaskQueueWithType<TestTaskQueue>( + TaskQueue::Spec("default")); EXPECT_THAT(default_task_queue.get(), testing::NotNull()); std::unique_ptr<MessageLoop> message_loop(new MessageLoop()); @@ -3885,6 +3886,15 @@ } } +TEST_P(SequenceManagerTest, CreateTaskQueue) { + scoped_refptr<TaskQueue> task_queue = + manager_->CreateTaskQueue(TaskQueue::Spec("test")); + EXPECT_THAT(task_queue.get(), testing::NotNull()); + + task_queue->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask)); + EXPECT_EQ(1u, manager_->GetPendingTaskCountForTesting()); +} + TEST_P(SequenceManagerTest, ThreadName) { std::string kThreadName1("foo"); PlatformThread::SetName(kThreadName1);
diff --git a/base/task/sequence_manager/sequence_manager_perftest.cc b/base/task/sequence_manager/sequence_manager_perftest.cc index 791e4d6..2a04efb 100644 --- a/base/task/sequence_manager/sequence_manager_perftest.cc +++ b/base/task/sequence_manager/sequence_manager_perftest.cc
@@ -108,7 +108,7 @@ scoped_refptr<TaskRunner> CreateTaskRunner() override { scoped_refptr<TestTaskQueue> task_queue = - manager_->CreateTaskQueue<TestTaskQueue>( + manager_->CreateTaskQueueWithType<TestTaskQueue>( TaskQueue::Spec("test").SetTimeDomain(time_domain_.get())); owned_task_queues_.push_back(task_queue); return task_queue->task_runner(); @@ -176,7 +176,7 @@ // ThreadControllerWithMessagePumpImpl doesn't provide a default task // runner. scoped_refptr<TaskQueue> default_task_queue = - GetManager()->template CreateTaskQueue<TestTaskQueue>( + GetManager()->template CreateTaskQueueWithType<TestTaskQueue>( TaskQueue::Spec("default")); GetManager()->SetDefaultTaskRunner(default_task_queue->task_runner()); }
diff --git a/base/task/task_scheduler/scheduler_worker_pool_impl.cc b/base/task/task_scheduler/scheduler_worker_pool_impl.cc index a840e87..a751613 100644 --- a/base/task/task_scheduler/scheduler_worker_pool_impl.cc +++ b/base/task/task_scheduler/scheduler_worker_pool_impl.cc
@@ -482,6 +482,9 @@ return nullptr; } + // Replace this worker if it was the last one, capacity permitting. + outer_->MaintainAtLeastOneIdleWorkerLockRequired(); + // Excess workers should not get work, until they are no longer excess (i.e. // max tasks increases or another worker cleans up). This ensures that if we // have excess workers in the pool, they get a chance to no longer be excess @@ -844,10 +847,6 @@ } } - // Ensure that there is one worker that can run tasks on top of the idle - // stack, capacity permitting. - MaintainAtLeastOneIdleWorkerLockRequired(); - return true; }
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc index 210b5e6..4ca00bf 100644 --- a/base/trace_event/trace_log.cc +++ b/base/trace_event/trace_log.cc
@@ -409,13 +409,15 @@ TraceLog::~TraceLog() = default; void TraceLog::InitializeThreadLocalEventBufferIfSupported() { - // A ThreadLocalEventBuffer needs the message loop + // A ThreadLocalEventBuffer needs the message loop with a task runner // - to know when the thread exits; // - to handle the final flush. - // For a thread without a message loop or the message loop may be blocked, the - // trace events will be added into the main buffer directly. - if (thread_blocks_message_loop_.Get() || !MessageLoopCurrent::IsSet()) + // For a thread without a message loop or if the message loop may be blocked, + // the trace events will be added into the main buffer directly. + if (thread_blocks_message_loop_.Get() || !MessageLoopCurrent::IsSet() || + !ThreadTaskRunnerHandle::IsSet()) { return; + } HEAP_PROFILER_SCOPED_IGNORE; auto* thread_local_event_buffer = thread_local_event_buffer_.Get(); if (thread_local_event_buffer &&
diff --git a/build/android/gyp/bundletool.py b/build/android/gyp/bundletool.py index 9256f99..1f0b2bb7 100755 --- a/build/android/gyp/bundletool.py +++ b/build/android/gyp/bundletool.py
@@ -17,7 +17,7 @@ __file__, '..', '..', '..', '..', 'third_party', 'android_build_tools', 'bundletool')) -BUNDLETOOL_VERSION = '0.6.2' +BUNDLETOOL_VERSION = '0.7.1' BUNDLETOOL_JAR_PATH = os.path.join( BUNDLETOOL_DIR, 'bundletool-all-%s.jar' % BUNDLETOOL_VERSION)
diff --git a/build/config/android/BUILD.gn b/build/config/android/BUILD.gn index 4ebefbf..a94c842 100644 --- a/build/config/android/BUILD.gn +++ b/build/config/android/BUILD.gn
@@ -125,6 +125,7 @@ root_build_dir) } cflags_cc += [ + "-nostdinc++", "-isystem" + libcxx_include_path, "-isystem" + libcxxabi_include_path, ]
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 946fb59..75b99f1 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -520,9 +520,7 @@ } # Makes builds independent of absolute file path. - # Currently disabled for nacl since its toolchain lacks this flag (too old). - # TODO(zforman): Once nacl's toolchain is updated, remove check. - if (symbol_level != 0 && is_clang && !is_nacl && !is_mac && !is_ios && + if (symbol_level != 0 && is_clang && !is_mac && !is_ios && strip_absolute_paths_from_debug_symbols) { # If debug option is given, clang includes $cwd in debug info by default. # For such build, this flag generates reproducible obj files even we use
diff --git a/build/toolchain/toolchain.gni b/build/toolchain/toolchain.gni index 7a87019..83efcd4 100644 --- a/build/toolchain/toolchain.gni +++ b/build/toolchain/toolchain.gni
@@ -23,8 +23,6 @@ use_xcode_clang = is_ios && is_official_build # Used for binary size analysis. - # Currently disabled on LLD because of a bug (fixed upstream). - # See https://crbug.com/716209. generate_linker_map = is_android && is_official_build # Use absolute file paths in the compiler diagnostics and __FILE__ macro
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn index 43fecc65..07319b79 100644 --- a/build/toolchain/win/BUILD.gn +++ b/build/toolchain/win/BUILD.gn
@@ -6,6 +6,7 @@ import("//build/config/compiler/compiler.gni") import("//build/config/sanitizers/sanitizers.gni") import("//build/config/win/visual_studio_version.gni") +import("//build/toolchain/cc_wrapper.gni") import("//build/toolchain/clang_static_analyzer.gni") import("//build/toolchain/goma.gni") import("//build/toolchain/toolchain.gni") @@ -28,8 +29,14 @@ } else { goma_prefix = "$goma_dir/gomacc " } + clang_prefix = goma_prefix } else { goma_prefix = "" + if (cc_wrapper != "") { + clang_prefix = cc_wrapper + " " + } else { + clang_prefix = "" + } } # Copy the VS runtime DLL for the default toolchain to the root build directory @@ -209,7 +216,7 @@ tool("asm") { if (toolchain_args.current_cpu == "arm64") { prefix = rebase_path("$clang_base_path/bin", root_build_dir) - ml = "${goma_prefix}${prefix}/${clang_cl} --target=arm64-windows" + ml = "${clang_prefix}${prefix}/${clang_cl} --target=arm64-windows" } else { if (toolchain_args.current_cpu == "x64") { ml = "ml64.exe /nologo" @@ -397,7 +404,7 @@ msvc_toolchain("win_clang_" + win_build_host_cpu) { environment = "environment." + win_build_host_cpu prefix = rebase_path("$clang_base_path/bin", root_build_dir) - cl = "${goma_prefix}$prefix/${clang_cl}" + cl = "${clang_prefix}$prefix/${clang_cl}" sys_include_flags = "${build_cpu_toolchain_data.include_flags_imsvc}" if (host_os != "win") { # For win cross build. @@ -449,7 +456,7 @@ msvc_toolchain("win_clang_" + target_name) { environment = "environment." + toolchain_arch prefix = rebase_path("$clang_base_path/bin", root_build_dir) - cl = "${goma_prefix}$prefix/${clang_cl}" + cl = "${clang_prefix}$prefix/${clang_cl}" if (toolchain_arch == "arm64") { cl += " --target=arm64-windows" }
diff --git a/cc/OWNERS b/cc/OWNERS index 5a453bed..10a074f 100644 --- a/cc/OWNERS +++ b/cc/OWNERS
@@ -58,6 +58,7 @@ # surfaces fsamuel@chromium.org kylechar@chromium.org +samans@chromium.org # input, scrolling bokan@chromium.org
diff --git a/chrome/VERSION b/chrome/VERSION index d77b1c5..3eacead 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=72 MINOR=0 -BUILD=3616 +BUILD=3617 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 7826eed..e1389a07 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -270,6 +270,7 @@ "//components/module_installer/android:module_installer_java", "//components/navigation_interception/android:navigation_interception_java", "//components/offline_items_collection/core:core_java", + "//components/omnibox/browser:browser_java", "//components/payments/content/android:java", "//components/payments/mojom:mojom_java", "//components/policy/android:policy_java", @@ -367,8 +368,6 @@ "//components/ntp_snippets:ntp_snippets_java_enums_srcjar", "//components/ntp_tiles:ntp_tiles_enums_java", "//components/offline_pages/core:offline_page_model_enums_java", - "//components/omnibox/browser:autocomplete_match_javagen", - "//components/omnibox/browser:autocomplete_match_type_javagen", "//components/search_engines:search_engine_type_java", "//components/security_state/core:security_state_enums_java", "//components/signin/core/browser:investigated_scenario_java", @@ -434,12 +433,12 @@ "//chrome/browser/android/webapk/webapk_install_service.h", "//chrome/browser/android/webapk/webapk_installer.h", "//chrome/browser/android/webapk/webapk_types.h", + "//chrome/browser/autofill/manual_filling_view_interface.h", "//chrome/browser/banners/app_banner_settings_helper.h", "//chrome/browser/notifications/notification_channels_provider_android.h", "//chrome/browser/notifications/notification_platform_bridge_android.cc", "//chrome/browser/ntp_snippets/ntp_snippets_metrics.h", "//chrome/browser/password_manager/password_accessory_metrics_util.h", - "//chrome/browser/password_manager/password_accessory_view_interface.h", "//chrome/browser/profiles/profile_metrics.h", "//chrome/browser/translate/android/translate_utils.h", "//chrome/browser/ui/android/infobars/infobar_android.h", @@ -663,6 +662,7 @@ "//components/navigation_interception/android:navigation_interception_java", "//components/offline_items_collection/core:core_java", "//components/offline_pages/core/prefetch:offline_prefetch_proto_java", + "//components/omnibox/browser:browser_java", "//components/payments/content/android:java", "//components/payments/mojom:mojom_java", "//components/policy/android:policy_java",
diff --git a/chrome/android/java/DEPS b/chrome/android/java/DEPS index 57627e5..881088f 100644 --- a/chrome/android/java/DEPS +++ b/chrome/android/java/DEPS
@@ -15,6 +15,7 @@ "+components/module_installer/android/java/src/org/chromium/components/module_installer", "+components/navigation_interception", "+components/offline_items_collection/core/android/java", + "+components/omnibox/browser/android/java", "+components/payments/content/android/java/src/org/chromium/components/payments", "+components/sync/android/java/src/org/chromium/components/sync", "+components/web_restrictions",
diff --git a/chrome/android/java/res/layout/js_modal_dialog.xml b/chrome/android/java/res/layout/js_modal_dialog.xml index 4bd19f05..fed6b532 100644 --- a/chrome/android/java/res/layout/js_modal_dialog.xml +++ b/chrome/android/java/res/layout/js_modal_dialog.xml
@@ -8,25 +8,11 @@ need (alerts, confirms and prompts). After inflating this layout, we remove the widgets that aren't needed for the current dialog type. --> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<org.chromium.chrome.browser.jsdialog.JavascriptDialogCustomView + xmlns:android="http://schemas.android.com/apk/res/android" style="@style/AlertDialogContent" android:orientation="vertical"> - <ScrollView - android:id="@+id/js_modal_dialog_scroll_view" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1"> - - <TextView - android:id="@+id/js_modal_dialog_message" - style="@style/TextAppearance.AppCompat.Subhead" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_gravity="start" /> - - </ScrollView> - <org.chromium.chrome.browser.widget.AlertDialogEditText android:id="@+id/js_modal_dialog_prompt" android:layout_width="match_parent" @@ -44,4 +30,4 @@ android:textAppearance="?android:attr/textAppearanceSmall" android:text="@string/suppress_js_modal_dialogs" /> -</LinearLayout> +</org.chromium.chrome.browser.jsdialog.JavascriptDialogCustomView>
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml index b2c0dd2f..9882ef70 100644 --- a/chrome/android/java/res/values-v17/styles.xml +++ b/chrome/android/java/res/values-v17/styles.xml
@@ -123,8 +123,6 @@ <item name="android:windowFrame">@null</item> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:backgroundDimAmount">0.5</item> - <item name="android:windowMinWidthMajor">100%</item> - <item name="android:windowMinWidthMinor">100%</item> <item name="buttonBarStyle">@style/ModalDialogButtonBarStyle</item> <item name="buttonBarButtonStyle">@style/ModalDialogButtonStyle</item> <item name="android:windowSoftInputMode">adjustResize|stateHidden</item>
diff --git a/chrome/android/java/res/xml/autofill_and_payments_preference_fragment_screen.xml b/chrome/android/java/res/xml/blank_preference_fragment_screen.xml similarity index 100% rename from chrome/android/java/res/xml/autofill_and_payments_preference_fragment_screen.xml rename to chrome/android/java/res/xml/blank_preference_fragment_screen.xml
diff --git a/chrome/android/java/res/xml/tracing_preferences.xml b/chrome/android/java/res/xml/tracing_preferences.xml index ca36165..321eaad1 100644 --- a/chrome/android/java/res/xml/tracing_preferences.xml +++ b/chrome/android/java/res/xml/tracing_preferences.xml
@@ -4,7 +4,21 @@ found in the LICENSE file. --> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> - <!-- TODO(eseckler): Add configuration options for categories and tracing mode. --> + <Preference + android:fragment="org.chromium.chrome.browser.preferences.developer.TracingCategoriesPreferences" + android:key="default_categories" + android:title="@string/prefs_tracing_default_categories_title" + android:order="0"/> + <Preference + android:fragment="org.chromium.chrome.browser.preferences.developer.TracingCategoriesPreferences" + android:key="non_default_categories" + android:title="@string/prefs_tracing_non_default_categories_title" + android:order="1"/> + <org.chromium.chrome.browser.preferences.ChromeBaseListPreference + android:key="mode" + android:title="@string/prefs_tracing_mode_title" + android:persistent="false" + android:order="2"/> <org.chromium.chrome.browser.preferences.ButtonPreference android:key="start_recording"/> <org.chromium.chrome.browser.preferences.TextMessagePreference
diff --git a/chrome/android/java/src/PRESUBMIT.py b/chrome/android/java/src/PRESUBMIT.py index 4aa1347..dc53f74 100644 --- a/chrome/android/java/src/PRESUBMIT.py +++ b/chrome/android/java/src/PRESUBMIT.py
@@ -67,8 +67,6 @@ blacklist = ( 'chrome/android/java/src/org/chromium/chrome/browser/init/' 'InvalidStartupDialog.java', - 'chrome/android/java/src/org/chromium/chrome/browser/' - 'JavascriptAppModalDialog.java', 'chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/' 'DomDistillerUIUtils.java', 'chrome/android/java/src/org/chromium/chrome/browser/signin/'
diff --git a/chrome/android/java/src/PRESUBMIT_test.py b/chrome/android/java/src/PRESUBMIT_test.py index 522f0cd5..c68e4b9 100755 --- a/chrome/android/java/src/PRESUBMIT_test.py +++ b/chrome/android/java/src/PRESUBMIT_test.py
@@ -81,8 +81,8 @@ 'PermissionDialogView.java', ['new AlertDialog.Builder()']), MockFile( - 'chrome/android/java/src/org/chromium/chrome/browser/' - 'JavascriptAppModalDialog.java', + 'chrome/android/java/src/org/chromium/chrome/browser/payments/' + 'AndroidPaymentApp.java', ['new AlertDialog.Builder()']), MockFile('path/One.java', ['AlertDialog.Builder']), MockFile('path/Two.java', ['// do not: new AlertDialog.Builder()']),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 4e0abcc..02e9248 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -622,9 +622,7 @@ ChromePreferenceManager.PROMOS_SKIPPED_ON_FIRST_START, true); } - if (!isShowingPromo) { - ToolbarButtonInProductHelpController.maybeShowColdStartIPH(this); - } + ToolbarButtonInProductHelpController.create(this, isShowingPromo); if (ChromeFeatureList.isEnabled(ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS)) { // We call getFeedAppLifecycle() here to ensure the app lifecycle is created so that
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/JavascriptAppModalDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/JavascriptAppModalDialog.java deleted file mode 100644 index 68fc37a..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/JavascriptAppModalDialog.java +++ /dev/null
@@ -1,274 +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. - -package org.chromium.chrome.browser; - -import android.content.Context; -import android.content.DialogInterface; -import android.support.v7.app.AlertDialog; -import android.text.TextUtils; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.TextView; - -import org.chromium.base.Log; -import org.chromium.base.VisibleForTesting; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.jsdialog.JavascriptModalDialogView; -import org.chromium.chrome.browser.modaldialog.DialogDismissalCause; -import org.chromium.chrome.browser.modaldialog.ModalDialogManager; -import org.chromium.chrome.browser.modaldialog.ModalDialogView; -import org.chromium.chrome.browser.vr.VrModuleProvider; -import org.chromium.ui.base.WindowAndroid; - -/** - * A dialog shown via JavaScript. This can be an alert dialog, a prompt dialog, a confirm dialog, - * or an onbeforeunload dialog. - */ -public class JavascriptAppModalDialog - implements DialogInterface.OnClickListener, ModalDialogView.Controller { - private static final String TAG = "JSAppModalDialog"; - - private final String mTitle; - private final String mMessage; - private final int mPositiveButtonTextId; - private final int mNegativeButtonTextId; - private final boolean mShouldShowSuppressCheckBox; - private long mNativeDialogPointer; - private AlertDialog mDialog; - private CheckBox mSuppressCheckBox; - private TextView mPromptTextView; - - private ModalDialogManager mModalDialogManager; - private JavascriptModalDialogView mDialogView; - - private JavascriptAppModalDialog(String title, String message, - int positiveButtonTextId, int negativeButtonTextId, - boolean shouldShowSuppressCheckBox) { - mTitle = title; - mMessage = message; - mPositiveButtonTextId = positiveButtonTextId; - mNegativeButtonTextId = negativeButtonTextId; - mShouldShowSuppressCheckBox = shouldShowSuppressCheckBox; - } - - @CalledByNative - public static JavascriptAppModalDialog createAlertDialog(String title, String message, - boolean shouldShowSuppressCheckBox) { - return new JavascriptAppModalDialog(title, message, R.string.ok, 0, - shouldShowSuppressCheckBox); - } - - @CalledByNative - public static JavascriptAppModalDialog createConfirmDialog(String title, String message, - boolean shouldShowSuppressCheckBox) { - return new JavascriptAppModalDialog(title, message, R.string.ok, R.string.cancel, - shouldShowSuppressCheckBox); - } - - @CalledByNative - public static JavascriptAppModalDialog createBeforeUnloadDialog(String title, String message, - boolean isReload, boolean shouldShowSuppressCheckBox) { - return new JavascriptAppModalDialog(title, message, - isReload ? R.string.reload : R.string.leave, R.string.cancel, - shouldShowSuppressCheckBox); - } - - @CalledByNative - public static JavascriptAppModalDialog createPromptDialog(String title, String message, - boolean shouldShowSuppressCheckBox, String defaultPromptText) { - return new JavascriptAppPromptDialog(title, message, shouldShowSuppressCheckBox, - defaultPromptText); - } - - @CalledByNative - void showJavascriptAppModalDialog(WindowAndroid window, long nativeDialogPointer) { - assert window != null; - Context context = window.getActivity().get(); - // If the activity has gone away, then just clean up the native pointer. - if (context == null) { - nativeDidCancelAppModalDialog(nativeDialogPointer, false); - return; - } - - // Cache the native dialog pointer so that we can use it to return the response. - mNativeDialogPointer = nativeDialogPointer; - - if (VrModuleProvider.getDelegate().isInVr()) { - // Use JavascriptModalDialogView while in VR. - ChromeActivity activity = (ChromeActivity) window.getActivity().get(); - mModalDialogManager = activity.getModalDialogManager(); - // Only BeforeUnloadDialog should be created this way, so it is safe to set prompt text - // to null. We also disabled suppress checkbox in VR. In the future, it is possible that - // we bring it back. See https://crbug.com/830057. - assert !(this instanceof JavascriptAppPromptDialog); - mDialogView = JavascriptModalDialogView.create(this, mTitle, mMessage, null, false, - mPositiveButtonTextId, mNegativeButtonTextId); - mModalDialogManager.showDialog(mDialogView, ModalDialogManager.ModalDialogType.TAB); - } else { - LayoutInflater inflater = LayoutInflater.from(context); - ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.js_modal_dialog, null); - mSuppressCheckBox = (CheckBox) layout.findViewById(R.id.suppress_js_modal_dialogs); - mPromptTextView = (TextView) layout.findViewById(R.id.js_modal_dialog_prompt); - - prepare(layout); - - AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.AlertDialogTheme) - .setView(layout) - .setTitle(mTitle) - .setOnCancelListener(dialog -> cancel(false)); - if (mPositiveButtonTextId != 0) builder.setPositiveButton(mPositiveButtonTextId, this); - if (mNegativeButtonTextId != 0) builder.setNegativeButton(mNegativeButtonTextId, this); - - mDialog = builder.create(); - mDialog.setCanceledOnTouchOutside(false); - mDialog.getDelegate().setHandleNativeActionModesEnabled(false); - mDialog.show(); - } - } - - @Override - public void onClick(DialogInterface dialog, int which) { - switch (which) { - case DialogInterface.BUTTON_POSITIVE: - confirm(mPromptTextView.getText().toString(), mSuppressCheckBox.isChecked()); - mDialog.dismiss(); - break; - case DialogInterface.BUTTON_NEGATIVE: - cancel(mSuppressCheckBox.isChecked()); - mDialog.dismiss(); - break; - default: - Log.e(TAG, "Unexpected button pressed in dialog: " + which); - } - } - - @Override - public void onClick(@ModalDialogView.ButtonType int buttonType) { - switch (buttonType) { - case ModalDialogView.ButtonType.POSITIVE: - mModalDialogManager.dismissDialog( - mDialogView, DialogDismissalCause.POSITIVE_BUTTON_CLICKED); - break; - case ModalDialogView.ButtonType.NEGATIVE: - mModalDialogManager.dismissDialog( - mDialogView, DialogDismissalCause.NEGATIVE_BUTTON_CLICKED); - break; - default: - Log.e(TAG, "Unexpected button pressed in dialog: " + buttonType); - } - } - - @Override - public void onDismiss(@DialogDismissalCause int dismissalCause) { - // TODO(https://crbug.com/874537): Add suppression logic in the refactor and make sure it - // doesn't break VR. - switch (dismissalCause) { - case DialogDismissalCause.POSITIVE_BUTTON_CLICKED: - confirm(mDialogView.getPromptText(), false); - break; - case DialogDismissalCause.DISMISSED_BY_NATIVE: - break; - default: - cancel(false); - } - mDialogView = null; - } - - protected void prepare(final ViewGroup layout) { - // Display the checkbox for suppressing dialogs if necessary. - layout.findViewById(R.id.suppress_js_modal_dialogs).setVisibility( - mShouldShowSuppressCheckBox ? View.VISIBLE : View.GONE); - - // If the message is null or empty do not display the message text view. - // Hide parent scroll view instead of text view in order to prevent ui discrepancies. - if (TextUtils.isEmpty(mMessage)) { - layout.findViewById(R.id.js_modal_dialog_scroll_view).setVisibility(View.GONE); - } else { - ((TextView) layout.findViewById(R.id.js_modal_dialog_message)).setText(mMessage); - - layout.findViewById(R.id.js_modal_dialog_scroll_view) - .addOnLayoutChangeListener( - (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { - boolean isScrollable = - v.getMeasuredHeight() - v.getPaddingTop() - - v.getPaddingBottom() - < ((ViewGroup) v).getChildAt(0).getMeasuredHeight(); - - v.setFocusable(isScrollable); - }); - } - } - - private void confirm(String promptResult, boolean suppressDialogs) { - if (mNativeDialogPointer != 0) { - nativeDidAcceptAppModalDialog(mNativeDialogPointer, promptResult, suppressDialogs); - } - } - - private void cancel(boolean suppressDialogs) { - if (mNativeDialogPointer != 0) { - nativeDidCancelAppModalDialog(mNativeDialogPointer, suppressDialogs); - } - } - - @CalledByNative - private void dismiss() { - if (mDialog != null) { - mDialog.dismiss(); - } else { - mModalDialogManager.dismissDialog( - mDialogView, DialogDismissalCause.DISMISSED_BY_NATIVE); - } - mNativeDialogPointer = 0; - } - - /** - * Returns the currently showing dialog, null if none is showing. - */ - @VisibleForTesting - public static JavascriptAppModalDialog getCurrentDialogForTest() { - return nativeGetCurrentModalDialog(); - } - - /** - * Returns the AlertDialog associated with this JavascriptAppPromptDialog. - */ - @VisibleForTesting - public AlertDialog getDialogForTest() { - return mDialog; - } - - private static class JavascriptAppPromptDialog extends JavascriptAppModalDialog { - private final String mDefaultPromptText; - - JavascriptAppPromptDialog(String title, String message, boolean shouldShowSuppressCheckBox, - String defaultPromptText) { - super(title, message, R.string.ok, R.string.cancel, shouldShowSuppressCheckBox); - mDefaultPromptText = defaultPromptText; - } - - @Override - protected void prepare(ViewGroup layout) { - super.prepare(layout); - EditText prompt = (EditText) layout.findViewById(R.id.js_modal_dialog_prompt); - prompt.setVisibility(View.VISIBLE); - - if (mDefaultPromptText.length() > 0) { - prompt.setText(mDefaultPromptText); - prompt.selectAll(); - } - } - } - - private native void nativeDidAcceptAppModalDialog(long nativeJavascriptAppModalDialogAndroid, - String prompt, boolean suppress); - private native void nativeDidCancelAppModalDialog(long nativeJavascriptAppModalDialogAndroid, - boolean suppress); - private static native JavascriptAppModalDialog nativeGetCurrentModalDialog(); -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillNameFixFlowPrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillNameFixFlowPrompt.java index e710879..99085a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillNameFixFlowPrompt.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillNameFixFlowPrompt.java
@@ -13,7 +13,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.inputmethod.EditorInfo; -import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.TextView.BufferType; @@ -190,8 +189,6 @@ mModalDialogManager = activity.getModalDialogManager(); mModalDialogManager.showDialog(mDialog, ModalDialogManager.ModalDialogType.APP); - - Button saveButton = mDialog.getButton(ModalDialogView.ButtonType.POSITIVE); } protected void dismiss() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java index 8dfdc37a..da72723 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java
@@ -25,7 +25,6 @@ import android.view.accessibility.AccessibilityEvent; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; -import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageView; @@ -41,7 +40,11 @@ import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.modaldialog.DialogDismissalCause; import org.chromium.chrome.browser.modaldialog.ModalDialogManager; +import org.chromium.chrome.browser.modaldialog.ModalDialogProperties; import org.chromium.chrome.browser.modaldialog.ModalDialogView; +import org.chromium.chrome.browser.modaldialog.ModalDialogViewBinder; +import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -54,6 +57,7 @@ private static CardUnmaskObserverForTest sObserverForTest; private final CardUnmaskPromptDelegate mDelegate; + private final PropertyModel mDialogModel; private final ModalDialogView mDialog; private boolean mShouldRequestExpirationDate; @@ -194,13 +198,19 @@ mSuccessMessageDurationMilliseconds = successMessageDurationMilliseconds; ((ImageView) v.findViewById(R.id.cvc_hint_image)).setImageResource(drawableId); - ModalDialogView.Params params = new ModalDialogView.Params(); - params.title = title; - params.customView = v; - params.negativeButtonTextId = R.string.cancel; - params.positiveButtonText = confirmButtonLabel; - params.cancelOnTouchOutside = false; - mDialog = new ModalDialogView(this, params); + Resources resources = context.getResources(); + mDialogModel = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) + .with(ModalDialogProperties.CONTROLLER, this) + .with(ModalDialogProperties.TITLE, title) + .with(ModalDialogProperties.CUSTOM_VIEW, v) + .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, confirmButtonLabel) + .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, + R.string.cancel) + .build(); + + mDialog = new ModalDialogView(context); + PropertyModelChangeProcessor.create(mDialogModel, mDialog, new ModalDialogViewBinder()); + mShouldRequestExpirationDate = shouldRequestExpirationDate; mThisYear = -1; mThisMonth = -1; @@ -214,8 +224,7 @@ // Hitting the "submit" button on the software keyboard should submit the form if valid. mCardUnmaskInput.setOnEditorActionListener((v14, actionId, event) -> { if (actionId == EditorInfo.IME_ACTION_DONE) { - Button positiveButton = mDialog.getButton(ModalDialogView.ButtonType.POSITIVE); - if (positiveButton.isEnabled()) positiveButton.performClick(); + onClick(ModalDialogView.ButtonType.POSITIVE); return true; } return false; @@ -236,7 +245,6 @@ }); // Load the error messages to show to the user. - Resources resources = context.getResources(); mCvcErrorMessage = resources.getString(R.string.autofill_card_unmask_prompt_error_try_again_cvc); mExpirationMonthErrorMessage = resources.getString( @@ -281,8 +289,7 @@ // Override the View.OnClickListener so that pressing the positive button doesn't dismiss // the dialog. - Button verifyButton = mDialog.getButton(ModalDialogView.ButtonType.POSITIVE); - verifyButton.setEnabled(false); + mDialogModel.set(ModalDialogProperties.POSITIVE_BUTTON_DISABLED, true); mCardUnmaskInput.addTextChangedListener(this); mCardUnmaskInput.post(() -> setInitialFocus()); } @@ -348,17 +355,16 @@ * is wrong. Finally checks whether the focuse should move to the next field. */ private void validate() { - Button positiveButton = mDialog.getButton(ModalDialogView.ButtonType.POSITIVE); - @ErrorType int errorType = getExpirationAndCvcErrorType(); - positiveButton.setEnabled(errorType == ErrorType.NONE); + mDialogModel.set( + ModalDialogProperties.POSITIVE_BUTTON_DISABLED, errorType != ErrorType.NONE); showDetailedErrorMessage(errorType); moveFocus(errorType); if (sObserverForTest != null) { sObserverForTest.onCardUnmaskPromptValidationDone(this); - if (positiveButton.isEnabled()) { + if (!mDialogModel.get(ModalDialogProperties.POSITIVE_BUTTON_DISABLED)) { sObserverForTest.onCardUnmaskPromptReadyToUnmask(this); } } @@ -636,7 +642,7 @@ mMonthInput.setEnabled(enabled); mYearInput.setEnabled(enabled); mStoreLocallyCheckbox.setEnabled(enabled); - mDialog.getButton(ModalDialogView.ButtonType.POSITIVE).setEnabled(enabled); + mDialogModel.set(ModalDialogProperties.POSITIVE_BUTTON_DISABLED, !enabled); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessoryBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingBridge.java similarity index 91% rename from chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessoryBridge.java rename to chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingBridge.java index 4e439ba..2841213 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessoryBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingBridge.java
@@ -21,7 +21,7 @@ import java.util.ArrayList; import java.util.List; -class PasswordAccessoryBridge { +class ManualFillingBridge { private final KeyboardAccessoryData.PropertyProvider<Item[]> mItemProvider = new KeyboardAccessoryData.PropertyProvider<>(); private final KeyboardAccessoryData.PropertyProvider<Action[]> mActionProvider = @@ -31,7 +31,7 @@ private final ChromeActivity mActivity; private long mNativeView; - private PasswordAccessoryBridge(long nativeView, WindowAndroid windowAndroid) { + private ManualFillingBridge(long nativeView, WindowAndroid windowAndroid) { mNativeView = nativeView; mActivity = (ChromeActivity) windowAndroid.getActivity().get(); mManualFillingCoordinator = mActivity.getManualFillingController(); @@ -40,8 +40,8 @@ } @CalledByNative - private static PasswordAccessoryBridge create(long nativeView, WindowAndroid windowAndroid) { - return new PasswordAccessoryBridge(nativeView, windowAndroid); + private static ManualFillingBridge create(long nativeView, WindowAndroid windowAndroid) { + return new ManualFillingBridge(nativeView, windowAndroid); } @CalledByNative @@ -152,8 +152,10 @@ mNativeView, item.isObfuscated(), item.getCaption()); }; } + // clang-format off items.add(Item.createSuggestion(field.getDisplayText(), field.getA11yDescription(), field.isObfuscated(), itemSelectedCallback, this::fetchFavicon)); + // clang-format on } } @@ -177,11 +179,11 @@ nativeOnFaviconRequested(mNativeView, desiredSize, faviconCallback); } - private native void nativeOnFaviconRequested(long nativePasswordAccessoryViewAndroid, + private native void nativeOnFaviconRequested(long nativeManualFillingViewAndroid, int desiredSizeInPx, Callback<Bitmap> faviconCallback); private native void nativeOnFillingTriggered( - long nativePasswordAccessoryViewAndroid, boolean isObfuscated, String textToFill); + long nativeManualFillingViewAndroid, boolean isObfuscated, String textToFill); private native void nativeOnOptionSelected( - long nativePasswordAccessoryViewAndroid, String selectedOption); - private native void nativeOnGenerationRequested(long nativePasswordAccessoryViewAndroid); + long nativeManualFillingViewAndroid, String selectedOption); + private native void nativeOnGenerationRequested(long nativeManualFillingViewAndroid); } \ No newline at end of file
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 0c6fe13..ebf2499 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
@@ -238,8 +238,6 @@ .findViewById(R.id.autofill_assistant); // TODO(crbug.com/806868): Set hint text on overlay. mTouchEventFilter = (TouchEventFilter) mFullContainer.findViewById(R.id.touch_event_filter); - mTouchEventFilter.init(client, activity.getFullscreenManager(), - activity.getActivityTab().getWebContents()); mBottomBar = mFullContainer.findViewById(R.id.bottombar); mBottomBar.findViewById(R.id.close_button) .setOnClickListener(unusedView -> mClient.onDismiss()); @@ -403,6 +401,8 @@ public void show() { if (mFullContainer.getVisibility() != View.VISIBLE) { + mTouchEventFilter.init(mClient, mActivity.getFullscreenManager(), + mActivity.getActivityTab().getWebContents()); mFullContainer.setVisibility(View.VISIBLE); // Set the initial progress. It is OK to make multiple calls to this method as it will @@ -412,6 +412,7 @@ } public void hide() { + mTouchEventFilter.deInit(); mFullContainer.setVisibility(View.GONE); } @@ -767,6 +768,9 @@ webContents, paymentOptions, unusedTitle, supportedBasicCardNetworks); // Make sure we wrap content in the container. mBottomBarAnimations.setBottomBarHeightToWrapContent(); + // Note: We show and hide (below) the carousel so that the margins are adjusted correctly. + // This is an intermediate adjustment before the UI refactoring. + mBottomBarAnimations.showCarousel(); mPaymentRequest.show(mCarouselScroll, callback); enableProgressBarPulsing(); } @@ -776,6 +780,7 @@ mPaymentRequest.close(); mPaymentRequest = null; mBottomBarAnimations.setBottomBarHeightToFixed(); + mBottomBarAnimations.hideCarousel(); disableProgressBarPulsing(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/ui/TouchEventFilter.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/ui/TouchEventFilter.java index 21301cd..e9944a2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/ui/TouchEventFilter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/ui/TouchEventFilter.java
@@ -66,6 +66,7 @@ private Client mClient; private ChromeFullscreenManager mFullscreenManager; + private GestureListenerManager mGestureListenerManager; private final List<RectF> mTouchableArea = new ArrayList<>(); private final Paint mGrayOut; private final Paint mClear; @@ -174,7 +175,20 @@ mClient = client; mFullscreenManager = fullscreenManager; mFullscreenManager.addListener(this); - GestureListenerManager.fromWebContents(webContents).addListener(this); + mGestureListenerManager = GestureListenerManager.fromWebContents(webContents); + mGestureListenerManager.addListener(this); + } + + public void deInit() { + mClient = null; + if (mFullscreenManager != null) { + mFullscreenManager.removeListener(this); + mFullscreenManager = null; + } + if (mGestureListenerManager != null) { + mGestureListenerManager.removeListener(this); + mGestureListenerManager = null; + } } /** Sets the color to be used for unusable areas. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java b/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java index fc507d9..56b50519 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java
@@ -4,11 +4,15 @@ package org.chromium.chrome.browser.banners; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; import android.graphics.Bitmap; -import android.os.Looper; +import org.chromium.base.ContextUtils; +import org.chromium.base.Log; +import org.chromium.base.PackageUtils; import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNIAdditionalImport; import org.chromium.base.annotations.JNINamespace; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.webapps.AddToHomescreenDialog; @@ -18,15 +22,12 @@ * is created by and owned by the native AppBannerUiDelegate. */ @JNINamespace("banners") -@JNIAdditionalImport(InstallerDelegate.class) -public class AppBannerUiDelegateAndroid - implements AddToHomescreenDialog.Delegate, InstallerDelegate.Observer { +public class AppBannerUiDelegateAndroid implements AddToHomescreenDialog.Delegate { + private static final String TAG = "AppBannerUi"; + /** Pointer to the native AppBannerUiDelegateAndroid. */ private long mNativePointer; - /** Delegate which does the actual monitoring of an in-progress installation. */ - private InstallerDelegate mInstallerDelegate; - private Tab mTab; private AddToHomescreenDialog mDialog; @@ -61,31 +62,9 @@ } mDialog = null; - mInstallerDelegate = null; mAddedToHomescreen = false; } - @Override - public void onInstallIntentCompleted(InstallerDelegate delegate, boolean isInstalling) { - // Do nothing. - } - - @Override - public void onInstallFinished(InstallerDelegate delegate, boolean success) { - // Do nothing. - } - - @Override - public void onApplicationStateChanged(InstallerDelegate delegate, int newState) { - // Do nothing. - } - - /** Creates the installer delegate with the specified observer. */ - @CalledByNative - public void createInstallerDelegate(InstallerDelegate.Observer observer) { - mInstallerDelegate = new InstallerDelegate(Looper.getMainLooper(), observer); - } - @CalledByNative private AddToHomescreenDialog getDialogForTesting() { return mDialog; @@ -93,17 +72,29 @@ @CalledByNative private void destroy() { - if (mInstallerDelegate != null) { - mInstallerDelegate.destroy(); - } - mInstallerDelegate = null; mNativePointer = 0; mAddedToHomescreen = false; } @CalledByNative - private boolean installOrOpenNativeApp(AppData appData, String referrer) { - return mInstallerDelegate.installOrOpenNativeApp(mTab, appData, referrer); + private boolean installOrOpenNativeApp(AppData appData) { + Context context = ContextUtils.getApplicationContext(); + Intent launchIntent; + if (PackageUtils.isPackageInstalled(context, appData.packageName())) { + launchIntent = + context.getPackageManager().getLaunchIntentForPackage(appData.packageName()); + } else { + launchIntent = appData.installIntent(); + } + if (launchIntent != null && mTab.getActivity() != null) { + try { + mTab.getActivity().startActivity(launchIntent); + } catch (ActivityNotFoundException e) { + Log.e(TAG, "Failed to install or open app : %s!", appData.packageName(), e); + return false; + } + } + return true; } @CalledByNative @@ -113,7 +104,6 @@ @CalledByNative private boolean showNativeAppDialog(String title, Bitmap iconBitmap, AppData appData) { - createInstallerDelegate(this); mDialog = new AddToHomescreenDialog(mTab.getActivity(), this); mDialog.show(); mDialog.onUserTitleAvailable(title, appData.installButtonText(), appData.rating()); @@ -131,11 +121,6 @@ } @CalledByNative - private int determineInstallState(String packageName) { - return mInstallerDelegate.determineInstallState(packageName); - } - - @CalledByNative private static AppBannerUiDelegateAndroid create(long nativePtr, Tab tab) { return new AppBannerUiDelegateAndroid(nativePtr, tab); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/banners/InstallerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/banners/InstallerDelegate.java deleted file mode 100644 index b6c1bdec..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/banners/InstallerDelegate.java +++ /dev/null
@@ -1,310 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.banners; - -import android.app.Activity; -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.os.Handler; -import android.os.Looper; -import android.os.SystemClock; -import android.support.annotation.IntDef; -import android.text.TextUtils; - -import org.chromium.base.ActivityState; -import org.chromium.base.ApplicationStatus; -import org.chromium.base.ContextUtils; -import org.chromium.base.Log; -import org.chromium.base.VisibleForTesting; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.ui.base.WindowAndroid; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.concurrent.TimeUnit; - -/** - * Monitors the app installation process and informs an observer of updates. - */ -public class InstallerDelegate { - /** Observer methods called for the different stages of app installation. */ - public static interface Observer { - /** - * Called when the installation intent completes to inform the observer if installation has - * begun. For instance, the user may have rejected the intent. - * @param delegate The delegate object sending the message. - * @param isInstalling true if the app is currently installing. - */ - public void onInstallIntentCompleted(InstallerDelegate delegate, boolean isInstalling); - - /** - * Called when the task has finished. - * @param delegate The delegate object sending the message. - * @param success Whether or not the package was successfully installed. - */ - public void onInstallFinished(InstallerDelegate delegate, boolean success); - - /** - * Called when the current application state changes due to an installation. - * @param delegate The delegate object sending the message. - * @param newState The new state id. - */ - public void onApplicationStateChanged( - InstallerDelegate delegate, @ActivityState int newState); - } - - /** - * Object to wait for the PackageManager to finish installation an app. For convenience, this is - * bound to an instance of InstallerDelegate, and accesses its members and methods. - */ - private class InstallMonitor implements Runnable { - /** Timestamp of when we started monitoring. */ - private long mTimestampStarted; - - public InstallMonitor() {} - - /** Begin monitoring the PackageManager to see if it completes installing the package. */ - public void start() { - mTimestampStarted = SystemClock.elapsedRealtime(); - mIsRunning = true; - mHandler.postDelayed(this, mMsBetweenRuns); - } - - /** Don't call this directly; instead, call {@link #start()}. */ - @Override - public void run() { - boolean isPackageInstalled = isInstalled(mPackageName); - boolean waitedTooLong = - (SystemClock.elapsedRealtime() - mTimestampStarted) > mMsMaximumWaitingTime; - if (isPackageInstalled || !mIsRunning || waitedTooLong) { - mIsRunning = false; - mObserver.onInstallFinished(InstallerDelegate.this, isPackageInstalled); - } else { - mHandler.postDelayed(this, mMsBetweenRuns); - } - } - - /** Prevent rescheduling the Runnable. */ - public void cancel() { - mIsRunning = false; - } - } - - // Installation states. - @IntDef({InstallState.NOT_INSTALLED, InstallState.INSTALLING, InstallState.INSTALLED}) - @Retention(RetentionPolicy.SOURCE) - public @interface InstallState { - int NOT_INSTALLED = 0; - int INSTALLING = 1; - int INSTALLED = 2; - } - - private static final String TAG = "cr_InstallerDelegate"; - private static final long DEFAULT_MS_BETWEEN_RUNS = TimeUnit.SECONDS.toMillis(1); - private static final long DEFAULT_MS_MAXIMUM_WAITING_TIME = TimeUnit.MINUTES.toMillis(3); - - /** PackageManager to use in place of the real one. */ - private static PackageManager sPackageManagerForTests; - - /** Monitors an installation in progress. */ - private InstallMonitor mInstallMonitor; - - /** Message loop to post the Runnable to. */ - private final Handler mHandler; - - /** Monitors for application state changes. */ - private final ApplicationStatus.ApplicationStateListener mListener; - - /** The name of the package currently being installed. */ - private String mPackageName; - - /** Milliseconds to wait between calls to check on the PackageManager during installation. */ - private long mMsBetweenRuns; - - /** Maximum milliseconds to wait before giving up on monitoring during installation. */ - private long mMsMaximumWaitingTime; - - /** The observer to inform of updates during the installation process. */ - private Observer mObserver; - - /** Whether or we are currently monitoring an installation. */ - private boolean mIsRunning; - - /** Overrides the PackageManager for testing. */ - @VisibleForTesting - static void setPackageManagerForTesting(PackageManager manager) { - sPackageManagerForTests = manager; - } - - /** - * Set how often the handler will check the PackageManager. - * @param msBetween How long to wait between executions of the Runnable. - * @param msMax How long to wait before giving up. - */ - @VisibleForTesting - void setTimingForTests(long msBetween, long msMax) { - mMsBetweenRuns = msBetween; - mMsMaximumWaitingTime = msMax; - } - - /** - * Checks if the app has been installed on the system. - * @return true if the PackageManager reports that the app is installed, false otherwise. - * @param packageManager PackageManager to use. - * @param packageName Name of the package to check. - */ - public static boolean isInstalled(PackageManager packageManager, String packageName) { - try { - packageManager.getPackageInfo(packageName, 0); - } catch (PackageManager.NameNotFoundException e) { - return false; - } - return true; - } - - /** - * Construct an InstallerDelegate to monitor an installation. - * @param looper Thread to run the monitor on. - * @param observer Object to inform of changes in the installation state. - */ - public InstallerDelegate(Looper looper, Observer observer) { - mHandler = new Handler(looper); - mObserver = observer; - mListener = createApplicationStateListener(); - ApplicationStatus.registerApplicationStateListener(mListener); - - mMsBetweenRuns = DEFAULT_MS_BETWEEN_RUNS; - mMsMaximumWaitingTime = DEFAULT_MS_MAXIMUM_WAITING_TIME; - } - - /** - * Checks if the app has been installed on the system. - * @return true if the PackageManager reports that the app is installed, false otherwise. - * @param packageName Name of the package to check. - */ - public boolean isInstalled(String packageName) { - return isInstalled(getPackageManager(ContextUtils.getApplicationContext()), packageName); - } - - /** - * Stops all current monitoring. - */ - public void destroy() { - if (mInstallMonitor != null) { - mInstallMonitor.cancel(); - mInstallMonitor = null; - } - ApplicationStatus.unregisterApplicationStateListener(mListener); - } - - /** - * Returns the current installation state of the provided package name - * @return the installation state - not installed, installing, or installed. - * @param packageName Name of the package to check. - */ - public @InstallState int determineInstallState(String packageName) { - if (mIsRunning) return InstallState.INSTALLING; - return isInstalled(packageName) ? InstallState.INSTALLED : InstallState.NOT_INSTALLED; - } - - /** - * Attempts to open the specified package name in the given content. - * @return true if successfully opened, otherwise false (e.g. not installed/opening failed). - * @param packageName Name of the package to open. - */ - public boolean openApp(String packageName) { - Context context = ContextUtils.getApplicationContext(); - PackageManager packageManager = getPackageManager(context); - if (!isInstalled(packageManager, packageName)) return false; - - Intent launchIntent = packageManager.getLaunchIntentForPackage(packageName); - if (launchIntent != null) { - try { - context.startActivity(launchIntent); - } catch (ActivityNotFoundException e) { - Log.e(TAG, "Failed to open app : %s!", packageName, e); - return false; - } - } - return true; - } - - /** - * Attempts to install or open a native app specified by the given data. - * @return true if the app was opened or installation was started successfully. false otherwise. - * @param tab The current tab. - * @param appData The native app data to try and open or install. - * @param referrer The referrer attached to the URL specifying the native app, if any. - */ - public boolean installOrOpenNativeApp(Tab tab, AppData appData, String referrer) { - if (openApp(appData.packageName())) { - return true; - } else { - // If the installation was started, return false to prevent the infobar disappearing. - // The supplied referrer is the URL of the page requesting the native app banner. It may - // be empty depending on that page's referrer policy. If it is non-empty, attach it to - // the installation intent as Intent.EXTRA_REFERRER. - Intent installIntent = appData.installIntent(); - if (!TextUtils.isEmpty(referrer)) { - installIntent.putExtra(Intent.EXTRA_REFERRER, referrer); - } - return !tab.getWindowAndroid().showIntent( - installIntent, createIntentCallback(appData), null); - } - } - - /** - * Start monitoring an installation. Should be called once per the lifetime of this object. - * @param packageName The name of the package to monitor. - * */ - public void startMonitoring(String packageName) { - mPackageName = packageName; - mInstallMonitor = new InstallMonitor(); - mInstallMonitor.start(); - } - - /** Checks to see if we are currently monitoring an installation. */ - @VisibleForTesting - boolean isRunning() { - return mIsRunning; - } - - /** Simulates a cancellation for testing purposes. */ - @VisibleForTesting - void cancel() { - mInstallMonitor.cancel(); - } - - private WindowAndroid.IntentCallback createIntentCallback(final AppData appData) { - return new WindowAndroid.IntentCallback() { - @Override - public void onIntentCompleted(WindowAndroid window, int resultCode, Intent data) { - boolean isInstalling = resultCode == Activity.RESULT_OK; - if (isInstalling) { - startMonitoring(appData.packageName()); - } - - mObserver.onInstallIntentCompleted(InstallerDelegate.this, isInstalling); - } - }; - } - - private ApplicationStatus.ApplicationStateListener createApplicationStateListener() { - return new ApplicationStatus.ApplicationStateListener() { - @Override - public void onApplicationStateChange(int newState) { - if (!ApplicationStatus.hasVisibleActivities()) return; - mObserver.onApplicationStateChanged(InstallerDelegate.this, newState); - } - }; - } - - private PackageManager getPackageManager(Context context) { - if (sPackageManagerForTests != null) return sPackageManagerForTests; - return context.getPackageManager(); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index ac39128..0faa83d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -110,9 +110,7 @@ import org.chromium.chrome.browser.webapps.WebappCustomTabTimeSpentLogger; import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; import org.chromium.content_public.browser.LoadUrlParams; -import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.NavigationEntry; -import org.chromium.content_public.browser.NavigationHistory; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.PageTransition; @@ -372,32 +370,6 @@ } } - /** - * @return The index of the previous navigation history entry managed by a dynamic module - * or -1 if there is no such entry. - */ - private boolean goToModuleManagedNavigationIndex() { - if (mModuleActivityDelegate == null && mModuleCallback == null) return false; - NavigationController navigationController = getNavigationController(); - if (navigationController == null) return false; - - NavigationHistory history = navigationController.getNavigationHistory(); - for (int i = history.getCurrentEntryIndex() - 1; i >= 0; i--) { - if (isModuleManagedUrl(history.getEntryAtIndex(i).getUrl())) { - navigationController.goToNavigationIndex(i); - return true; - } - } - - return false; - } - - @Nullable - private NavigationController getNavigationController() { - WebContents webContents = getActivityTab().getWebContents(); - return webContents == null ? null : webContents.getNavigationController(); - } - @VisibleForTesting void maybeInitialiseDynamicModulePostMessageHandler(PostMessageBackend backend) { // Only initialise the handler if the feature is enabled. @@ -555,8 +527,12 @@ } private CustomTabDelegateFactory createCustomTabDelegateFactory() { + // Don't show an app install banner for the user of a Trusted Web Activity - they've already + // got an app installed! + // TODO(peconn): Look into allowing the banner again if the user leaves the Trusted origin. + boolean allowAppBanners = !mIntentDataProvider.isTrustedWebActivity(); return new CustomTabDelegateFactory(mIntentDataProvider.shouldEnableUrlBarHiding(), - mIntentDataProvider.isOpenedByChrome(), + mIntentDataProvider.isOpenedByChrome(), allowAppBanners, getComponent().resolveControlsVisibilityDelegate()); } @@ -620,11 +596,6 @@ if (mIntentDataProvider.shouldEnableEmbeddedMediaExperience()) { RecordUserAction.record("CustomTabs.CloseButtonClicked.DownloadsUI"); } - if (goToModuleManagedNavigationIndex()) { - RecordUserAction.record( - "CustomTabs.CloseButtonClicked.GoToModuleManagedUrl"); - return; - } recordClientConnectionStatus(); finishAndClose(false); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java index e1fb5cd2..fc4dbdc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java
@@ -192,6 +192,7 @@ private final boolean mShouldHideBrowserControls; private final boolean mIsOpenedByChrome; + private final boolean mShouldAllowAppBanners; private final BrowserControlsVisibilityDelegate mBrowserStateVisibilityDelegate; private ExternalNavigationDelegateImpl mNavigationDelegate; @@ -200,16 +201,26 @@ /** * @param shouldHideBrowserControls Whether or not the browser controls may auto-hide. * @param isOpenedByChrome Whether the CustomTab was originally opened by Chrome. + * @param shouldAllowAppBanners Whether app install banners can be shown. * @param visibilityDelegate The delegate that handles browser control visibility associated * with browser actions (as opposed to tab state). */ public CustomTabDelegateFactory(boolean shouldHideBrowserControls, boolean isOpenedByChrome, - BrowserControlsVisibilityDelegate visibilityDelegate) { + boolean shouldAllowAppBanners, BrowserControlsVisibilityDelegate visibilityDelegate) { mShouldHideBrowserControls = shouldHideBrowserControls; mIsOpenedByChrome = isOpenedByChrome; + mShouldAllowAppBanners = shouldAllowAppBanners; mBrowserStateVisibilityDelegate = visibilityDelegate; } + /** + * Creates a basic/empty CustomTabDelegateFactory for use when creating a hidden tab. It will + * be replaced when the hidden Tab becomes shown. + */ + static CustomTabDelegateFactory createDummy() { + return new CustomTabDelegateFactory(false, false, false, null); + } + @Override public BrowserControlsVisibilityDelegate createBrowserControlsVisibilityDelegate(Tab tab) { TabStateBrowserControlsVisibilityDelegate tabDelegate = @@ -247,6 +258,11 @@ ChromeContextMenuPopulator.ContextMenuMode.CUSTOM_TAB); } + @Override + public boolean canShowAppBanners(Tab tab) { + return mShouldAllowAppBanners; + } + /** * @return The {@link ExternalNavigationHandler} in this tab. For test purpose only. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index 97d4b0d..29a9db42 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -134,12 +134,10 @@ "org.chromium.chrome.browser.customtabs.EXTRA_MODULE_MANAGED_URLS_REGEX"; /** The APK package to load the module from. */ - @VisibleForTesting /* package */ static final String EXTRA_MODULE_PACKAGE_NAME = "org.chromium.chrome.browser.customtabs.EXTRA_MODULE_PACKAGE_NAME"; /** The class name of the module entry point. */ - @VisibleForTesting /* package */ static final String EXTRA_MODULE_CLASS_NAME = "org.chromium.chrome.browser.customtabs.EXTRA_MODULE_CLASS_NAME";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java index de04d9e6..5d03f665 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
@@ -1445,7 +1445,7 @@ if (extras != null) extrasIntent.putExtras(extras); if (IntentHandler.getExtraHeadersFromIntent(extrasIntent) != null) return; - Tab tab = Tab.createDetached(new CustomTabDelegateFactory(false, false, null)); + Tab tab = Tab.createDetached(CustomTabDelegateFactory.createDummy()); HiddenTabObserver observer = new HiddenTabObserver(this); tab.addObserver(observer);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManager.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManager.java index 00dea81..dda8688 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManager.java
@@ -31,9 +31,11 @@ import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; +import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.ProcessInitException; import org.chromium.chrome.browser.ChromeApplication; import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.download.DownloadNotificationUmaHelper.UmaDownloadResumption; import org.chromium.chrome.browser.download.items.OfflineContentAggregatorNotificationBridgeUiFactory; import org.chromium.chrome.browser.init.BrowserParts; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; @@ -43,6 +45,7 @@ import org.chromium.components.offline_items_collection.ContentId; import org.chromium.components.offline_items_collection.LegacyHelpers; import org.chromium.components.offline_items_collection.PendingState; +import org.chromium.content_public.browser.BrowserStartupController; /** * Class that spins up native when an interaction with a notification happens and passes the @@ -170,12 +173,20 @@ */ @VisibleForTesting void loadNativeAndPropagateInteraction(final Intent intent) { + final boolean browserStarted = + BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER) + .isStartupSuccessfullyCompleted(); final BrowserParts parts = new EmptyBrowserParts() { @Override public void finishNativeInitialization() { // Delay the stop of the service by WAIT_TIME_MS after native library is loaded. mHandler.postDelayed(mStopSelfRunnable, WAIT_TIME_MS); + if (ACTION_DOWNLOAD_RESUME.equals(intent.getAction())) { + DownloadNotificationUmaHelper.recordDownloadResumptionHistogram(browserStarted + ? UmaDownloadResumption.BROWSER_RUNNING + : UmaDownloadResumption.BROWSER_NOT_RUNNING); + } propagateInteraction(intent); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java index 2a93153..a2b390d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -32,6 +32,7 @@ import org.chromium.base.task.AsyncTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.download.DownloadMetrics.DownloadOpenSource; +import org.chromium.chrome.browser.download.DownloadNotificationUmaHelper.UmaDownloadResumption; import org.chromium.chrome.browser.download.ui.BackendProvider; import org.chromium.chrome.browser.externalnav.ExternalNavigationDelegateImpl; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; @@ -108,20 +109,6 @@ private static final String PREF_IS_DOWNLOAD_HOME_ENABLED = "org.chromium.chrome.browser.download.IS_DOWNLOAD_HOME_ENABLED"; - // Values for the histogram MobileDownloadResumptionCount. - @IntDef({UmaDownloadResumption.MANUAL_PAUSE, UmaDownloadResumption.BROWSER_KILLED, - UmaDownloadResumption.CLICKED, UmaDownloadResumption.FAILED, - UmaDownloadResumption.AUTO_STARTED}) - @Retention(RetentionPolicy.SOURCE) - private @interface UmaDownloadResumption { - int MANUAL_PAUSE = 0; - int BROWSER_KILLED = 1; - int CLICKED = 2; - int FAILED = 3; - int AUTO_STARTED = 4; - int NUM_ENTRIES = 5; - } - // Set will be more expensive to initialize, so use an ArrayList here. private static final List<String> MIME_TYPES_TO_OPEN = new ArrayList<String>(Arrays.asList( OMADownloadHandler.OMA_DOWNLOAD_DESCRIPTOR_MIME, @@ -498,7 +485,8 @@ case DownloadStatus.IN_PROGRESS: if (info.isPaused()) { mDownloadNotifier.notifyDownloadPaused(info); - recordDownloadResumption(UmaDownloadResumption.MANUAL_PAUSE); + DownloadNotificationUmaHelper.recordDownloadResumptionHistogram( + UmaDownloadResumption.MANUAL_PAUSE); } else { mDownloadNotifier.notifyDownloadProgress( info, progress.mStartTimeInMillis, progress.mCanDownloadWhileMetered); @@ -973,14 +961,15 @@ } int uma = hasUserGesture ? UmaDownloadResumption.CLICKED : UmaDownloadResumption.AUTO_STARTED; - recordDownloadResumption(uma); + DownloadNotificationUmaHelper.recordDownloadResumptionHistogram(uma); if (progress == null) { assert !item.getDownloadInfo().isPaused(); // If the download was not resumed before, the browser must have been killed while the // download is active. if (!sFirstSeenDownloadIds.contains(item.getId())) { sFirstSeenDownloadIds.add(item.getId()); - recordDownloadResumption(UmaDownloadResumption.BROWSER_KILLED); + DownloadNotificationUmaHelper.recordDownloadResumptionHistogram( + UmaDownloadResumption.BROWSER_KILLED); } updateDownloadProgress(item, DownloadStatus.IN_PROGRESS); progress = mDownloadProgressMap.get(item.getId()); @@ -1140,7 +1129,8 @@ .setFailState(FailState.CANNOT_DOWNLOAD) .build()); removeDownloadProgress(downloadGuid); - recordDownloadResumption(UmaDownloadResumption.FAILED); + DownloadNotificationUmaHelper.recordDownloadResumptionHistogram( + UmaDownloadResumption.FAILED); recordDownloadFinishedUMA(DownloadStatus.FAILED, downloadGuid, 0); } @@ -1178,15 +1168,6 @@ } /** - * Helper method to record the download resumption UMA. - * @param type UMA type to be recorded. - */ - private void recordDownloadResumption(@UmaDownloadResumption int type) { - RecordHistogram.recordEnumeratedHistogram( - "MobileDownload.DownloadResumption", type, UmaDownloadResumption.NUM_ENTRIES); - } - - /** * Helper method to record the metrics when a download completes. * @param useDownloadManager Whether the download goes through Android DownloadManager. * @param status Download completion status.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java index e44ebd51f6..d2a550f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationUmaHelper.java
@@ -74,6 +74,23 @@ int NUM_ENTRIES = 5; } + // Values for the histogram MobileDownloadResumptionCount. + @IntDef({UmaDownloadResumption.MANUAL_PAUSE, UmaDownloadResumption.BROWSER_KILLED, + UmaDownloadResumption.CLICKED, UmaDownloadResumption.FAILED, + UmaDownloadResumption.AUTO_STARTED, UmaDownloadResumption.BROWSER_RUNNING, + UmaDownloadResumption.BROWSER_NOT_RUNNING}) + @Retention(RetentionPolicy.SOURCE) + public @interface UmaDownloadResumption { + int MANUAL_PAUSE = 0; + int BROWSER_KILLED = 1; + int CLICKED = 2; + int FAILED = 3; + int AUTO_STARTED = 4; + int BROWSER_RUNNING = 5; + int BROWSER_NOT_RUNNING = 6; + int NUM_ENTRIES = 7; + } + /** * Records an instance where a user interacts with a notification (clicks on, pauses, etc). * @param action Notification interaction that was taken (ie. pause, resume). @@ -164,4 +181,13 @@ StateAtCancel.NUM_ENTRIES); } } + + /** + * Helper method to record the download resumption UMA. + * @param type UMA type to be recorded. + */ + static void recordDownloadResumptionHistogram(@UmaDownloadResumption int type) { + RecordHistogram.recordEnumeratedHistogram( + "MobileDownload.DownloadResumption", type, UmaDownloadResumption.NUM_ENTRIES); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoDisclosureActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoDisclosureActivity.java index cdf473b..7979c3f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoDisclosureActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoDisclosureActivity.java
@@ -6,6 +6,7 @@ import android.content.Context; import android.content.Intent; +import android.content.res.Resources; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; @@ -18,8 +19,12 @@ import org.chromium.chrome.browser.modaldialog.DialogDismissalCause; import org.chromium.chrome.browser.modaldialog.ModalDialogManager; import org.chromium.chrome.browser.modaldialog.ModalDialogManager.ModalDialogType; +import org.chromium.chrome.browser.modaldialog.ModalDialogProperties; import org.chromium.chrome.browser.modaldialog.ModalDialogView; import org.chromium.chrome.browser.modaldialog.ModalDialogView.ButtonType; +import org.chromium.chrome.browser.modaldialog.ModalDialogViewBinder; +import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; import org.chromium.chrome.browser.profiles.Profile; /** @@ -49,13 +54,20 @@ contentView.findViewById(R.id.incognito_disclosure_close_incognito_checkbox); checkBox.setOnCheckedChangeListener((view, isChecked) -> mCloseIncognitoTabs = isChecked); - ModalDialogView.Params params = new ModalDialogView.Params(); - params.customView = contentView; - params.title = getString(R.string.incognito_disclosure_title); - params.positiveButtonText = getString(R.string.ok_got_it); - params.negativeButtonText = getString(R.string.cancel); + Resources resources = getResources(); + PropertyModel model = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) + .with(ModalDialogProperties.CONTROLLER, mDialogController) + .with(ModalDialogProperties.TITLE, resources, + R.string.incognito_disclosure_title) + .with(ModalDialogProperties.CUSTOM_VIEW, contentView) + .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, + R.string.ok_got_it) + .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, + R.string.cancel) + .build(); - ModalDialogView dialog = new ModalDialogView(mDialogController, params); + ModalDialogView dialog = new ModalDialogView(this); + PropertyModelChangeProcessor.create(model, dialog, new ModalDialogViewBinder()); new ModalDialogManager(new AppModalPresenter(this), ModalDialogType.APP) .showDialog(dialog, ModalDialogType.APP);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java index da9585f1..c371954 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java
@@ -13,11 +13,11 @@ import android.widget.ImageView; import org.chromium.base.ContextUtils; +import org.chromium.base.PackageUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.chrome.R; import org.chromium.chrome.browser.banners.AppBannerManager; import org.chromium.chrome.browser.banners.AppData; -import org.chromium.chrome.browser.banners.InstallerDelegate; import org.chromium.chrome.browser.widget.DualControlLayout; /** @@ -34,7 +34,6 @@ // Data for native app installs. private final AppData mAppData; - private @InstallerDelegate.InstallState int mInstallState; // Data for web app installs. private final String mAppUrl; @@ -45,7 +44,6 @@ mAppTitle = appTitle; mAppData = data; mAppUrl = null; - mInstallState = InstallerDelegate.InstallState.NOT_INSTALLED; } // Banner for web apps. @@ -54,7 +52,6 @@ mAppTitle = appTitle; mAppData = null; mAppUrl = url; - mInstallState = InstallerDelegate.InstallState.NOT_INSTALLED; } @Override @@ -115,45 +112,23 @@ } } - @Override - public void onButtonClicked(boolean isPrimaryButton) { - if (isPrimaryButton && mInstallState == InstallerDelegate.InstallState.INSTALLING) { - setControlsEnabled(true); - updateButton(); - return; - } - super.onButtonClicked(isPrimaryButton); - } - - @CalledByNative - public void onInstallStateChanged(int newState) { - setControlsEnabled(true); - mInstallState = newState; - updateButton(); - } - private void updateButton() { if (mButton == null || mAppData == null) return; String text; String accessibilityText = null; - boolean enabled = true; Context context = getContext(); - if (mInstallState == InstallerDelegate.InstallState.NOT_INSTALLED) { + if (PackageUtils.isPackageInstalled(context, mAppData.packageName())) { + text = context.getString(R.string.app_banner_open); + } else { text = mAppData.installButtonText(); accessibilityText = context.getString( R.string.app_banner_view_native_app_install_accessibility, text); - } else if (mInstallState == InstallerDelegate.InstallState.INSTALLING) { - text = context.getString(R.string.app_banner_installing); - mButton.announceForAccessibility(text); - enabled = false; - } else { - text = context.getString(R.string.app_banner_open); } mButton.setText(text); mButton.setContentDescription(accessibilityText); - mButton.setEnabled(enabled); + mButton.setEnabled(true); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java deleted file mode 100644 index b52f740f..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.infobar; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; -import org.chromium.chrome.browser.banners.InstallerDelegate; - -/** - * Handles the promotion and installation of an app specified by the current web page. This object - * is created by and owned by the native AppBannerInfoBarDelegateAndroid. - */ -@JNINamespace("banners") -public class AppBannerInfoBarDelegateAndroid implements InstallerDelegate.Observer { - /** Pointer to the native AppBannerInfoBarDelegateAndroid. */ - private long mNativePointer; - - private AppBannerInfoBarDelegateAndroid(long nativePtr) { - mNativePointer = nativePtr; - } - - @Override - public void onInstallIntentCompleted(InstallerDelegate delegate, boolean isInstalling) { - if (mNativePointer != 0) nativeOnInstallIntentReturned(mNativePointer, isInstalling); - } - - @Override - public void onInstallFinished(InstallerDelegate delegate, boolean success) { - if (mNativePointer != 0) nativeOnInstallFinished(mNativePointer, success); - } - - @Override - public void onApplicationStateChanged(InstallerDelegate delegate, int newState) { - if (mNativePointer != 0) nativeUpdateInstallState(mNativePointer); - } - - @CalledByNative - private void destroy() { - mNativePointer = 0; - } - - @CalledByNative - private static AppBannerInfoBarDelegateAndroid create(long nativePtr) { - return new AppBannerInfoBarDelegateAndroid(nativePtr); - } - - private native void nativeOnInstallIntentReturned( - long nativeAppBannerInfoBarDelegateAndroid, boolean isInstalling); - private native void nativeOnInstallFinished( - long nativeAppBannerInfoBarDelegateAndroid, boolean success); - private native void nativeUpdateInstallState(long nativeAppBannerInfoBarDelegateAndroid); -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptAppModalDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptAppModalDialog.java new file mode 100644 index 0000000..133eaeb2 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptAppModalDialog.java
@@ -0,0 +1,108 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.jsdialog; + +import org.chromium.base.VisibleForTesting; +import org.chromium.base.annotations.CalledByNative; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.modaldialog.DialogDismissalCause; +import org.chromium.chrome.browser.modaldialog.ModalDialogManager; +import org.chromium.ui.base.WindowAndroid; + +/** + * A dialog shown via JavaScript. This can be an alert dialog, a prompt dialog, a confirm dialog, + * or an onbeforeunload dialog. + */ +public class JavascriptAppModalDialog extends JavascriptModalDialog { + private long mNativeDialogPointer; + + /** + * Constructor for initializing contents to be shown on the dialog. + */ + private JavascriptAppModalDialog(String title, String message, String promptText, + boolean shouldShowSuppressCheckBox, int positiveButtonTextId, + int negativeButtonTextId) { + super(title, message, promptText, shouldShowSuppressCheckBox, positiveButtonTextId, + negativeButtonTextId); + } + + @CalledByNative + public static JavascriptAppModalDialog createAlertDialog( + String title, String message, boolean shouldShowSuppressCheckBox) { + return new JavascriptAppModalDialog( + title, message, null, shouldShowSuppressCheckBox, R.string.ok, 0); + } + + @CalledByNative + public static JavascriptAppModalDialog createConfirmDialog( + String title, String message, boolean shouldShowSuppressCheckBox) { + return new JavascriptAppModalDialog( + title, message, null, shouldShowSuppressCheckBox, R.string.ok, R.string.cancel); + } + + @CalledByNative + public static JavascriptAppModalDialog createBeforeUnloadDialog( + String title, String message, boolean isReload, boolean shouldShowSuppressCheckBox) { + return new JavascriptAppModalDialog(title, message, null, shouldShowSuppressCheckBox, + isReload ? R.string.reload : R.string.leave, R.string.cancel); + } + + @CalledByNative + public static JavascriptAppModalDialog createPromptDialog(String title, String message, + boolean shouldShowSuppressCheckBox, String defaultPromptText) { + return new JavascriptAppModalDialog(title, message, defaultPromptText, + shouldShowSuppressCheckBox, R.string.ok, R.string.cancel); + } + + @CalledByNative + void showJavascriptAppModalDialog(WindowAndroid window, long nativeDialogPointer) { + assert window != null; + ChromeActivity activity = (ChromeActivity) window.getActivity().get(); + // If the activity has gone away, then just clean up the native pointer. + if (activity == null) { + nativeDidCancelAppModalDialog(nativeDialogPointer, false); + return; + } + + // Cache the native dialog pointer so that we can use it to return the response. + mNativeDialogPointer = nativeDialogPointer; + show(activity, ModalDialogManager.ModalDialogType.APP); + } + + @CalledByNative + private void dismiss() { + dismiss(DialogDismissalCause.DISMISSED_BY_NATIVE); + mNativeDialogPointer = 0; + } + + @Override + protected void accept(String promptResult, boolean suppressDialogs) { + if (mNativeDialogPointer != 0) { + nativeDidAcceptAppModalDialog(mNativeDialogPointer, promptResult, suppressDialogs); + } + } + + @Override + protected void cancel(boolean buttonClicked, boolean suppressDialogs) { + if (mNativeDialogPointer != 0) { + nativeDidCancelAppModalDialog(mNativeDialogPointer, suppressDialogs); + } + } + + /** + * Returns the currently showing dialog, null if none is showing. + */ + @VisibleForTesting + public static JavascriptAppModalDialog getCurrentDialogForTest() { + return nativeGetCurrentModalDialog(); + } + + private native void nativeDidAcceptAppModalDialog( + long nativeJavascriptAppModalDialogAndroid, String prompt, boolean suppress); + private native void nativeDidCancelAppModalDialog( + long nativeJavascriptAppModalDialogAndroid, boolean suppress); + private static native JavascriptAppModalDialog nativeGetCurrentModalDialog(); +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptDialogCustomView.java b/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptDialogCustomView.java new file mode 100644 index 0000000..3a77a28f --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptDialogCustomView.java
@@ -0,0 +1,73 @@ +// 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.jsdialog; + +import android.content.Context; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.LinearLayout; + +import org.chromium.chrome.R; + +/** + * The JavaScript dialog that is either app modal or tab modal. + */ +public class JavascriptDialogCustomView extends LinearLayout { + private EditText mPromptEditText; + private CheckBox mSuppressCheckBox; + + /** + * Constructor for inflating from XMLs. + */ + public JavascriptDialogCustomView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + mPromptEditText = findViewById(R.id.js_modal_dialog_prompt); + mSuppressCheckBox = findViewById(R.id.suppress_js_modal_dialogs); + } + + /** + * @param promptText Prompt text for prompt dialog. If null, prompt text is not visible. + */ + public void setPromptText(String promptText) { + if (promptText == null) return; + mPromptEditText.setVisibility(View.VISIBLE); + + if (promptText.length() > 0) { + mPromptEditText.setText(promptText); + mPromptEditText.selectAll(); + } + } + + /** + * @return The prompt text edited by user. + */ + public String getPromptText() { + return mPromptEditText.getText().toString(); + } + + /** + * @param visible Whether the suppress check box should be visible. The check box should only + * be set visible if applicable for app modal JavaScript dialogs. + */ + public void setSuppressCheckBoxVisibility(boolean visible) { + mSuppressCheckBox.setVisibility(visible ? View.VISIBLE : View.GONE); + } + + /** + * @return Whether the suppress check box is checked by user. + */ + public boolean isSuppressCheckBoxChecked() { + return mSuppressCheckBox.isChecked(); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptModalDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptModalDialog.java new file mode 100644 index 0000000..9501654 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptModalDialog.java
@@ -0,0 +1,143 @@ +// 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.jsdialog; + +import android.content.res.Resources; +import android.support.annotation.StringRes; +import android.view.LayoutInflater; + +import org.chromium.base.Log; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.modaldialog.DialogDismissalCause; +import org.chromium.chrome.browser.modaldialog.ModalDialogManager; +import org.chromium.chrome.browser.modaldialog.ModalDialogProperties; +import org.chromium.chrome.browser.modaldialog.ModalDialogView; +import org.chromium.chrome.browser.modaldialog.ModalDialogViewBinder; +import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; + +/** + * A base class for creating, showing and dismissing a modal dialog for a JavaScript popup. + */ +public abstract class JavascriptModalDialog implements ModalDialogView.Controller { + private static final String TAG = "JSModalDialog"; + + private final String mTitle; + private final String mMessage; + private final int mPositiveButtonTextId; + private final int mNegativeButtonTextId; + private final String mDefaultPromptText; + private final boolean mShouldShowSuppressCheckBox; + + private ModalDialogManager mModalDialogManager; + private ModalDialogView mDialogView; + protected JavascriptDialogCustomView mDialogCustomView; + + protected JavascriptModalDialog(String title, String message, String promptText, + boolean shouldShowSuppressCheckBox, @StringRes int positiveButtonTextId, + @StringRes int negativeButtonTextId) { + mTitle = title; + mMessage = message; + mPositiveButtonTextId = positiveButtonTextId; + mNegativeButtonTextId = negativeButtonTextId; + mDefaultPromptText = promptText; + mShouldShowSuppressCheckBox = shouldShowSuppressCheckBox; + } + + /** + * Showing a modal dialog for a JavaScript popup with the specified dialog type. + * @param activity The {@link ChromeActivity} that this dialog is shown upon. + * @param dialogType The {@link ModalDialogManager.ModalDialogType} of the dialog. + */ + protected void show( + ChromeActivity activity, @ModalDialogManager.ModalDialogType int dialogType) { + mDialogCustomView = (JavascriptDialogCustomView) LayoutInflater.from(activity).inflate( + R.layout.js_modal_dialog, null); + mDialogCustomView.setPromptText(mDefaultPromptText); + mDialogCustomView.setSuppressCheckBoxVisibility(mShouldShowSuppressCheckBox); + + Resources resources = activity.getResources(); + PropertyModel model = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) + .with(ModalDialogProperties.CONTROLLER, this) + .with(ModalDialogProperties.TITLE, mTitle) + .with(ModalDialogProperties.MESSAGE, mMessage) + .with(ModalDialogProperties.CUSTOM_VIEW, mDialogCustomView) + .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, + mPositiveButtonTextId) + .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, + mNegativeButtonTextId) + .with(ModalDialogProperties.TITLE_SCROLLABLE, true) + .build(); + + mDialogView = new ModalDialogView(activity); + PropertyModelChangeProcessor.create(model, mDialogView, new ModalDialogViewBinder()); + + mModalDialogManager = activity.getModalDialogManager(); + mModalDialogManager.showDialog(mDialogView, dialogType); + } + + /** + * Dismissing the dialog with the specified reason. + * @param dismissalCause The specified reason that the dialog is dismissed. + */ + protected void dismiss(@DialogDismissalCause int dismissalCause) { + if (mModalDialogManager == null) return; + mModalDialogManager.dismissDialog(mDialogView, dismissalCause); + } + + @Override + public void onClick(@ModalDialogView.ButtonType int buttonType) { + if (mModalDialogManager == null) return; + switch (buttonType) { + case ModalDialogView.ButtonType.POSITIVE: + mModalDialogManager.dismissDialog( + mDialogView, DialogDismissalCause.POSITIVE_BUTTON_CLICKED); + break; + case ModalDialogView.ButtonType.NEGATIVE: + mModalDialogManager.dismissDialog( + mDialogView, DialogDismissalCause.NEGATIVE_BUTTON_CLICKED); + break; + default: + Log.e(TAG, "Unexpected button pressed in dialog: " + buttonType); + } + } + + @Override + public void onDismiss(@DialogDismissalCause int dismissalCause) { + if (mDialogCustomView == null) return; + switch (dismissalCause) { + case DialogDismissalCause.POSITIVE_BUTTON_CLICKED: + accept(mDialogCustomView.getPromptText(), + mDialogCustomView.isSuppressCheckBoxChecked()); + break; + case DialogDismissalCause.NEGATIVE_BUTTON_CLICKED: + cancel(true, mDialogCustomView.isSuppressCheckBoxChecked()); + break; + case DialogDismissalCause.DISMISSED_BY_NATIVE: + // We don't need to call native back in this case. + break; + default: + cancel(false, mDialogCustomView.isSuppressCheckBoxChecked()); + } + mDialogView = null; + mDialogCustomView = null; + mModalDialogManager = null; + } + + /** + * Sends notification to native that the user accepts the dialog. + * @param promptResult The text edited by user. + * @param suppressDialogs Whether the upcoming JavaScript popups should be suppressed. + */ + protected abstract void accept(String promptResult, boolean suppressDialogs); + + /** + * Sends notification to native that the user accepts the dialog. + * @param buttonClicked Whether the dialog is cancelled by user clicking the cancel button. + * @param suppressDialogs Whether the upcoming JavaScript popups should be suppressed. + */ + protected abstract void cancel(boolean buttonClicked, boolean suppressDialogs); +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptModalDialogView.java b/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptModalDialogView.java deleted file mode 100644 index dc5427d..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptModalDialogView.java +++ /dev/null
@@ -1,106 +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. - -package org.chromium.chrome.browser.jsdialog; - -import android.support.annotation.StringRes; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.CheckBox; -import android.widget.EditText; - -import org.chromium.chrome.R; -import org.chromium.chrome.browser.modaldialog.ModalDialogView; - -/** - * The JavaScript dialog that is either app modal or tab modal. - */ -public class JavascriptModalDialogView extends ModalDialogView { - private final EditText mPromptEditText; - private final CheckBox mSuppressCheckBox; - - /** - * Create a {@link JavascriptModalDialogView} with the specified properties. - * @param controller The controller for the dialog view. - * @param title The title of the dialog view. - * @param message The message of the dialog view. - * @param promptText The promptText of the dialog view. If null, - * prompt edit text will not be shown. - * @param shouldShowSuppressCheckBox Whether the suppress check box should be shown. - * @param positiveButtonTextId The string resource id of the positive button. - * @param negativeButtonTextId The string resource id of the negative button. - * @return A {@link JavascriptModalDialogView} with the specified properties. - */ - public static JavascriptModalDialogView create(Controller controller, String title, - String message, String promptText, boolean shouldShowSuppressCheckBox, - @StringRes int positiveButtonTextId, @StringRes int negativeButtonTextId) { - Params params = new Params(); - params.title = title; - params.message = message; - params.positiveButtonTextId = positiveButtonTextId; - params.negativeButtonTextId = negativeButtonTextId; - LayoutInflater inflater = LayoutInflater.from(ModalDialogView.getContext()); - params.customView = inflater.inflate(R.layout.js_modal_dialog, null); - params.titleScrollable = true; - - return new JavascriptModalDialogView( - controller, params, message, promptText, shouldShowSuppressCheckBox); - } - - private JavascriptModalDialogView(Controller controller, Params params, String message, - String promptText, boolean shouldShowSuppressCheckBox) { - super(controller, params); - - mPromptEditText = params.customView.findViewById(R.id.js_modal_dialog_prompt); - mSuppressCheckBox = params.customView.findViewById(R.id.suppress_js_modal_dialogs); - - // TODO(huayinz): Remove this scroll view once JavaScript dialogs are fully switched to use - // ModalDialogView. - params.customView.findViewById(R.id.js_modal_dialog_scroll_view).setVisibility(View.GONE); - setPromptText(promptText); - setSuppressCheckBoxVisibility(shouldShowSuppressCheckBox); - - View scrollView = getView().findViewById(R.id.modal_dialog_scroll_view); - scrollView.addOnLayoutChangeListener( - (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { - boolean isScrollable = v.canScrollVertically(-1) || v.canScrollVertically(1); - v.setFocusable(isScrollable); - }); - } - - /** - * @param promptText Prompt text for prompt dialog. If null, prompt text is not visible. - */ - private void setPromptText(String promptText) { - if (promptText == null) return; - mPromptEditText.setVisibility(View.VISIBLE); - - if (promptText.length() > 0) { - mPromptEditText.setText(promptText); - mPromptEditText.selectAll(); - } - } - - /** - * @return The prompt text edited by user. - */ - public String getPromptText() { - return mPromptEditText.getText().toString(); - } - - /** - * @param visible Whether the suppress check box should be visible. The check box should only - * be set visible if applicable for app modal JavaScript dialogs. - */ - private void setSuppressCheckBoxVisibility(boolean visible) { - mSuppressCheckBox.setVisibility(visible ? View.VISIBLE : View.GONE); - } - - /** - * @return Whether the suppress check box is checked by user. - */ - public boolean isSuppressCheckBoxChecked() { - return mSuppressCheckBox.isChecked(); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptTabModalDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptTabModalDialog.java index 90404e5..37b776a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptTabModalDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptTabModalDialog.java
@@ -4,65 +4,42 @@ package org.chromium.chrome.browser.jsdialog; -import org.chromium.base.Log; import org.chromium.base.annotations.CalledByNative; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.modaldialog.DialogDismissalCause; import org.chromium.chrome.browser.modaldialog.ModalDialogManager; -import org.chromium.chrome.browser.modaldialog.ModalDialogView; import org.chromium.ui.base.WindowAndroid; /** * The controller to communicate with native JavaScriptDialogAndroid for a tab modal JavaScript * dialog. This can be an alert dialog, a prompt dialog or a confirm dialog. */ -public class JavascriptTabModalDialog implements ModalDialogView.Controller { - private static final String TAG = "JsTabModalDialog"; - - private final String mTitle; - private final String mMessage; - private final int mPositiveButtonTextId; - private final int mNegativeButtonTextId; - - private ModalDialogManager mModalDialogManager; - private String mDefaultPromptText; +public class JavascriptTabModalDialog extends JavascriptModalDialog { private long mNativeDialogPointer; - private JavascriptModalDialogView mDialogView; /** * Constructor for initializing contents to be shown on the dialog. */ private JavascriptTabModalDialog( - String title, String message, int positiveButtonTextId, int negativeButtonTextId) { - mTitle = title; - mMessage = message; - mPositiveButtonTextId = positiveButtonTextId; - mNegativeButtonTextId = negativeButtonTextId; - } - - /** - * Constructor for creating prompt dialog only. - */ - private JavascriptTabModalDialog(String title, String message, String defaultPromptText) { - this(title, message, R.string.ok, R.string.cancel); - mDefaultPromptText = defaultPromptText; + String title, String message, String promptText, int negativeButtonTextId) { + super(title, message, promptText, false, R.string.ok, negativeButtonTextId); } @CalledByNative private static JavascriptTabModalDialog createAlertDialog(String title, String message) { - return new JavascriptTabModalDialog(title, message, R.string.ok, 0); + return new JavascriptTabModalDialog(title, message, null, 0); } @CalledByNative private static JavascriptTabModalDialog createConfirmDialog(String title, String message) { - return new JavascriptTabModalDialog(title, message, R.string.ok, R.string.cancel); + return new JavascriptTabModalDialog(title, message, null, R.string.cancel); } @CalledByNative private static JavascriptTabModalDialog createPromptDialog( String title, String message, String defaultPromptText) { - return new JavascriptTabModalDialog(title, message, defaultPromptText); + return new JavascriptTabModalDialog(title, message, defaultPromptText, R.string.cancel); } @CalledByNative @@ -77,63 +54,26 @@ // Cache the native dialog pointer so that we can use it to return the response. mNativeDialogPointer = nativeDialogPointer; - - mModalDialogManager = activity.getModalDialogManager(); - mDialogView = JavascriptModalDialogView.create(this, mTitle, mMessage, mDefaultPromptText, - false, mPositiveButtonTextId, mNegativeButtonTextId); - mModalDialogManager.showDialog(mDialogView, ModalDialogManager.ModalDialogType.TAB); + show(activity, ModalDialogManager.ModalDialogType.TAB); } @CalledByNative private String getUserInput() { - return mDialogView.getPromptText(); + return mDialogCustomView.getPromptText(); } @CalledByNative private void dismiss() { - mModalDialogManager.dismissDialog(mDialogView, DialogDismissalCause.DISMISSED_BY_NATIVE); + dismiss(DialogDismissalCause.DISMISSED_BY_NATIVE); mNativeDialogPointer = 0; } - @Override - public void onClick(@ModalDialogView.ButtonType int buttonType) { - switch (buttonType) { - case ModalDialogView.ButtonType.POSITIVE: - mModalDialogManager.dismissDialog( - mDialogView, DialogDismissalCause.POSITIVE_BUTTON_CLICKED); - break; - case ModalDialogView.ButtonType.NEGATIVE: - mModalDialogManager.dismissDialog( - mDialogView, DialogDismissalCause.NEGATIVE_BUTTON_CLICKED); - break; - default: - Log.e(TAG, "Unexpected button pressed in dialog: " + buttonType); - } - } - - @Override - public void onDismiss(@DialogDismissalCause int dismissalCause) { - switch (dismissalCause) { - case DialogDismissalCause.POSITIVE_BUTTON_CLICKED: - accept(mDialogView.getPromptText()); - break; - case DialogDismissalCause.NEGATIVE_BUTTON_CLICKED: - cancel(true); - break; - case DialogDismissalCause.DISMISSED_BY_NATIVE: - // We don't need to call native back in this case. - break; - default: - cancel(false); - } - mDialogView = null; - } - /** * Sends notification to native that the user accepts the dialog. * @param promptResult The text edited by user. */ - private void accept(String promptResult) { + @Override + protected void accept(String promptResult, boolean suppressDialogs) { if (mNativeDialogPointer == 0) return; nativeAccept(mNativeDialogPointer, promptResult); } @@ -141,7 +81,8 @@ /** * Sends notification to native that the user cancels the dialog. */ - private void cancel(boolean buttonClicked) { + @Override + protected void cancel(boolean buttonClicked, boolean suppressDialogs) { if (mNativeDialogPointer == 0) return; nativeCancel(mNativeDialogPointer, buttonClicked); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/language/LanguageAskPrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/language/LanguageAskPrompt.java index 889f331e..fa44a121 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/language/LanguageAskPrompt.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/language/LanguageAskPrompt.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.language; import android.content.Context; +import android.content.res.Resources; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.ViewHolder; @@ -23,7 +24,11 @@ import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.modaldialog.DialogDismissalCause; import org.chromium.chrome.browser.modaldialog.ModalDialogManager; +import org.chromium.chrome.browser.modaldialog.ModalDialogProperties; import org.chromium.chrome.browser.modaldialog.ModalDialogView; +import org.chromium.chrome.browser.modaldialog.ModalDialogViewBinder; +import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.preferences.languages.LanguageItem; import org.chromium.components.language.AndroidLanguageMetricsBridge; @@ -295,15 +300,9 @@ mInitialLanguages.addAll(userAcceptLanguagesList); mLanguagesUpdate = new HashSet<String>(mInitialLanguages); - ModalDialogView.Params params = new ModalDialogView.Params(); - params.title = activity.getString(R.string.languages_explicit_ask_title); - params.positiveButtonTextId = R.string.save; - params.negativeButtonTextId = R.string.cancel; - params.cancelOnTouchOutside = true; - - params.customView = LayoutInflater.from(activity).inflate( + View customView = LayoutInflater.from(activity).inflate( R.layout.language_ask_prompt_content, null, false); - RecyclerView list = (RecyclerView) params.customView.findViewById(R.id.recycler_view); + RecyclerView list = customView.findViewById(R.id.recycler_view); LanguageItemAdapter adapter = new LanguageItemAdapter(activity, mLanguagesUpdate); list.setAdapter(adapter); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(activity); @@ -311,8 +310,8 @@ list.setLayoutManager(linearLayoutManager); list.setHasFixedSize(true); - ImageView topShadow = (ImageView) params.customView.findViewById(R.id.top_shadow); - ImageView bottomShadow = (ImageView) params.customView.findViewById(R.id.bottom_shadow); + ImageView topShadow = customView.findViewById(R.id.top_shadow); + ImageView bottomShadow = customView.findViewById(R.id.bottom_shadow); mListScrollListener = new ListScrollListener(list, topShadow, bottomShadow); List<LanguageItem> languages = PrefServiceBridge.getInstance().getChromeLanguageList(); @@ -346,8 +345,22 @@ adapter.setLanguages(topLanguages, bottomLanguages); + Resources resources = activity.getResources(); + PropertyModel model = + new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) + .with(ModalDialogProperties.CONTROLLER, this) + .with(ModalDialogProperties.TITLE, resources, + R.string.languages_explicit_ask_title) + .with(ModalDialogProperties.CUSTOM_VIEW, customView) + .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, R.string.save) + .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, + R.string.cancel) + .with(ModalDialogProperties.CANCEL_ON_TOUCH_OUTSIDE, true) + .build(); + mDialog = new ModalDialogView(activity); + PropertyModelChangeProcessor.create(model, mDialog, new ModalDialogViewBinder()); + mModalDialogManager = activity.getModalDialogManager(); - mDialog = new ModalDialogView(this, params); mModalDialogManager.showDialog(mDialog, ModalDialogManager.ModalDialogType.APP); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/BaseSessionController.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/BaseSessionController.java index 73df8b20..bd1e327 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/BaseSessionController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/BaseSessionController.java
@@ -205,4 +205,12 @@ public FlingingController getFlingingController() { return null; } + + /** + * Helper message to get the session ID of the attached session. For stubbing in tests as + * {@link CastSession#getSessionId()} is final. + */ + public String getSessionId() { + return isConnected() ? getSession().getSessionId() : null; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafBaseMediaRouteProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafBaseMediaRouteProvider.java index 5c6a15ab..0d4228a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafBaseMediaRouteProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafBaseMediaRouteProvider.java
@@ -6,6 +6,7 @@ import android.os.Handler; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import android.support.v7.media.MediaRouteSelector; import android.support.v7.media.MediaRouter; import android.support.v7.media.MediaRouter.RouteInfo; @@ -43,7 +44,8 @@ protected final MediaRouteManager mManager; protected final Map<String, DiscoveryCallback> mDiscoveryCallbacks = new HashMap<String, DiscoveryCallback>(); - protected final Map<String, MediaRoute> mRoutes = new HashMap<String, MediaRoute>(); + @VisibleForTesting + final Map<String, MediaRoute> mRoutes = new HashMap<String, MediaRoute>(); protected Handler mHandler = new Handler(); private CreateRouteRequestInfo mPendingCreateRouteRequestInfo; @@ -199,6 +201,8 @@ return; } + // Don't remove the route while the session is still active. All the routes will be removed + // upon session end. sessionController().endSession(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafMediaRouteProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafMediaRouteProvider.java index bab48124..6f8eda4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafMediaRouteProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafMediaRouteProvider.java
@@ -8,6 +8,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import android.support.v7.media.MediaRouter; import com.google.android.gms.cast.framework.CastSession; @@ -36,12 +37,14 @@ private CreateRouteRequestInfo mPendingCreateRouteRequestInfo; - private ClientRecord mLastRemovedRouteRecord; + @VisibleForTesting + ClientRecord mLastRemovedRouteRecord; // The records for clients, which must match mRoutes. This is used for the saving last record // for autojoin. private final Map<String, ClientRecord> mClientIdToRecords = new HashMap<String, ClientRecord>(); - private CafMessageHandler mMessageHandler; + @VisibleForTesting + CafMessageHandler mMessageHandler; // The session controller which is always attached to the current CastSession. private final CastSessionController mSessionController; @@ -75,7 +78,6 @@ MediaRoute route = new MediaRoute(sessionController().getSink().getId(), sourceId, presentationId); addRoute(route, origin, tabId, nativeRequestId, /* wasLaunched= */ false); - mManager.onRouteCreated(route.id, route.sinkId, nativeRequestId, this, false); } // TODO(zqzhang): the clientRecord/route management is not clean and the logic seems to be @@ -90,8 +92,7 @@ ClientRecord client = getClientRecordByRouteId(routeId); if (client != null) { - MediaSink sink = MediaSink.fromSinkId( - sessionController().getSink().getId(), getAndroidMediaRouter()); + MediaSink sink = sessionController().getSink(); if (sink != null) { mMessageHandler.sendReceiverActionToClient(routeId, sink, client.clientId, "stop"); } @@ -153,10 +154,8 @@ for (ClientRecord clientRecord : mClientIdToRecords.values()) { // Should be exactly one instance of MediaRoute/ClientRecord at this moment. - MediaRoute route = mRoutes.get(clientRecord.routeId); - MediaSink sink = MediaSink.fromSinkId(route.sinkId, getAndroidMediaRouter()); - mMessageHandler.sendReceiverActionToClient( - clientRecord.routeId, sink, clientRecord.clientId, "cast"); + mMessageHandler.sendReceiverActionToClient(clientRecord.routeId, + sessionController().getSink(), clientRecord.clientId, "cast"); } mMessageHandler.onSessionStarted(); @@ -200,14 +199,15 @@ mMessageHandler = new CafMessageHandler(this, mSessionController); } - private boolean canJoinExistingSession( + @VisibleForTesting + boolean canJoinExistingSession( String presentationId, String origin, int tabId, CastMediaSource source) { if (AUTO_JOIN_PRESENTATION_ID.equals(presentationId)) { return canAutoJoin(source, origin, tabId); } if (presentationId.startsWith(PRESENTATION_ID_SESSION_ID_PREFIX)) { String sessionId = presentationId.substring(PRESENTATION_ID_SESSION_ID_PREFIX.length()); - return sessionController().getSession().getSessionId().equals(sessionId); + return sessionId != null && sessionId.equals(sessionController().getSessionId()); } for (MediaRoute route : mRoutes.values()) { if (route.presentationId.equals(presentationId)) return true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafMessageHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafMessageHandler.java index 901a31fd..e939889 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafMessageHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/caf/CafMessageHandler.java
@@ -70,8 +70,6 @@ private ArrayMap<String, Queue<Integer>> mStopRequests; private Queue<RequestRecord> mVolumeRequests; - // The reference to CastSession, only valid after calling {@link onSessionCreated}, and will be - // reset to null when calling {@link onApplicationStopped}. private final CastSessionController mSessionController; private final CafMediaRouteProvider mRouteProvider; private Handler mHandler; @@ -216,7 +214,7 @@ if (clientId == null || !mSessionController.isConnected()) return false; String sessionId = jsonMessage.getString("message"); - if (!mSessionController.getSession().getSessionId().equals(sessionId)) return false; + if (!mSessionController.getSessionId().equals(sessionId)) return false; ClientRecord currentClient = mRouteProvider.getClientIdToRecords().get(clientId); if (currentClient == null) return false; @@ -225,8 +223,8 @@ // The web sender SDK doesn't actually recognize "leave_session" response, but this is to // acknowledge the "leave_session" request. - mRouteProvider.sendMessageToClient(clientId, - buildSimpleSessionMessage("leave_session", sequenceNumber, clientId, null)); + mRouteProvider.sendMessageToClient( + clientId, buildSimpleSessionMessage("leave_session", sequenceNumber, clientId)); List<ClientRecord> leavingClients = new ArrayList<>(); @@ -253,14 +251,13 @@ } /** Builds a simple message for session-related events. */ - private String buildSimpleSessionMessage( - String type, int sequenceNumber, String clientId, String message) throws JSONException { + private String buildSimpleSessionMessage(String type, int sequenceNumber, String clientId) + throws JSONException { JSONObject jsonMessage = new JSONObject(); jsonMessage.put("type", type); jsonMessage.put("sequenceNumber", sequenceNumber); jsonMessage.put("timeoutMillis", TIMEOUT_IMMEDIATE); jsonMessage.put("clientId", clientId); - jsonMessage.put("message", message); return jsonMessage.toString(); } @@ -414,7 +411,7 @@ JSONObject jsonAppMessageWrapper = jsonMessage.getJSONObject("message"); - if (!mSessionController.getSession().getSessionId().equals( + if (!mSessionController.getSessionId().equals( jsonAppMessageWrapper.getString("sessionId"))) { return false; } @@ -522,7 +519,7 @@ void onAppMessage(String message, String namespace, RequestRecord request) { try { JSONObject jsonMessage = new JSONObject(); - jsonMessage.put("sessionId", mSessionController.getSession().getSessionId()); + jsonMessage.put("sessionId", mSessionController.getSessionId()); jsonMessage.put("namespaceName", namespace); jsonMessage.put("message", message); if (request != null) { @@ -544,13 +541,13 @@ Queue<Integer> sequenceNumbersForClient = mStopRequests.get(clientId); if (sequenceNumbersForClient == null) { sendEnclosedMessageToClient(clientId, "remove_session", - mSessionController.getSession().getSessionId(), VOID_SEQUENCE_NUMBER); + mSessionController.getSessionId(), VOID_SEQUENCE_NUMBER); continue; } for (int sequenceNumber : sequenceNumbersForClient) { sendEnclosedMessageToClient(clientId, "remove_session", - mSessionController.getSession().getSessionId(), sequenceNumber); + mSessionController.getSessionId(), sequenceNumber); } mStopRequests.remove(clientId); } @@ -688,7 +685,7 @@ } JSONObject jsonMessage = new JSONObject(); - jsonMessage.put("sessionId", mSessionController.getSession().getSessionId()); + jsonMessage.put("sessionId", mSessionController.getSessionId()); jsonMessage.put("statusText", mSessionController.getSession().getApplicationStatus()); jsonMessage.put("receiver", jsonReceiver); jsonMessage.put("namespaces", jsonNamespaces); @@ -714,12 +711,12 @@ * Modifies the received MediaStatus message to match the format expected by the client. */ private void sanitizeMediaStatusMessage(JSONObject object) throws JSONException { - object.put("sessionId", mSessionController.getSession().getSessionId()); + object.put("sessionId", mSessionController.getSessionId()); JSONArray mediaStatus = object.getJSONArray("status"); for (int i = 0; i < mediaStatus.length(); ++i) { JSONObject status = mediaStatus.getJSONObject(i); - status.put("sessionId", mSessionController.getSession().getSessionId()); + status.put("sessionId", mSessionController.getSessionId()); if (!status.has("supportedMediaCommands")) continue; JSONArray commands = new JSONArray(); @@ -776,7 +773,7 @@ return result; } - private boolean sendStringCastMessage( + boolean sendStringCastMessage( String message, String namespace, String clientId, int sequenceNumber) { if (!mSessionController.isConnected()) return false; @@ -795,7 +792,7 @@ * @param clientId The client id the message is sent from. * @param sequenceNumber The sequence number of the message. */ - private void onSendAppMessageResult(Status result, String clientId, int sequenceNumber) { + void onSendAppMessageResult(Status result, String clientId, int sequenceNumber) { if (!result.isSuccess()) { // TODO(avayvod): should actually report back to the page. // See https://crbug.com/550445.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/remoting/RemotingMediaSource.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/remoting/RemotingMediaSource.java index fead258..abefde7e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/remoting/RemotingMediaSource.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/cast/remoting/RemotingMediaSource.java
@@ -3,11 +3,16 @@ // found in the LICENSE file. package org.chromium.chrome.browser.media.router.cast.remoting; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.os.Bundle; import android.support.v7.media.MediaRouteSelector; import android.util.Base64; import com.google.android.gms.cast.CastMediaControlIntent; +import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.chrome.browser.media.router.MediaSource; @@ -24,6 +29,13 @@ // Need to be in sync with third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp. // TODO(avayvod): Find a way to share the constants somehow. private static final String SOURCE_PREFIX = "remote-playback://"; + private static final String REMOTE_PLAYBACK_APP_ID_KEY = + "org.chromium.content.browser.REMOTE_PLAYBACK_APP_ID"; + + /** + * The Cast application id. + */ + private static String sApplicationId; /** * The original source URL that the {@link MediaSource} object was created from. @@ -31,11 +43,6 @@ private final String mSourceId; /** - * The Cast application id. - */ - private final String mApplicationId; - - /** * The URL to fling to the Cast device. */ private final String mMediaUrl; @@ -61,9 +68,7 @@ return null; } - // TODO(avayvod): check the content URL and override the app id if needed. - String applicationId = CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID; - return new RemotingMediaSource(sourceId, applicationId, mediaUrl); + return new RemotingMediaSource(sourceId, mediaUrl); } /** @@ -75,16 +80,46 @@ @Override public MediaRouteSelector buildRouteSelector() { return new MediaRouteSelector.Builder() - .addControlCategory(CastMediaControlIntent.categoryForCast(mApplicationId)) + .addControlCategory(CastMediaControlIntent.categoryForCast(getApplicationId())) .build(); } /** + * Lazily loads a custom App ID from the AndroidManifest, which can be overriden + * downstream. This app ID will never change, so we can store it in a static field. + * If there is no custom app ID defined, or if there is an error retreiving the app ID, + * we fallback to the default media receiver app ID. + * + * @return a custom app ID or the default media receiver app ID. + */ + private static String applicationId() { + if (sApplicationId == null) { + String customAppId = null; + + try { + Context context = ContextUtils.getApplicationContext(); + ApplicationInfo ai = context.getPackageManager().getApplicationInfo( + context.getPackageName(), PackageManager.GET_META_DATA); + Bundle bundle = ai.metaData; + customAppId = bundle.getString(REMOTE_PLAYBACK_APP_ID_KEY); + } catch (Exception e) { + // Should never happen, implies a corrupt AndroidManifest. + } + + sApplicationId = (customAppId != null) + ? customAppId + : CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID; + } + + return sApplicationId; + } + + /** * @return the Cast application id corresponding to the source. Can be overridden downstream. */ @Override public String getApplicationId() { - return mApplicationId; + return applicationId(); } /** @@ -102,9 +137,8 @@ return mMediaUrl; } - private RemotingMediaSource(String sourceId, String applicationId, String mediaUrl) { + private RemotingMediaSource(String sourceId, String mediaUrl) { mSourceId = sourceId; - mApplicationId = applicationId; mMediaUrl = mediaUrl; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/AppModalPresenter.java b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/AppModalPresenter.java index 5d0e492..6d60e2a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/AppModalPresenter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/AppModalPresenter.java
@@ -6,11 +6,7 @@ import android.app.Dialog; import android.content.Context; -import android.view.Gravity; -import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; import org.chromium.chrome.R; @@ -25,20 +21,11 @@ @Override protected void addDialogView(View dialogView) { + dialogView.setBackgroundResource(R.drawable.popup_bg); mDialog = new Dialog(mContext, R.style.ModalDialogTheme); mDialog.setOnCancelListener(dialogInterface -> dismissCurrentDialog(DialogDismissalCause.NAVIGATE_BACK_OR_TOUCH_OUTSIDE)); - ViewGroup container = (ViewGroup) LayoutInflater.from(mContext).inflate( - R.layout.modal_dialog_container, null); - // We use the Android Dialog dim for app modal dialog, so a custom scrim is not needed. - container.findViewById(R.id.scrim).setVisibility(View.GONE); - mDialog.setContentView(container); - - FrameLayout.LayoutParams params = - new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER); - dialogView.setBackgroundResource(R.drawable.popup_bg); - container.addView(dialogView, params); + mDialog.setContentView(dialogView); mDialog.setCanceledOnTouchOutside(getModalDialog().getCancelOnTouchOutside()); mDialog.show(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogManager.java b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogManager.java index c49de31..1a4c881 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogManager.java
@@ -199,7 +199,6 @@ if (isShowing()) suspendCurrentDialog(); assert !isShowing(); - dialog.prepareBeforeShow(); mCurrentType = dialogType; mCurrentPresenter = mPresenters.get(dialogType, mDefaultPresenter); mCurrentPresenter.setModalDialog(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogProperties.java index 74d8005..55447552 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogProperties.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogProperties.java
@@ -20,6 +20,10 @@ public static final ReadableObjectPropertyKey<ModalDialogView.Controller> CONTROLLER = new ReadableObjectPropertyKey<>(); + /** The content description of the dialog for accessibility. */ + public static final ReadableObjectPropertyKey<String> CONTENT_DESCRIPTION = + new ReadableObjectPropertyKey<>(); + /** The title of the dialog. */ public static final WritableObjectPropertyKey<String> TITLE = new WritableObjectPropertyKey<>(); @@ -59,8 +63,8 @@ public static final WritableBooleanPropertyKey TITLE_SCROLLABLE = new WritableBooleanPropertyKey(); - public static final PropertyKey[] ALL_KEYS = - new PropertyKey[] {CONTROLLER, TITLE, TITLE_ICON, MESSAGE, CUSTOM_VIEW, - POSITIVE_BUTTON_TEXT, POSITIVE_BUTTON_DISABLED, NEGATIVE_BUTTON_TEXT, - NEGATIVE_BUTTON_DISABLED, CANCEL_ON_TOUCH_OUTSIDE, TITLE_SCROLLABLE}; + public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {CONTROLLER, CONTENT_DESCRIPTION, + TITLE, TITLE_ICON, MESSAGE, CUSTOM_VIEW, POSITIVE_BUTTON_TEXT, POSITIVE_BUTTON_DISABLED, + NEGATIVE_BUTTON_TEXT, NEGATIVE_BUTTON_DISABLED, CANCEL_ON_TOUCH_OUTSIDE, + TITLE_SCROLLABLE}; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogView.java b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogView.java index f75887c..553c541 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogView.java
@@ -5,12 +5,8 @@ package org.chromium.chrome.browser.modaldialog; import android.content.Context; -import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.support.annotation.IntDef; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.annotation.StringRes; import android.text.TextUtils; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; @@ -21,7 +17,7 @@ import android.widget.LinearLayout.LayoutParams; import android.widget.TextView; -import org.chromium.base.ContextUtils; +import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.widget.FadingEdgeScrollView; import org.chromium.ui.UiUtils; @@ -56,53 +52,6 @@ void onDismiss(@DialogDismissalCause int dismissalCause); } - /** - * Parameters that can be used to create a new ModalDialogView. - * Deprecated. Use {@link ModalDialogProperties} instead. - */ - public static class Params { - /** Optional: The String to show as the dialog title. */ - public String title; - - /** Optional: The String to show as descriptive text. */ - public String message; - - /** - * Optional: The customized View to show in the dialog. Note that the message and the - * custom view cannot be set together. - */ - public View customView; - - /** Optional: Resource ID of the String to show on the positive button. */ - public @StringRes int positiveButtonTextId; - - /** Optional: Resource ID of the String to show on the negative button. */ - public @StringRes int negativeButtonTextId; - - /** - * Optional: The String to show on the positive button. Note that String - * must be null if positiveButtonTextId is not zero. - */ - public String positiveButtonText; - - /** - * Optional: The String to show on the negative button. Note that String - * must be null if negativeButtonTextId is not zero - */ - public String negativeButtonText; - - /** - * Optional: If true the dialog gets cancelled when the user touches outside of the dialog. - */ - public boolean cancelOnTouchOutside; - - /** - * Optional: If true, the dialog title is scrollable with the message. Note that the - * {@link #customView} will have height WRAP_CONTENT if this is set to true. - */ - public boolean titleScrollable; - } - @IntDef({ButtonType.POSITIVE, ButtonType.NEGATIVE}) @Retention(RetentionPolicy.SOURCE) public @interface ButtonType { @@ -111,7 +60,6 @@ } private Controller mController; - private @Nullable Params mParams; private final View mDialogView; @@ -124,21 +72,13 @@ private View mButtonBar; private Button mPositiveButton; private Button mNegativeButton; + private String mContentDescription; private boolean mTitleScrollable; // TODO(huayinz): Remove this temporary variable once ModalDialogManager takes a model. private boolean mCancelOnTouchOutside; /** - * @return The {@link Context} with the modal dialog theme set. - * Deprecated. - */ - public static Context getContext() { - return new ContextThemeWrapper( - ContextUtils.getApplicationContext(), R.style.ModalDialogTheme); - } - - /** * Temporary constructor before ModalDialogManager takes a model. * @param context The {@link Context} from which the dialog view should be inflated. * TODO(huayinz): Change this once ModalDialogManager takes a model. @@ -150,18 +90,6 @@ initialize(); } - /** - * Constructor for initializing controller and views. - * Deprecated. Use {@link ModalDialogView(Context)} instead. - * @param controller The controller for this dialog. - */ - public ModalDialogView(@NonNull Controller controller, @NonNull Params params) { - mController = controller; - mParams = params; - mDialogView = LayoutInflater.from(getContext()).inflate(R.layout.modal_dialog_view, null); - initialize(); - } - private void initialize() { mScrollView = mDialogView.findViewById(R.id.modal_dialog_scroll_view); mTitleContainer = mDialogView.findViewById(R.id.title_container); @@ -177,6 +105,15 @@ mNegativeButton.setOnClickListener(this); updateContentVisibility(); updateButtonVisibility(); + + // If the scroll view can not be scrolled, make the scroll view not focusable so that the + // focusing behavior for hardware keyboard is less confusing. + // See https://codereview.chromium.org/2939883002. + mScrollView.addOnLayoutChangeListener( + (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { + boolean isScrollable = v.canScrollVertically(-1) || v.canScrollVertically(1); + v.setFocusable(isScrollable); + }); } @Override @@ -189,36 +126,6 @@ } /** - * Prepare the contents before showing the dialog. - * Deprecated. - */ - protected void prepareBeforeShow() { - if (mParams == null) return; - - setTitle(mParams.title); - setTitleScrollable(mParams.titleScrollable); - setMessage(mParams.message); - setCustomView(mParams.customView); - setCancelOnTouchOutside(mParams.cancelOnTouchOutside); - - Resources resources = mDialogView.getResources(); - assert(mParams.positiveButtonTextId == 0 || mParams.positiveButtonText == null); - if (mParams.positiveButtonTextId != 0) { - setButtonText(ButtonType.POSITIVE, resources.getString(mParams.positiveButtonTextId)); - } else if (mParams.positiveButtonText != null) { - setButtonText(ButtonType.POSITIVE, mParams.positiveButtonText); - } - - assert(mParams.negativeButtonTextId == 0 || mParams.negativeButtonText == null); - if (mParams.negativeButtonTextId != 0) { - setButtonText(ButtonType.NEGATIVE, resources.getString(mParams.negativeButtonTextId)); - mNegativeButton.setOnClickListener(this); - } else if (mParams.negativeButtonText != null) { - setButtonText(ButtonType.NEGATIVE, mParams.negativeButtonText); - } - } - - /** * @return The content view of this dialog. */ public View getView() { @@ -226,20 +133,6 @@ } /** - * @return The button that was added to the dialog using {@link Params}. - * @param button indicates which button should be returned. - */ - public Button getButton(@ButtonType int button) { - if (button == ButtonType.POSITIVE) { - return mPositiveButton; - } else if (button == ButtonType.NEGATIVE) { - return mNegativeButton; - } - assert false; - return null; - } - - /** * @return The controller that controls the actions on the dialogs. */ public Controller getController() { @@ -254,10 +147,17 @@ } /** + * @param contentDescription The content description of the dialog view for accessibility. + */ + void setContentDescription(String contentDescription) { + mContentDescription = contentDescription; + } + + /** * @return The content description of the dialog view. */ public CharSequence getContentDescription() { - return mTitleView.getText(); + return mContentDescription != null ? mContentDescription : mTitleView.getText(); } /** @param title The title of the dialog. */ @@ -328,6 +228,21 @@ } /** + * @param buttonType Indicates which button should be returned. + */ + private Button getButton(@ButtonType int buttonType) { + switch (buttonType) { + case ButtonType.POSITIVE: + return mPositiveButton; + case ButtonType.NEGATIVE: + return mNegativeButton; + default: + assert false; + return null; + } + } + + /** * Sets button text for the specified button. If {@code buttonText} is empty or null, the * specified button will not be visible. * @param buttonType The {@link ButtonType} of the button. @@ -384,4 +299,9 @@ mNegativeButton.setVisibility(negativeButtonVisible ? View.VISIBLE : View.GONE); mButtonBar.setVisibility(buttonBarVisible ? View.VISIBLE : View.GONE); } + + @VisibleForTesting + public Button getButtonForTesting(@ButtonType int buttonType) { + return getButton(buttonType); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewBinder.java index 57ce2d2..ef2446c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/ModalDialogViewBinder.java
@@ -39,6 +39,8 @@ !model.get(ModalDialogProperties.NEGATIVE_BUTTON_DISABLED)); } else if (ModalDialogProperties.CANCEL_ON_TOUCH_OUTSIDE == propertyKey) { view.setCancelOnTouchOutside(model.get(ModalDialogProperties.CANCEL_ON_TOUCH_OUTSIDE)); + } else if (ModalDialogProperties.CONTENT_DESCRIPTION == propertyKey) { + view.setContentDescription(model.get(ModalDialogProperties.CONTENT_DESCRIPTION)); } else if (ModalDialogProperties.TITLE_SCROLLABLE == propertyKey) { view.setTitleScrollable(model.get(ModalDialogProperties.TITLE_SCROLLABLE)); } else if (ModalDialogProperties.CONTROLLER == propertyKey) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/PropertyModel.java b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/PropertyModel.java index e1a6f22..18a94f9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/PropertyModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/PropertyModel.java
@@ -55,7 +55,22 @@ * @param <T> The type of the Object being tracked by the key. */ public final static class WritableObjectPropertyKey<T> - extends ReadableObjectPropertyKey<T> implements PropertyKey {} + extends ReadableObjectPropertyKey<T> implements PropertyKey { + private final boolean mSkipEquality; + + /** Default constructor for a writable object property. */ + public WritableObjectPropertyKey() { + this(false); + } + + /** + * Constructs a new writable object property. + * @param skipEquality Whether the equality check should be bypassed for this key. + */ + public WritableObjectPropertyKey(boolean skipEquality) { + mSkipEquality = skipEquality; + } + } private final Map<PropertyKey, ValueContainer> mData; @@ -177,7 +192,7 @@ if (container == null) { container = new ObjectContainer<T>(); mData.put(key, container); - } else if (ObjectsCompat.equals(container.value, value)) { + } else if (!key.mSkipEquality && ObjectsCompat.equals(container.value, value)) { return; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AnswerTextBuilder.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AnswerTextBuilder.java index cc5702c..47d20913 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AnswerTextBuilder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AnswerTextBuilder.java
@@ -18,6 +18,8 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ContextUtils; import org.chromium.chrome.R; +import org.chromium.components.omnibox.AnswerTextType; +import org.chromium.components.omnibox.SuggestionAnswer; import java.util.List; @@ -28,28 +30,6 @@ class AnswerTextBuilder { private static final String TAG = "AnswerTextBuilder"; - // Types, sizes and colors specified at http://goto.google.com/ais_api. - // Deprecated: ANSWERS_ANSWER_TEXT_TYPE = 1; - // Deprecated: ANSWERS_HEADLINE_TEXT_TYPE = 2; - private static final int ANSWERS_TOP_ALIGNED_TEXT_TYPE = 3; - // Deprecated: ANSWERS_DESCRIPTION_TEXT_TYPE = 4; - private static final int ANSWERS_DESCRIPTION_TEXT_NEGATIVE_TYPE = 5; - private static final int ANSWERS_DESCRIPTION_TEXT_POSITIVE_TYPE = 6; - // Deprecated: ANSWERS_MORE_INFO_TEXT_TYPE = 7; - private static final int ANSWERS_SUGGESTION_TEXT_TYPE = 8; - // Deprecated: ANSWERS_SUGGESTION_TEXT_POSITIVE_TYPE = 9; - // Deprecated: ANSWERS_SUGGESTION_TEXT_NEGATIVE_TYPE = 10; - // Deprecated: ANSWERS_SUGGESTION_LINK_COLOR_TYPE = 11; - // Deprecated: ANSWERS_STATUS_TEXT_TYPE = 12; - private static final int ANSWERS_PERSONALIZED_SUGGESTION_TEXT_TYPE = 13; - // Deprecated: ANSWERS_IMMERSIVE_DESCRIPTION_TEXT = 14; - // Deprecated: ANSWERS_DATE_TEXT = 15; - // Deprecated: ANSWERS_PREVIEW_TEXT = 16; - private static final int ANSWERS_ANSWER_TEXT_MEDIUM_TYPE = 17; - private static final int ANSWERS_ANSWER_TEXT_LARGE_TYPE = 18; - private static final int ANSWERS_SECONDARY_TEXT_SMALL_TYPE = 19; - private static final int ANSWERS_SECONDARY_TEXT_MEDIUM_TYPE = 20; - private static final int ANSWERS_TOP_ALIGNED_TEXT_SIZE_SP = 12; private static final int ANSWERS_DESCRIPTION_TEXT_NEGATIVE_SIZE_SP = 16; private static final int ANSWERS_DESCRIPTION_TEXT_POSITIVE_SIZE_SP = 16; @@ -156,7 +136,7 @@ ForegroundColorSpan colorSpan = new ForegroundColorSpan(getAnswerTextColor(type)); builder.setSpan(colorSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - if (type == ANSWERS_TOP_ALIGNED_TEXT_TYPE) { + if (type == AnswerTextType.TOP_ALIGNED) { TopAlignedSpan topAlignedSpan = new TopAlignedSpan(ANSWERS_TOP_ALIGNED_TEXT_SIZE_SP, maxTextHeightSp, density); builder.setSpan(topAlignedSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); @@ -168,25 +148,25 @@ * * @param type The answer type as specified at http://goto.google.com/ais_api. */ - private static int getAnswerTextSizeSp(int type) { + private static int getAnswerTextSizeSp(@AnswerTextType int type) { switch (type) { - case ANSWERS_TOP_ALIGNED_TEXT_TYPE: + case AnswerTextType.TOP_ALIGNED: return ANSWERS_TOP_ALIGNED_TEXT_SIZE_SP; - case ANSWERS_DESCRIPTION_TEXT_NEGATIVE_TYPE: + case AnswerTextType.DESCRIPTION_NEGATIVE: return ANSWERS_DESCRIPTION_TEXT_NEGATIVE_SIZE_SP; - case ANSWERS_DESCRIPTION_TEXT_POSITIVE_TYPE: + case AnswerTextType.DESCRIPTION_POSITIVE: return ANSWERS_DESCRIPTION_TEXT_POSITIVE_SIZE_SP; - case ANSWERS_SUGGESTION_TEXT_TYPE: + case AnswerTextType.SUGGESTION: return ANSWERS_SUGGESTION_TEXT_SIZE_SP; - case ANSWERS_PERSONALIZED_SUGGESTION_TEXT_TYPE: + case AnswerTextType.PERSONALIZED_SUGGESTION: return ANSWERS_PERSONALIZED_SUGGESTION_TEXT_SIZE_SP; - case ANSWERS_ANSWER_TEXT_MEDIUM_TYPE: + case AnswerTextType.ANSWER_TEXT_MEDIUM: return ANSWERS_ANSWER_TEXT_MEDIUM_SIZE_SP; - case ANSWERS_ANSWER_TEXT_LARGE_TYPE: + case AnswerTextType.ANSWER_TEXT_LARGE: return ANSWERS_ANSWER_TEXT_LARGE_SIZE_SP; - case ANSWERS_SECONDARY_TEXT_SMALL_TYPE: + case AnswerTextType.SUGGESTION_SECONDARY_TEXT_SMALL: return ANSWERS_SECONDARY_TEXT_SMALL_SIZE_SP; - case ANSWERS_SECONDARY_TEXT_MEDIUM_TYPE: + case AnswerTextType.SUGGESTION_SECONDARY_TEXT_MEDIUM: return ANSWERS_SECONDARY_TEXT_MEDIUM_SIZE_SP; default: Log.w(TAG, "Unknown answer type: " + type); @@ -199,28 +179,28 @@ * * @param type The answer type as specified at http://goto.google.com/ais_api. */ - private static int getAnswerTextColor(int type) { + private static int getAnswerTextColor(@AnswerTextType int type) { Resources resources = ContextUtils.getApplicationContext().getResources(); switch (type) { - case ANSWERS_DESCRIPTION_TEXT_NEGATIVE_TYPE: + case AnswerTextType.DESCRIPTION_NEGATIVE: return ApiCompatibilityUtils.getColor( resources, R.color.answers_description_text_negative); - case ANSWERS_DESCRIPTION_TEXT_POSITIVE_TYPE: + case AnswerTextType.DESCRIPTION_POSITIVE: return ApiCompatibilityUtils.getColor( resources, R.color.answers_description_text_positive); - case ANSWERS_SUGGESTION_TEXT_TYPE: + case AnswerTextType.SUGGESTION: return ApiCompatibilityUtils.getColor(resources, R.color.url_emphasis_default_text); - case ANSWERS_PERSONALIZED_SUGGESTION_TEXT_TYPE: + case AnswerTextType.PERSONALIZED_SUGGESTION: return ApiCompatibilityUtils.getColor(resources, R.color.url_emphasis_default_text); - case ANSWERS_TOP_ALIGNED_TEXT_TYPE: - case ANSWERS_ANSWER_TEXT_MEDIUM_TYPE: - case ANSWERS_ANSWER_TEXT_LARGE_TYPE: - case ANSWERS_SECONDARY_TEXT_SMALL_TYPE: - case ANSWERS_SECONDARY_TEXT_MEDIUM_TYPE: + case AnswerTextType.TOP_ALIGNED: + case AnswerTextType.ANSWER_TEXT_MEDIUM: + case AnswerTextType.ANSWER_TEXT_LARGE: + case AnswerTextType.SUGGESTION_SECONDARY_TEXT_SMALL: + case AnswerTextType.SUGGESTION_SECONDARY_TEXT_MEDIUM: return ApiCompatibilityUtils.getColor(resources, R.color.answers_answer_text); default:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java index d9e1ae22..b393ed48 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java
@@ -16,6 +16,7 @@ import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType; import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion.MatchClassification; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.components.omnibox.SuggestionAnswer; import org.chromium.content_public.browser.WebContents; import java.util.ArrayList; @@ -293,8 +294,8 @@ int relevance, int transition, String contents, int[] contentClassificationOffsets, int[] contentClassificationStyles, String description, int[] descriptionClassificationOffsets, int[] descriptionClassificationStyles, - String answerContents, String answerType, String fillIntoEdit, String url, - boolean isStarred, boolean isDeletable) { + SuggestionAnswer answer, String fillIntoEdit, String url, boolean isStarred, + boolean isDeletable) { assert contentClassificationOffsets.length == contentClassificationStyles.length; List<MatchClassification> contentClassifications = new ArrayList<>(); for (int i = 0; i < contentClassificationOffsets.length; i++) { @@ -310,8 +311,8 @@ } return new OmniboxSuggestion(nativeType, isSearchType, relevance, transition, contents, - contentClassifications, description, descriptionClassifications, answerContents, - answerType, fillIntoEdit, url, isStarred, isDeletable); + contentClassifications, description, descriptionClassifications, answer, + fillIntoEdit, url, isStarred, isDeletable); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java index 20fc3ce..795990a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -6,6 +6,7 @@ import android.app.Activity; import android.content.Context; +import android.content.res.Resources; import android.graphics.Bitmap; import android.os.Handler; import android.os.SystemClock; @@ -28,8 +29,11 @@ import org.chromium.chrome.browser.init.AsyncInitializationActivity; import org.chromium.chrome.browser.modaldialog.DialogDismissalCause; import org.chromium.chrome.browser.modaldialog.ModalDialogManager; +import org.chromium.chrome.browser.modaldialog.ModalDialogProperties; import org.chromium.chrome.browser.modaldialog.ModalDialogView; +import org.chromium.chrome.browser.modaldialog.ModalDialogViewBinder; import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; import org.chromium.chrome.browser.omnibox.LocationBarVoiceRecognitionHandler; import org.chromium.chrome.browser.omnibox.MatchClassificationStyle; import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType; @@ -42,6 +46,7 @@ import org.chromium.chrome.browser.omnibox.suggestions.SuggestionViewProperties.SuggestionTextContainer; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.toolbar.ToolbarDataProvider; +import org.chromium.components.omnibox.SuggestionAnswer; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.DeviceFormFactor; import org.chromium.ui.base.PageTransition; @@ -679,12 +684,6 @@ return; } - ModalDialogView.Params dialogParams = new ModalDialogView.Params(); - dialogParams.title = suggestion.getDisplayText(); - dialogParams.message = mContext.getString(R.string.omnibox_confirm_delete); - dialogParams.positiveButtonTextId = R.string.ok; - dialogParams.negativeButtonTextId = R.string.cancel; - ModalDialogView.Controller dialogController = new ModalDialogView.Controller() { @Override public void onDismiss(int dismissalCause) { @@ -705,7 +704,23 @@ } }; - mSuggestionDeleteDialog = new ModalDialogView(dialogController, dialogParams); + Resources resources = mContext.getResources(); + PropertyModel model = + new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) + .with(ModalDialogProperties.CONTROLLER, dialogController) + .with(ModalDialogProperties.TITLE, suggestion.getDisplayText()) + .with(ModalDialogProperties.MESSAGE, resources, + R.string.omnibox_confirm_delete) + .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, R.string.ok) + .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, + R.string.cancel) + .with(ModalDialogProperties.CANCEL_ON_TOUCH_OUTSIDE, true) + .build(); + + mSuggestionDeleteDialog = new ModalDialogView(mContext); + PropertyModelChangeProcessor.create( + model, mSuggestionDeleteDialog, new ModalDialogViewBinder()); + // Prevent updates to the shown omnibox suggestions list while the dialog is open. stopAutocomplete(false); manager.showDialog(mSuggestionDeleteDialog, ModalDialogManager.ModalDialogType.APP);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestion.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestion.java index 63379b4..9b8d1655 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestion.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestion.java
@@ -6,11 +6,13 @@ import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; +import android.support.v4.util.ObjectsCompat; import android.text.TextUtils; import org.chromium.base.ContextUtils; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.omnibox.MatchClassificationStyle; +import org.chromium.components.omnibox.SuggestionAnswer; import java.util.ArrayList; import java.util.List; @@ -27,7 +29,8 @@ private static final String KEY_PREFIX_ZERO_SUGGEST_NATIVE_TYPE = "zero_suggest_native_type"; private static final String KEY_PREFIX_ZERO_SUGGEST_IS_SEARCH_TYPE = "zero_suggest_is_search"; private static final String KEY_PREFIX_ZERO_SUGGEST_ANSWER_TEXT = "zero_suggest_answer_text"; - private static final String KEY_PREFIX_ZERO_SUGGEST_ANSWER_TYPE = "zero_suggest_answer_type"; + // Deprecated: + // private static final String KEY_PREFIX_ZERO_SUGGEST_ANSWER_TYPE = "zero_suggest_answer_type"; private static final String KEY_PREFIX_ZERO_SUGGEST_IS_DELETABLE = "zero_suggest_is_deletable"; private static final String KEY_PREFIX_ZERO_SUGGEST_IS_STARRED = "zero_suggest_is_starred"; @@ -60,8 +63,6 @@ private final List<MatchClassification> mDisplayTextClassifications; private final String mDescription; private final List<MatchClassification> mDescriptionClassifications; - private final String mAnswerContents; - private final String mAnswerType; private final SuggestionAnswer mAnswer; private final String mFillIntoEdit; private final String mUrl; @@ -73,8 +74,8 @@ public OmniboxSuggestion(int nativeType, boolean isSearchType, int relevance, int transition, String displayText, List<MatchClassification> displayTextClassifications, String description, List<MatchClassification> descriptionClassifications, - String answerContents, String answerType, String fillIntoEdit, String url, - boolean isStarred, boolean isDeletable) { + SuggestionAnswer answer, String fillIntoEdit, String url, boolean isStarred, + boolean isDeletable) { mType = nativeType; mIsSearchType = isSearchType; mRelevance = relevance; @@ -83,20 +84,11 @@ mDisplayTextClassifications = displayTextClassifications; mDescription = description; mDescriptionClassifications = descriptionClassifications; - mAnswerContents = answerContents; - mAnswerType = answerType; + mAnswer = answer; mFillIntoEdit = TextUtils.isEmpty(fillIntoEdit) ? displayText : fillIntoEdit; mUrl = url; mIsStarred = isStarred; mIsDeletable = isDeletable; - - if (!TextUtils.isEmpty(mAnswerContents)) { - // If any errors are encountered parsing the answer contents, this will return null and - // hasAnswer will return false, just as if there were no answer contents at all. - mAnswer = SuggestionAnswer.parseAnswerContents(mAnswerContents); - } else { - mAnswer = null; - } } public int getType() { @@ -123,14 +115,6 @@ return mDescriptionClassifications; } - public String getAnswerContents() { - return mAnswerContents; - } - - public String getAnswerType() { - return mAnswerType; - } - public SuggestionAnswer getAnswer() { return mAnswer; } @@ -181,9 +165,7 @@ public int hashCode() { int hash = 37 * mType + mDisplayText.hashCode() + mFillIntoEdit.hashCode() + (mIsStarred ? 1 : 0) + (mIsDeletable ? 1 : 0); - if (mAnswerContents != null) { - hash = hash + mAnswerContents.hashCode(); - } + if (mAnswer != null) hash = hash + mAnswer.hashCode(); return hash; } @@ -194,13 +176,10 @@ } OmniboxSuggestion suggestion = (OmniboxSuggestion) obj; - - boolean answersAreEqual = (mAnswerContents == null && suggestion.mAnswerContents == null) - || (mAnswerContents != null && suggestion.mAnswerContents != null - && mAnswerContents.equals(suggestion.mAnswerContents)); return mType == suggestion.mType && mFillIntoEdit.equals(suggestion.mFillIntoEdit) - && mDisplayText.equals(suggestion.mDisplayText) && answersAreEqual - && mIsStarred == suggestion.mIsStarred && mIsDeletable == suggestion.mIsDeletable; + && mDisplayText.equals(suggestion.mDisplayText) + && mIsStarred == suggestion.mIsStarred && mIsDeletable == suggestion.mIsDeletable + && ObjectsCompat.equals(mAnswer, suggestion.mAnswer); } /** @@ -213,13 +192,12 @@ editor.putInt(KEY_ZERO_SUGGEST_LIST_SIZE, suggestions.size()).apply(); for (int i = 0; i < suggestions.size(); i++) { OmniboxSuggestion suggestion = suggestions.get(i); + if (suggestion.mAnswer != null) continue; + editor.putString(KEY_PREFIX_ZERO_SUGGEST_URL + i, suggestion.getUrl()) .putString( KEY_PREFIX_ZERO_SUGGEST_DISPLAY_TEST + i, suggestion.getDisplayText()) .putString(KEY_PREFIX_ZERO_SUGGEST_DESCRIPTION + i, suggestion.getDescription()) - .putString( - KEY_PREFIX_ZERO_SUGGEST_ANSWER_TEXT + i, suggestion.getAnswerContents()) - .putString(KEY_PREFIX_ZERO_SUGGEST_ANSWER_TYPE + i, suggestion.getAnswerType()) .putInt(KEY_PREFIX_ZERO_SUGGEST_NATIVE_TYPE + i, suggestion.getType()) .putBoolean(KEY_PREFIX_ZERO_SUGGEST_IS_SEARCH_TYPE + i, !suggestion.isUrlSuggestion()) @@ -241,11 +219,16 @@ List<MatchClassification> classifications = new ArrayList<>(); classifications.add(new MatchClassification(0, MatchClassificationStyle.NONE)); for (int i = 0; i < size; i++) { + // TODO(tedchoc): Answers in suggest were previously cached, but that could lead to + // stale or misleading answers for cases like weather. Ignore any + // previously cached answers for several releases while any previous + // results are cycled through. + String answerText = prefs.getString(KEY_PREFIX_ZERO_SUGGEST_ANSWER_TEXT + i, ""); + if (!TextUtils.isEmpty(answerText)) continue; + String url = prefs.getString(KEY_PREFIX_ZERO_SUGGEST_URL + i, ""); String displayText = prefs.getString(KEY_PREFIX_ZERO_SUGGEST_DISPLAY_TEST + i, ""); String description = prefs.getString(KEY_PREFIX_ZERO_SUGGEST_DESCRIPTION + i, ""); - String answerText = prefs.getString(KEY_PREFIX_ZERO_SUGGEST_ANSWER_TEXT + i, ""); - String answerType = prefs.getString(KEY_PREFIX_ZERO_SUGGEST_ANSWER_TYPE + i, ""); int nativeType = prefs.getInt(KEY_PREFIX_ZERO_SUGGEST_NATIVE_TYPE + i, -1); boolean isSearchType = prefs.getBoolean(KEY_PREFIX_ZERO_SUGGEST_IS_SEARCH_TYPE, true); @@ -253,8 +236,8 @@ boolean isDeletable = prefs.getBoolean(KEY_PREFIX_ZERO_SUGGEST_IS_DELETABLE + i, false); OmniboxSuggestion suggestion = new OmniboxSuggestion(nativeType, !isSearchType, 0, - 0, displayText, classifications, description, classifications, answerText, - answerType, "", url, isStarred, isDeletable); + 0, displayText, classifications, description, classifications, null, "", + url, isStarred, isDeletable); suggestions.add(suggestion); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionAnswer.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionAnswer.java deleted file mode 100644 index 8ba38ee..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionAnswer.java +++ /dev/null
@@ -1,208 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.omnibox.suggestions; - -import android.util.Log; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.List; - -/** - * Structured representation of the JSON payload of a suggestion with an answer. An answer has - * exactly two image lines, so called because they are a combination of text and an optional - * image. Each image line has 0 or more text fields, each of which is required to contain a string - * and an integer type. The text fields are contained in a list and two optional named properties, - * referred to as "additional text" and "status text". The image, if present, contains a single - * string, which may be a URL or base64-encoded image data. - * - * When represented in the UI, these elements should be styled and laid out according to the - * specification at http://goto.google.com/ais_api. - */ -public class SuggestionAnswer { - private static final String TAG = "SuggestionAnswer"; - - private ImageLine mFirstLine; - private ImageLine mSecondLine; - - private static final String ANSWERS_JSON_LINE = "l"; - private static final String ANSWERS_JSON_IMAGE_LINE = "il"; - private static final String ANSWERS_JSON_TEXT = "t"; - private static final String ANSWERS_JSON_ADDITIONAL_TEXT = "at"; - private static final String ANSWERS_JSON_STATUS_TEXT = "st"; - private static final String ANSWERS_JSON_TEXT_TYPE = "tt"; - private static final String ANSWERS_JSON_IMAGE = "i"; - private static final String ANSWERS_JSON_IMAGE_DATA = "d"; - private static final String ANSWERS_JSON_NUMBER_OF_LINES = "ln"; - - private SuggestionAnswer() {} - - /** - * Parses the JSON representation of an answer and constructs a SuggestionAnswer from the - * contents. - * - * @param answerContents The JSON representation of an answer. - * @return A SuggestionAnswer with the answer contents or null if the contents are malformed or - * missing required elements. - */ - public static SuggestionAnswer parseAnswerContents(String answerContents) { - SuggestionAnswer answer = new SuggestionAnswer(); - - try { - JSONObject jsonAnswer = new JSONObject(answerContents); - JSONArray jsonLines = jsonAnswer.getJSONArray(ANSWERS_JSON_LINE); - - if (jsonLines.length() != 2) { - Log.e(TAG, "Answer JSON doesn't contain exactly two lines: " + jsonAnswer); - return null; - } - - answer.mFirstLine = new SuggestionAnswer.ImageLine( - jsonLines.getJSONObject(0).getJSONObject(ANSWERS_JSON_IMAGE_LINE)); - answer.mSecondLine = new SuggestionAnswer.ImageLine( - jsonLines.getJSONObject(1).getJSONObject(ANSWERS_JSON_IMAGE_LINE)); - } catch (JSONException e) { - Log.e(TAG, "Problem parsing answer JSON: " + e.getMessage()); - return null; - } - - return answer; - } - - /** - * Returns the first of the two required image lines. - */ - public ImageLine getFirstLine() { - return mFirstLine; - } - - /** - * Returns the second of the two required image lines. - */ - public ImageLine getSecondLine() { - return mSecondLine; - } - - /** - * Represents a single line of an answer, containing any number of typed text fields and an - * optional image. - */ - public static class ImageLine { - private final List<TextField> mTextFields; - private final TextField mAdditionalText; - private final TextField mStatusText; - private final String mImage; - - ImageLine(JSONObject jsonLine) throws JSONException { - mTextFields = new ArrayList<TextField>(); - - JSONArray textValues = jsonLine.getJSONArray(ANSWERS_JSON_TEXT); - for (int i = 0; i < textValues.length(); i++) { - mTextFields.add(new TextField(textValues.getJSONObject(i))); - } - - mAdditionalText = jsonLine.has(ANSWERS_JSON_ADDITIONAL_TEXT) - ? new TextField(jsonLine.getJSONObject(ANSWERS_JSON_ADDITIONAL_TEXT)) - : null; - - mStatusText = jsonLine.has(ANSWERS_JSON_STATUS_TEXT) - ? new TextField(jsonLine.getJSONObject(ANSWERS_JSON_STATUS_TEXT)) - : null; - - String jsonImageData = jsonLine.has(ANSWERS_JSON_IMAGE) - ? jsonLine.getJSONObject(ANSWERS_JSON_IMAGE).getString(ANSWERS_JSON_IMAGE_DATA) - : null; - if (jsonImageData != null) { - jsonImageData = "https:" + jsonImageData.replace("\\/", "/"); - } - mImage = jsonImageData; - } - - /** - * Return an unnamed list of text fields. These represent the main content of the line. - */ - public List<TextField> getTextFields() { - return mTextFields; - } - - /** - * Returns true if the line contains an "additional text" field. - */ - public boolean hasAdditionalText() { - return mAdditionalText != null; - } - - /** - * Return the "additional text" field. - */ - public TextField getAdditionalText() { - return mAdditionalText; - } - - /** - * Returns true if the line contains an "status text" field. - */ - public boolean hasStatusText() { - return mStatusText != null; - } - - /** - * Return the "status text" field. - */ - public TextField getStatusText() { - return mStatusText; - } - - /** - * Returns true if the line contains an image. - */ - public boolean hasImage() { - return mImage != null; - } - - /** - * Return the optional image (URL or base64-encoded image data). - */ - public String getImage() { - return mImage; - } - } - - /** - * Represents one text field of an answer, containing a integer type and a string. - */ - public static class TextField { - private final int mType; - private final String mText; - private final int mNumLines; - - TextField(JSONObject jsonTextField) throws JSONException { - mType = jsonTextField.getInt(ANSWERS_JSON_TEXT_TYPE); - mText = jsonTextField.getString(ANSWERS_JSON_TEXT); - mNumLines = jsonTextField.has(ANSWERS_JSON_NUMBER_OF_LINES) - ? jsonTextField.getInt(ANSWERS_JSON_NUMBER_OF_LINES) - : -1; - } - - public int getType() { - return mType; - } - - public String getText() { - return mText; - } - - public boolean hasNumLines() { - return mNumLines != -1; - } - - public int getNumLines() { - return mNumLines; - } - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java index cb611e1..74d6f99 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java
@@ -25,7 +25,7 @@ /** The list of models controlling the state of the suggestion items. */ public static final WritableObjectPropertyKey<List<PropertyModel>> SUGGESTION_MODELS = - new WritableObjectPropertyKey<>(); + new WritableObjectPropertyKey<>(true); /** Whether the suggestion list should have a dark background. */ public static final WritableBooleanPropertyKey USE_DARK_BACKGROUND =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/VoiceSuggestionProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/VoiceSuggestionProvider.java index dd09bfc..5785a3c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/VoiceSuggestionProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/VoiceSuggestionProvider.java
@@ -121,8 +121,8 @@ List<MatchClassification> classifications = new ArrayList<>(); classifications.add(new MatchClassification(0, MatchClassificationStyle.NONE)); suggestions.add(new OmniboxSuggestion(OmniboxSuggestionType.VOICE_SUGGEST, true, 0, 1, - result.getMatch(), classifications, null, classifications, null, null, null, - voiceUrl, false, false)); + result.getMatch(), classifications, null, classifications, null, null, voiceUrl, + false, false)); } private boolean doesVoiceResultHaveMatch(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopup.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopup.java index e3722a1..7c0edab 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopup.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopup.java
@@ -26,8 +26,12 @@ import org.chromium.chrome.browser.ResourceId; import org.chromium.chrome.browser.modaldialog.DialogDismissalCause; import org.chromium.chrome.browser.modaldialog.ModalDialogManager; +import org.chromium.chrome.browser.modaldialog.ModalDialogProperties; import org.chromium.chrome.browser.modaldialog.ModalDialogView; import org.chromium.chrome.browser.modaldialog.ModalDialogView.ButtonType; +import org.chromium.chrome.browser.modaldialog.ModalDialogViewBinder; +import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.vr.UiUnsupportedMode; import org.chromium.chrome.browser.vr.VrModuleProvider; @@ -191,10 +195,14 @@ ScrollView scrollView = new ScrollView(mContext); scrollView.addView(mContainer); - ModalDialogView.Params params = new ModalDialogView.Params(); - params.customView = scrollView; - params.cancelOnTouchOutside = true; - mDialog = new ModalDialogView(this, params); + PropertyModel model = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) + .with(ModalDialogProperties.CONTROLLER, this) + .with(ModalDialogProperties.CUSTOM_VIEW, scrollView) + .with(ModalDialogProperties.CANCEL_ON_TOUCH_OUTSIDE, true) + .build(); + + mDialog = new ModalDialogView(mContext); + PropertyModelChangeProcessor.create(model, mDialog, new ModalDialogViewBinder()); mModalDialogManager.showDialog(mDialog, ModalDialogManager.ModalDialogType.APP, true); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoDialog.java index 3c4b8564..56a8429 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoDialog.java
@@ -23,7 +23,11 @@ import org.chromium.chrome.browser.modaldialog.DialogDismissalCause; import org.chromium.chrome.browser.modaldialog.ModalDialogManager; +import org.chromium.chrome.browser.modaldialog.ModalDialogProperties; import org.chromium.chrome.browser.modaldialog.ModalDialogView; +import org.chromium.chrome.browser.modaldialog.ModalDialogViewBinder; +import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; import org.chromium.ui.interpolators.BakedBezierInterpolator; /** @@ -173,10 +177,15 @@ } private ModalDialogView createModalDialog(View container) { - ModalDialogView.Params params = new ModalDialogView.Params(); - params.customView = container; - params.cancelOnTouchOutside = true; - return new ModalDialogView(mController, params); + PropertyModel model = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) + .with(ModalDialogProperties.CONTROLLER, mController) + .with(ModalDialogProperties.CUSTOM_VIEW, container) + .with(ModalDialogProperties.CANCEL_ON_TOUCH_OUTSIDE, true) + .build(); + + ModalDialogView dialogView = new ModalDialogView(container.getContext()); + PropertyModelChangeProcessor.create(model, dialogView, new ModalDialogViewBinder()); + return dialogView; } private ViewGroup createSheetContainer(Context context, View tabView) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogViewHolder.java index 19fd20f..f1c00e4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogViewHolder.java
@@ -5,12 +5,18 @@ package org.chromium.chrome.browser.password_manager; import android.content.Context; +import android.content.res.Resources; import android.support.annotation.Nullable; import android.view.LayoutInflater; +import android.view.View; import android.widget.TextView; import org.chromium.chrome.R; +import org.chromium.chrome.browser.modaldialog.ModalDialogProperties; import org.chromium.chrome.browser.modaldialog.ModalDialogView; +import org.chromium.chrome.browser.modaldialog.ModalDialogViewBinder; +import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; /** Class holding a {@link ModalDialogView} that is lazily created after all the data is made * available. @@ -42,19 +48,28 @@ } public void initializeView() { - ModalDialogView.Params params = new ModalDialogView.Params(); - params.title = mContext.getString(R.string.password_generation_dialog_title); - params.positiveButtonTextId = R.string.password_generation_dialog_use_password_button; - params.negativeButtonTextId = R.string.password_generation_dialog_cancel_button; - params.customView = + View customView = LayoutInflater.from(mContext).inflate(R.layout.password_generation_dialog, null); - mGeneratedPasswordTextView = params.customView.findViewById(R.id.generated_password); + mGeneratedPasswordTextView = customView.findViewById(R.id.generated_password); mGeneratedPasswordTextView.setText(mGeneratedPassword); - - mSaveExplantaionTextView = params.customView.findViewById(R.id.generation_save_explanation); + mSaveExplantaionTextView = customView.findViewById(R.id.generation_save_explanation); mSaveExplantaionTextView.setText(mSaveExplanationText); - mView = new ModalDialogView(mController, params); + Resources resources = mContext.getResources(); + PropertyModel model = + new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) + .with(ModalDialogProperties.CONTROLLER, mController) + .with(ModalDialogProperties.TITLE, resources, + R.string.password_generation_dialog_title) + .with(ModalDialogProperties.CUSTOM_VIEW, customView) + .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, + R.string.password_generation_dialog_use_password_button) + .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, + R.string.password_generation_dialog_cancel_button) + .build(); + + mView = new ModalDialogView(mContext); + PropertyModelChangeProcessor.create(model, mView, new ModalDialogViewBinder()); } @Nullable
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionAppModalDialogView.java b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionAppModalDialogView.java index 53f8873..f394c94f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionAppModalDialogView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionAppModalDialogView.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.permissions; +import android.content.Context; import android.support.v4.widget.TextViewCompat; import android.text.TextUtils; import android.view.LayoutInflater; @@ -11,64 +12,51 @@ import android.widget.TextView; import org.chromium.chrome.R; +import org.chromium.chrome.browser.modaldialog.ModalDialogProperties; import org.chromium.chrome.browser.modaldialog.ModalDialogView; +import org.chromium.chrome.browser.modaldialog.ModalDialogViewBinder; +import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; /** * The Permission dialog that is app modal. */ -public class PermissionAppModalDialogView extends ModalDialogView { - private PermissionDialogDelegate mDialogDelegate; - private View mView; +class PermissionAppModalDialogView { + private final ModalDialogView mDialogView; - /** - * Constructor for the Dialog View. Creates the AlertDialog. - */ - public static PermissionAppModalDialogView create( - Controller controller, PermissionDialogDelegate delegate) { - Params params = new Params(); - params.positiveButtonText = delegate.getPrimaryButtonText(); - params.negativeButtonText = delegate.getSecondaryButtonText(); - return new PermissionAppModalDialogView(controller, params, delegate); - } + PermissionAppModalDialogView( + ModalDialogView.Controller controller, PermissionDialogDelegate delegate) { + Context context = delegate.getTab().getActivity(); + LayoutInflater inflater = LayoutInflater.from(context); + View customView = inflater.inflate(R.layout.permission_dialog, null); - private PermissionAppModalDialogView( - Controller controller, Params params, PermissionDialogDelegate delegate) { - super(controller, params); - mDialogDelegate = delegate; - params.customView = createView(); - } - - @Override - protected void prepareBeforeShow() { - super.prepareBeforeShow(); - TextView messageTextView = (TextView) mView.findViewById(R.id.text); - messageTextView.setText(prepareMainMessageString(mDialogDelegate)); - messageTextView.setVisibility(View.VISIBLE); - messageTextView.announceForAccessibility(mDialogDelegate.getMessageText()); - TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds( - messageTextView, mDialogDelegate.getDrawableId(), 0, 0, 0); - } - - /** - * Prepares the dialog before show. Creates the View inside of the dialog. - */ - private View createView() { - LayoutInflater inflater = LayoutInflater.from(getContext()); - mView = inflater.inflate(R.layout.permission_dialog, null); - return mView; - } - - private CharSequence prepareMainMessageString(final PermissionDialogDelegate delegate) { String messageText = delegate.getMessageText(); assert !TextUtils.isEmpty(messageText); - // TODO(timloh): Currently the strings are shared with infobars, so we for now manually - // remove the full stop (this code catches most but not all languages). Update the strings - // after removing the infobar path. - if (messageText.endsWith(".") || messageText.endsWith("。")) { - messageText = messageText.substring(0, messageText.length() - 1); - } + TextView messageTextView = customView.findViewById(R.id.text); + messageTextView.setText(messageText); + TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds( + messageTextView, delegate.getDrawableId(), 0, 0, 0); - return messageText; + PropertyModel model = + new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) + .with(ModalDialogProperties.CONTROLLER, controller) + .with(ModalDialogProperties.CUSTOM_VIEW, customView) + .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, + delegate.getPrimaryButtonText()) + .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, + delegate.getSecondaryButtonText()) + .with(ModalDialogProperties.CONTENT_DESCRIPTION, delegate.getMessageText()) + .build(); + + mDialogView = new ModalDialogView(context); + PropertyModelChangeProcessor.create(model, mDialogView, new ModalDialogViewBinder()); + } + + /** + * @return The {@link ModalDialogView} for the permission dialog. + */ + ModalDialogView getDialogView() { + return mDialogView; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java index b60cf74..18bc9de 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java
@@ -262,9 +262,9 @@ if (useAppModalDialogView()) { mModalDialogManager = mDialogDelegate.getTab().getActivity().getModalDialogManager(); - mAppModalDialogView = PermissionAppModalDialogView.create(this, mDialogDelegate); + mAppModalDialogView = new PermissionAppModalDialogView(this, mDialogDelegate); mModalDialogManager.showDialog( - mAppModalDialogView, ModalDialogManager.ModalDialogType.APP); + mAppModalDialogView.getDialogView(), ModalDialogManager.ModalDialogType.APP); } else { mDialogView = new PermissionDialogView(mDialogDelegate); mDialogView.createView( @@ -282,7 +282,7 @@ mDialogDelegate = null; if (mState == State.PROMPT_OPEN) { if (useAppModalDialogView()) { - mModalDialogManager.dismissDialog(mAppModalDialogView); + mModalDialogManager.dismissDialog(mAppModalDialogView.getDialogView()); } else { mDialogView.dismiss(); } @@ -315,7 +315,7 @@ default: assert false : "Unexpected button pressed in dialog: " + buttonType; } - mModalDialogManager.dismissDialog(mAppModalDialogView); + mModalDialogManager.dismissDialog(mAppModalDialogView.getDialogView()); } private void destroyDelegate() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AndroidPaymentAppsFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AndroidPaymentAppsFragment.java index 02343ea..5fd2b32 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AndroidPaymentAppsFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AndroidPaymentAppsFragment.java
@@ -28,8 +28,7 @@ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - PreferenceUtils.addPreferencesFromResource( - this, R.xml.autofill_and_payments_preference_fragment_screen); + PreferenceUtils.addPreferencesFromResource(this, R.xml.blank_preference_fragment_screen); getActivity().setTitle(R.string.payment_apps_title); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillPaymentMethodsFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillPaymentMethodsFragment.java index 2189ac7..2fe5408 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillPaymentMethodsFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillPaymentMethodsFragment.java
@@ -35,8 +35,7 @@ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - PreferenceUtils.addPreferencesFromResource( - this, R.xml.autofill_and_payments_preference_fragment_screen); + PreferenceUtils.addPreferencesFromResource(this, R.xml.blank_preference_fragment_screen); getActivity().setTitle(R.string.autofill_payment_methods); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfilesFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfilesFragment.java index d8383de..c179468 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfilesFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfilesFragment.java
@@ -34,8 +34,7 @@ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - PreferenceUtils.addPreferencesFromResource( - this, R.xml.autofill_and_payments_preference_fragment_screen); + PreferenceUtils.addPreferencesFromResource(this, R.xml.blank_preference_fragment_screen); getActivity().setTitle(R.string.autofill_addresses_settings_title); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/developer/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/preferences/developer/OWNERS new file mode 100644 index 0000000..e9689fa --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/developer/OWNERS
@@ -0,0 +1,4 @@ +eseckler@chromium.org +skyostil@chromium.org + +per-file Tracing*=file://base/trace_event/OWNERS
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/developer/TracingCategoriesPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/developer/TracingCategoriesPreferences.java new file mode 100644 index 0000000..52f1f68 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/developer/TracingCategoriesPreferences.java
@@ -0,0 +1,76 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.preferences.developer; + +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.Preference; +import android.preference.PreferenceFragment; + +import org.chromium.chrome.R; +import org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference; +import org.chromium.chrome.browser.preferences.PreferenceUtils; +import org.chromium.chrome.browser.tracing.TracingController; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Settings fragment that configures chrome tracing categories of a specific type. The type is + * passed to the fragment via an extra (EXTRA_CATEGORY_TYPE). + */ +public class TracingCategoriesPreferences + extends PreferenceFragment implements Preference.OnPreferenceChangeListener { + public static final String EXTRA_CATEGORY_TYPE = "type"; + + private @TracingPreferences.CategoryType int mType; + private Set<String> mEnabledCategories; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActivity().setTitle(R.string.prefs_tracing_category_selection_title); + PreferenceUtils.addPreferencesFromResource(this, R.xml.blank_preference_fragment_screen); + getPreferenceScreen().setOrderingAsAdded(true); + + mType = getArguments().getInt(EXTRA_CATEGORY_TYPE); + mEnabledCategories = new HashSet<>(TracingPreferences.getEnabledCategories(mType)); + + List<String> sortedCategories = + new ArrayList<>(TracingController.getInstance().getKnownCategories()); + Collections.sort(sortedCategories); + for (String category : sortedCategories) { + if (TracingPreferences.getCategoryType(category) == mType) createPreference(category); + } + } + + private void createPreference(String category) { + CheckBoxPreference preference = new ChromeBaseCheckBoxPreference(getActivity(), null); + preference.setKey(category); + preference.setTitle(category.startsWith(TracingPreferences.NON_DEFAULT_CATEGORY_PREFIX) + ? category.substring( + TracingPreferences.NON_DEFAULT_CATEGORY_PREFIX.length()) + : category); + preference.setChecked(mEnabledCategories.contains(category)); + preference.setPersistent(false); // We persist the preference value ourselves. + preference.setOnPreferenceChangeListener(this); + getPreferenceScreen().addPreference(preference); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + boolean value = (boolean) newValue; + if (value) { + mEnabledCategories.add(preference.getKey()); + } else { + mEnabledCategories.remove(preference.getKey()); + } + TracingPreferences.setEnabledCategories(mType, mEnabledCategories); + return true; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/developer/TracingPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/developer/TracingPreferences.java index c03bfc6..48f799db 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/developer/TracingPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/developer/TracingPreferences.java
@@ -5,36 +5,189 @@ package org.chromium.chrome.browser.preferences.developer; import android.os.Bundle; +import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceFragment; +import android.support.annotation.IntDef; +import org.chromium.base.ContextUtils; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.preferences.PreferenceUtils; import org.chromium.chrome.browser.tracing.TracingController; import org.chromium.chrome.browser.tracing.TracingNotificationManager; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + /** * Settings fragment that shows options for recording a performance trace. */ public class TracingPreferences extends PreferenceFragment implements TracingController.Observer { + static final String NON_DEFAULT_CATEGORY_PREFIX = "disabled-by-default-"; + + @VisibleForTesting + static final String UI_PREF_DEFAULT_CATEGORIES = "default_categories"; + @VisibleForTesting + static final String UI_PREF_NON_DEFAULT_CATEGORIES = "non_default_categories"; + @VisibleForTesting + static final String UI_PREF_MODE = "mode"; @VisibleForTesting static final String UI_PREF_START_RECORDING = "start_recording"; @VisibleForTesting static final String UI_PREF_TRACING_STATUS = "tracing_status"; + private static final String PREF_TRACING_CATEGORIES = "tracing_categories"; + private static final String PREF_TRACING_MODE = "tracing_mode"; + + // Ordered map that maps tracing mode string to resource id for its description. + private static final Map<String, Integer> TRACING_MODES = createTracingModesMap(); + + private Preference mPrefDefaultCategories; + private Preference mPrefNondefaultCategories; + private ListPreference mPrefMode; private Preference mPrefStartRecording; private Preference mPrefTracingStatus; + /** + * Type of a tracing category indicating whether it is enabled by default or not. + */ + @IntDef({CategoryType.DEFAULT, CategoryType.NON_DEFAULT}) + @Retention(RetentionPolicy.SOURCE) + public @interface CategoryType { + int DEFAULT = 0; + int NON_DEFAULT = 1; + } + + private static Map<String, Integer> createTracingModesMap() { + Map<String, Integer> map = new LinkedHashMap<>(); + map.put("record-until-full", R.string.prefs_tracing_mode_record_until_full); + map.put("record-as-much-as-possible", + R.string.prefs_tracing_mode_record_as_much_as_possible); + map.put("record-continuously", R.string.prefs_tracing_mode_record_continuously); + return map; + } + + /** + * @return the current set of all enabled categories, irrespective of their type. + */ + public static Set<String> getEnabledCategories() { + Set<String> enabled = + ContextUtils.getAppSharedPreferences().getStringSet(PREF_TRACING_CATEGORIES, null); + if (enabled == null) { + enabled = new HashSet<>(); + // By default, enable all default categories. + for (String category : TracingController.getInstance().getKnownCategories()) { + if (getCategoryType(category) == CategoryType.DEFAULT) enabled.add(category); + } + } + return enabled; + } + + /** + * Get the set of enabled categories of a given category type. + * + * @param type the category type. + * @return the current set of enabled categories with |type|. + */ + public static Set<String> getEnabledCategories(@CategoryType int type) { + Set<String> enabled = new HashSet<>(); + for (String category : getEnabledCategories()) { + if (type == getCategoryType(category)) { + enabled.add(category); + } + } + return enabled; + } + + /** + * Set the enabled categories of a given category type. The set of enabled categories with + * different types will not be changed. + * + * @param type the category type. + * @param enabledOfType the set of enabled categories with the given |type|. + */ + public static void setEnabledCategories(@CategoryType int type, Set<String> enabledOfType) { + Set<String> enabled = new HashSet<>(enabledOfType); + for (String category : getEnabledCategories()) { + if (type != getCategoryType(category)) { + enabled.add(category); + } + } + ContextUtils.getAppSharedPreferences() + .edit() + .putStringSet(PREF_TRACING_CATEGORIES, enabled) + .apply(); + } + + /** + * Get the type of a category derived from its name. + * @param category the name of the category. + * @return the type of the category. + */ + public static @CategoryType int getCategoryType(String category) { + return category.startsWith(NON_DEFAULT_CATEGORY_PREFIX) ? CategoryType.NON_DEFAULT + : CategoryType.DEFAULT; + } + + /** + * @return the current tracing mode stored in the preferences. Either "record-until-full", + * "record-as-much-as-possible", or "record-continuously". + */ + public static String getSelectedTracingMode() { + return ContextUtils.getAppSharedPreferences().getString( + PREF_TRACING_MODE, TRACING_MODES.keySet().iterator().next()); + } + + /** + * Select and store a new tracing mode in the preferences. + * + * @param tracingMode the new tracing mode, should be either "record-until-full", + * "record-as-much-as-possible", or "record-continuously". + */ + public static void setSelectedTracingMode(String tracingMode) { + assert TRACING_MODES.containsKey(tracingMode); + ContextUtils.getAppSharedPreferences() + .edit() + .putString(PREF_TRACING_MODE, tracingMode) + .apply(); + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getActivity().setTitle(R.string.prefs_tracing); PreferenceUtils.addPreferencesFromResource(this, R.xml.tracing_preferences); + mPrefDefaultCategories = findPreference(UI_PREF_DEFAULT_CATEGORIES); + mPrefNondefaultCategories = findPreference(UI_PREF_NON_DEFAULT_CATEGORIES); + mPrefMode = (ListPreference) findPreference(UI_PREF_MODE); mPrefStartRecording = findPreference(UI_PREF_START_RECORDING); mPrefTracingStatus = findPreference(UI_PREF_TRACING_STATUS); + mPrefDefaultCategories.getExtras().putInt( + TracingCategoriesPreferences.EXTRA_CATEGORY_TYPE, CategoryType.DEFAULT); + + mPrefNondefaultCategories.getExtras().putInt( + TracingCategoriesPreferences.EXTRA_CATEGORY_TYPE, CategoryType.NON_DEFAULT); + + mPrefMode.setEntryValues(TRACING_MODES.keySet().toArray(new String[TRACING_MODES.size()])); + String[] descriptions = new String[TRACING_MODES.size()]; + int i = 0; + for (int resourceId : TRACING_MODES.values()) { + descriptions[i++] = getActivity().getResources().getString(resourceId); + } + mPrefMode.setEntries(descriptions); + mPrefMode.setOnPreferenceChangeListener((preference, newValue) -> { + setSelectedTracingMode((String) newValue); + updatePreferences(); + return true; + }); + mPrefStartRecording.setOnPreferenceClickListener(preference -> { TracingController.getInstance().startRecording(); updatePreferences(); @@ -67,8 +220,34 @@ boolean idle = state == TracingController.State.IDLE || !initialized; boolean notificationsEnabled = TracingNotificationManager.browserNotificationsEnabled(); + mPrefDefaultCategories.setEnabled(initialized); + mPrefNondefaultCategories.setEnabled(initialized); + mPrefMode.setEnabled(initialized); mPrefStartRecording.setEnabled(idle && initialized && notificationsEnabled); + if (initialized) { + int defaultTotal = 0; + int nondefaultTotal = 0; + for (String category : TracingController.getInstance().getKnownCategories()) { + if (getCategoryType(category) == CategoryType.DEFAULT) { + defaultTotal++; + } else { + nondefaultTotal++; + } + } + + int defaultEnabled = getEnabledCategories(CategoryType.DEFAULT).size(); + int nondefaultEnabled = getEnabledCategories(CategoryType.NON_DEFAULT).size(); + + mPrefDefaultCategories.setSummary(getActivity().getResources().getString( + R.string.prefs_tracing_categories_summary, defaultEnabled, defaultTotal)); + mPrefNondefaultCategories.setSummary(getActivity().getResources().getString( + R.string.prefs_tracing_categories_summary, nondefaultEnabled, nondefaultTotal)); + + mPrefMode.setValue(getSelectedTracingMode()); + mPrefMode.setSummary(TRACING_MODES.get(getSelectedTracingMode())); + } + if (!notificationsEnabled) { mPrefStartRecording.setTitle(R.string.prefs_tracing_start); mPrefTracingStatus.setTitle(R.string.tracing_notifications_disabled);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java index 1f8cc50..3d53e2e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
@@ -8,7 +8,6 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; -import android.os.Handler; import org.chromium.base.ActivityState; import org.chromium.base.ApiCompatibilityUtils; @@ -312,7 +311,7 @@ } private void notifySignInAllowedChanged() { - new Handler().post(() -> { + ThreadUtils.postOnUiThread(() -> { for (SignInAllowedObserver observer : mSignInAllowedObservers) { observer.onSignInAllowedChanged(); } @@ -671,7 +670,7 @@ assert mSignOutState != null; if (mSignOutState.callback != null) { - new Handler().post(mSignOutState.callback); + ThreadUtils.postOnUiThread(mSignOutState.callback); } mSignOutState = null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index 35f66c5..ed059953 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -45,7 +45,6 @@ import org.chromium.chrome.browser.ChromeActionModeCallback; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.ChromeVersionInfo; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.IntentHandler.TabOpenType; @@ -72,7 +71,6 @@ import org.chromium.chrome.browser.native_page.NativePage; import org.chromium.chrome.browser.native_page.NativePageAssassin; import org.chromium.chrome.browser.native_page.NativePageFactory; -import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.policy.PolicyAuditor; import org.chromium.chrome.browser.prerender.ExternalPrerenderHandler; @@ -91,7 +89,6 @@ import org.chromium.chrome.browser.tabmodel.TabReparentingParams; import org.chromium.chrome.browser.vr.VrModuleProvider; import org.chromium.chrome.browser.widget.PulseDrawable; -import org.chromium.chrome.browser.widget.ViewHighlighter; import org.chromium.chrome.browser.widget.textbubble.TextBubble; import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; import org.chromium.components.embedder_support.view.ContentView; @@ -119,7 +116,6 @@ import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.mojom.WindowOpenDisposition; import org.chromium.ui.widget.AnchoredPopupWindow; -import org.chromium.ui.widget.ViewRectProvider; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -369,15 +365,6 @@ private boolean mIsDetached; /** - * Stores total data saved at the start of a page load. Used to calculate delta at the end of - * page load, which is just an estimate of the data saved for the current page load since there - * may be multiple pages loading at the same time. This estimate is used to get an idea of how - * widely used the data saver feature is for a particular user at a time (i.e. not since the - * user started using Chrome). - */ - private long mDataSavedOnStartPageLoad; - - /** * The Text bubble used to display In Product help widget for download feature on videos. */ private TextBubble mDownloadIPHBubble; @@ -1470,9 +1457,6 @@ */ protected void didStartPageLoad(String validatedUrl, boolean showingErrorPage) { updateTitle(); - mDataSavedOnStartPageLoad = - DataReductionProxySettings.getInstance().getContentLengthSavedInHistorySummary(); - if (mIsRendererUnresponsive) handleRendererResponsiveStateChanged(true); for (TabObserver observer : mObservers) observer.onPageLoadStarted(this, validatedUrl); @@ -1489,87 +1473,6 @@ for (TabObserver observer : mObservers) observer.onPageLoadFinished(this, url); mIsBeingRestored = false; - - // TODO(crbug.com/889682): Consider moving the rest of this function to a Tab User data. - long dataSaved = - DataReductionProxySettings.getInstance().getContentLengthSavedInHistorySummary() - - mDataSavedOnStartPageLoad; - - Tracker tracker = TrackerFactory.getTrackerForProfile(Profile.getLastUsedProfile()); - if (dataSaved > 0L) { - tracker.notifyEvent(EventConstants.DATA_SAVED_ON_PAGE_LOAD); - } - - if (isPreview()) { - tracker.notifyEvent(EventConstants.PREVIEWS_PAGE_LOADED); - } - - maybeShowDataSaverInProductHelp(tracker); - maybeShowPreviewVerboseStatusInProductHelp(tracker); - } - - private void maybeShowDataSaverInProductHelp(final Tracker tracker) { - if (!tracker.shouldTriggerHelpUI(FeatureConstants.DATA_SAVER_DETAIL_FEATURE)) return; - - if (!(getActivity() instanceof ChromeTabbedActivity)) return; - - View anchorView = getActivity().getToolbarManager().getMenuButton(); - if (anchorView == null) return; - - ViewRectProvider rectProvider = new ViewRectProvider(anchorView); - TextBubble textBubble = - new TextBubble(getActivity(), anchorView, R.string.iph_data_saver_detail_text, - R.string.iph_data_saver_detail_accessibility_text, rectProvider); - textBubble.setDismissOnTouchInteraction(true); - getActivity().getAppMenuHandler().setMenuHighlight(R.id.app_menu_footer); - textBubble.addOnDismissListener(new OnDismissListener() { - @Override - public void onDismiss() { - ThreadUtils.postOnUiThread(new Runnable() { - @Override - public void run() { - tracker.dismissed(FeatureConstants.DATA_SAVER_DETAIL_FEATURE); - getActivity().getAppMenuHandler().setMenuHighlight(null); - } - }); - } - }); - int yInsetPx = mThemedApplicationContext.getResources().getDimensionPixelOffset( - R.dimen.text_bubble_menu_anchor_y_inset); - rectProvider.setInsetPx(0, 0, 0, yInsetPx); - textBubble.show(); - } - - private void maybeShowPreviewVerboseStatusInProductHelp(final Tracker tracker) { - if (!isPreview()) return; - if (!(getActivity() instanceof ChromeTabbedActivity)) return; - final View anchorView = getActivity().getToolbarManager().getSecurityIconView(); - if (anchorView == null) return; - - if (!tracker.shouldTriggerHelpUI(FeatureConstants.PREVIEWS_OMNIBOX_UI_FEATURE)) return; - - final ViewRectProvider rectProvider = new ViewRectProvider(anchorView); - final TextBubble textBubble = - new TextBubble(getActivity(), anchorView, R.string.iph_previews_omnibox_ui_text, - R.string.iph_previews_omnibox_ui_accessibility_text, rectProvider); - textBubble.setDismissOnTouchInteraction(true); - textBubble.addOnDismissListener(new OnDismissListener() { - @Override - public void onDismiss() { - ThreadUtils.postOnUiThread(new Runnable() { - @Override - public void run() { - ViewHighlighter.turnOffHighlight(anchorView); - tracker.dismissed(FeatureConstants.PREVIEWS_OMNIBOX_UI_FEATURE); - } - }); - } - }); - final int yInsetPx = mThemedApplicationContext.getResources().getDimensionPixelOffset( - R.dimen.text_bubble_menu_anchor_y_inset); - rectProvider.setInsetPx(0, 0, 0, yInsetPx); - textBubble.show(); - ViewHighlighter.turnOnHighlight(anchorView, true); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarButtonInProductHelpController.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarButtonInProductHelpController.java index ecf2ba2..98f5ad5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarButtonInProductHelpController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarButtonInProductHelpController.java
@@ -8,53 +8,143 @@ import android.support.annotation.StringRes; import android.text.TextUtils; import android.view.View; +import android.widget.PopupWindow.OnDismissListener; import org.chromium.base.Callback; import org.chromium.base.ThreadUtils; import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.appmenu.AppMenuHandler; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; +import org.chromium.chrome.browser.lifecycle.Destroyable; +import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.widget.ViewHighlighter; import org.chromium.chrome.browser.widget.textbubble.TextBubble; +import org.chromium.components.feature_engagement.EventConstants; import org.chromium.components.feature_engagement.FeatureConstants; import org.chromium.components.feature_engagement.Tracker; import org.chromium.ui.widget.ViewRectProvider; /** * A helper class for IPH shown on the toolbar. + * TODO(jinsukkim): Find a way to break (i.e. invert) the dependency on Destroyable + * to be able to split up the build target for toolbar which can be a base construct. */ -public class ToolbarButtonInProductHelpController { - private ToolbarButtonInProductHelpController() {} +public class ToolbarButtonInProductHelpController implements Destroyable { + private final TabModelSelectorTabObserver mPageLoadObserver; + private final ChromeActivity mActivity; + + /** + * Create ToolbarButtonInProductHelpController. + * @param activity ChromeActivity the controller is attached to. + * @param isShowingPromo {@code true} if promo dialog is being shown. + */ + public static void create(final ChromeActivity activity, boolean isShowingPromo) { + ToolbarButtonInProductHelpController controller = + new ToolbarButtonInProductHelpController(activity); + activity.getLifecycleDispatcher().register(controller); + if (!isShowingPromo) controller.maybeShowColdStartIPH(); + } + + private ToolbarButtonInProductHelpController(final ChromeActivity activity) { + mActivity = activity; + // TODO(jinsukkim): Consider switching to ActivityTabProvider and its TabObserver. + mPageLoadObserver = new TabModelSelectorTabObserver(activity.getTabModelSelector()) { + /** + * Stores total data saved at the start of a page load. Used to calculate delta at the + * end of page load, which is just an estimate of the data saved for the current page + * load since there may be multiple pages loading at the same time. This estimate is + * used to get an idea of how widely used the data saver feature is for a particular + * user at a time (i.e. not since the user started using Chrome). + */ + private long mDataSavedOnStartPageLoad; + private Tab mPageLoadTab; + + @Override + public void onPageLoadStarted(Tab tab, String url) { + if (tab != activity.getActivityTabProvider().getActivityTab()) return; + mDataSavedOnStartPageLoad = DataReductionProxySettings.getInstance() + .getContentLengthSavedInHistorySummary(); + mPageLoadTab = tab; + } + + @Override + public void onPageLoadFinished(Tab tab, String url) { + if (mPageLoadTab != tab) return; + long dataSaved = DataReductionProxySettings.getInstance() + .getContentLengthSavedInHistorySummary() + - mDataSavedOnStartPageLoad; + Tracker tracker = TrackerFactory.getTrackerForProfile(Profile.getLastUsedProfile()); + if (dataSaved > 0L) tracker.notifyEvent(EventConstants.DATA_SAVED_ON_PAGE_LOAD); + if (tab.isPreview()) tracker.notifyEvent(EventConstants.PREVIEWS_PAGE_LOADED); + if (tab == activity.getActivityTabProvider().getActivityTab() + && tab.isUserInteractable()) { + maybeShowDataSaver(activity); + maybeShowPreviewVerboseStatus(activity); + } + mPageLoadTab = null; + } + }; + } + + @Override + public void destroy() { + mPageLoadObserver.destroy(); + } + + // Attempts to show an IPH text bubble for data saver. + private static void maybeShowDataSaver(ChromeActivity activity) { + View anchorView = activity.getToolbarManager().getMenuButton(); + if (anchorView == null) return; + + setupAndMaybeShowIPHForFeature(FeatureConstants.DATA_SAVER_DETAIL_FEATURE, + R.id.app_menu_footer, R.string.iph_data_saver_detail_text, + R.string.iph_data_saver_detail_accessibility_text, anchorView, + activity.getAppMenuHandler(), activity); + } + + // Attempts to show an IPH text bubble for page in preview mode. + private static void maybeShowPreviewVerboseStatus(ChromeActivity activity) { + if (!activity.getActivityTabProvider().getActivityTab().isPreview()) return; + + final View anchorView = activity.getToolbarManager().getSecurityIconView(); + if (anchorView == null) return; + + setupAndMaybeShowIPHForFeature(FeatureConstants.PREVIEWS_OMNIBOX_UI_FEATURE, null, + R.string.iph_previews_omnibox_ui_text, + R.string.iph_previews_omnibox_ui_accessibility_text, anchorView, null, activity); + } /** * Attempts to show an IPH text bubble for those that trigger on a cold start. * @param activity The activity to use for the IPH. */ - public static void maybeShowColdStartIPH(ChromeTabbedActivity activity) { - maybeShowDownloadHomeIPH(activity); - maybeShowNTPButtonIPH(activity); + public void maybeShowColdStartIPH() { + maybeShowDownloadHomeIPH(); + maybeShowNTPButtonIPH(); } - private static void maybeShowDownloadHomeIPH(ChromeTabbedActivity activity) { + private void maybeShowDownloadHomeIPH() { setupAndMaybeShowIPHForFeature(FeatureConstants.DOWNLOAD_HOME_FEATURE, R.id.downloads_menu_id, R.string.iph_download_home_text, R.string.iph_download_home_accessibility_text, - activity.getToolbarManager().getMenuButton(), activity.getAppMenuHandler(), - Profile.getLastUsedProfile(), activity); + mActivity.getToolbarManager().getMenuButton(), mActivity.getAppMenuHandler(), + mActivity); } - private static void maybeShowNTPButtonIPH(ChromeTabbedActivity activity) { - if (!canShowNTPButtonIPH(activity)) return; + private void maybeShowNTPButtonIPH() { + if (!canShowNTPButtonIPH(mActivity)) return; setupAndMaybeShowIPHForFeature(FeatureConstants.NTP_BUTTON_FEATURE, null, R.string.iph_ntp_button_text_home_text, R.string.iph_ntp_button_text_home_accessibility_text, - activity.findViewById(R.id.home_button), null, Profile.getLastUsedProfile(), - activity); + mActivity.findViewById(R.id.home_button), null, mActivity); } /** @@ -68,25 +158,30 @@ FeatureConstants.DOWNLOAD_INFOBAR_DOWNLOAD_CONTINUING_FEATURE, R.id.downloads_menu_id, R.string.iph_download_infobar_download_continuing_text, R.string.iph_download_infobar_download_continuing_text, - activity.getToolbarManager().getMenuButton(), activity.getAppMenuHandler(), profile, + activity.getToolbarManager().getMenuButton(), activity.getAppMenuHandler(), activity); } private static void setupAndMaybeShowIPHForFeature(String featureName, Integer highlightMenuItemId, @StringRes int stringId, @StringRes int accessibilityStringId, View anchorView, - @Nullable AppMenuHandler appMenuHandler, Profile profile, - ChromeTabbedActivity activity) { - final Tracker tracker = TrackerFactory.getTrackerForProfile(profile); - tracker.addOnInitializedCallback((Callback<Boolean>) success - -> maybeShowIPH(tracker, featureName, highlightMenuItemId, stringId, - accessibilityStringId, anchorView, appMenuHandler, activity)); + @Nullable AppMenuHandler appMenuHandler, ChromeActivity activity) { + final Tracker tracker = TrackerFactory.getTrackerForProfile(Profile.getLastUsedProfile()); + tracker.addOnInitializedCallback((Callback<Boolean>) success -> { + OnDismissListener dismissListener = () -> anchorView.getHandler().postDelayed(() -> { + tracker.dismissed(featureName); + turnOffHighlightForTextBubble(appMenuHandler, anchorView); + }, ViewHighlighter.IPH_MIN_DELAY_BETWEEN_TWO_HIGHLIGHTS); + + turnOnHighlightForTextBubble(appMenuHandler, highlightMenuItemId, anchorView); + maybeShowIPHBubble(tracker, featureName, stringId, accessibilityStringId, anchorView, + activity, dismissListener); + }); } - private static void maybeShowIPH(Tracker tracker, String featureName, - Integer highlightMenuItemId, @StringRes int stringId, - @StringRes int accessibilityStringId, View anchorView, AppMenuHandler appMenuHandler, - ChromeTabbedActivity activity) { + private static void maybeShowIPHBubble(Tracker tracker, String featureName, + @StringRes int stringId, @StringRes int accessibilityStringId, View anchorView, + ChromeActivity activity, OnDismissListener dismissListener) { // Activity was destroyed; don't show IPH. if (activity.isActivityDestroyed() || anchorView == null) return; @@ -109,12 +204,7 @@ TextBubble textBubble = new TextBubble( activity, anchorView, stringId, accessibilityStringId, rectProvider); textBubble.setDismissOnTouchInteraction(true); - textBubble.addOnDismissListener(() -> anchorView.getHandler().postDelayed(() -> { - tracker.dismissed(featureName); - turnOffHighlightForTextBubble(appMenuHandler, anchorView); - }, ViewHighlighter.IPH_MIN_DELAY_BETWEEN_TWO_HIGHLIGHTS)); - - turnOnHighlightForTextBubble(appMenuHandler, highlightMenuItemId, anchorView); + textBubble.addOnDismissListener(dismissListener); int yInsetPx = activity.getResources().getDimensionPixelOffset( R.dimen.text_bubble_menu_anchor_y_inset); @@ -140,7 +230,7 @@ } } - private static boolean canShowNTPButtonIPH(ChromeTabbedActivity activity) { + private static boolean canShowNTPButtonIPH(ChromeActivity activity) { View homeButton = activity.findViewById(R.id.home_button); return FeatureUtilities.isNewTabPageButtonEnabled() && !activity.getCurrentTabModel().isIncognito() && activity.getActivityTab() != null
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingController.java b/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingController.java index 6911b4e..0af88f1b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingController.java
@@ -6,6 +6,7 @@ import android.content.Context; import android.support.annotation.IntDef; +import android.text.TextUtils; import org.chromium.base.ContextUtils; import org.chromium.base.Log; @@ -13,6 +14,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.task.AsyncTask; import org.chromium.chrome.R; +import org.chromium.chrome.browser.preferences.developer.TracingPreferences; import org.chromium.content_public.browser.TracingControllerAndroid; import org.chromium.ui.widget.Toast; @@ -194,9 +196,9 @@ private void startNativeTrace() { assert mState == State.STARTING; - // TODO(eseckler): Support configuring these. - String categories = "*"; - String options = "record-until-full"; + // TODO(eseckler): TracingControllerAndroid currently doesn't support a json trace config. + String categories = TextUtils.join(",", TracingPreferences.getEnabledCategories()); + String options = TracingPreferences.getSelectedTracingMode(); if (!mNativeController.startTracing( mTracingTempFile.getPath(), false, categories, options, true)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrAlertDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrAlertDialog.java index 6e4c7ed..c7a4a5c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrAlertDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrAlertDialog.java
@@ -11,7 +11,11 @@ import org.chromium.chrome.browser.modaldialog.DialogDismissalCause; import org.chromium.chrome.browser.modaldialog.ModalDialogManager; +import org.chromium.chrome.browser.modaldialog.ModalDialogProperties; import org.chromium.chrome.browser.modaldialog.ModalDialogView; +import org.chromium.chrome.browser.modaldialog.ModalDialogViewBinder; +import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; /** * This class implements a VrAlertDialog which is similar to Android AlertDialog in VR. @@ -117,18 +121,23 @@ @Override public void onDismiss(@DialogDismissalCause int dialogDismissal) {} }; - final ModalDialogView.Params params = new ModalDialogView.Params(); - assert(mView == null || mMessage == null); - if (mView != null) { - params.customView = mView; - } else if (mMessage != null) { - params.message = mMessage.toString(); - } - if (mButtonPositive != null) params.positiveButtonText = mButtonPositive.getText(); - if (mButtonNegative != null) params.negativeButtonText = mButtonNegative.getText(); + String message = mMessage != null ? mMessage.toString() : null; + String positiveButtonText = mButtonPositive != null ? mButtonPositive.getText() : null; + String negativeButtonText = mButtonNegative != null ? mButtonNegative.getText() : null; - return new ModalDialogView(controller, params); + final PropertyModel model = + new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) + .with(ModalDialogProperties.CONTROLLER, controller) + .with(ModalDialogProperties.MESSAGE, message) + .with(ModalDialogProperties.CUSTOM_VIEW, mView) + .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, positiveButtonText) + .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, negativeButtonText) + .build(); + + ModalDialogView dialogView = new ModalDialogView(getContext()); + PropertyModelChangeProcessor.create(model, dialogView, new ModalDialogViewBinder()); + return dialogView; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java index ec090e1..f6a416b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java
@@ -4,15 +4,14 @@ package org.chromium.chrome.browser.webapps; -import android.content.pm.PackageManager; import android.graphics.Bitmap; import org.chromium.base.Callback; import org.chromium.base.ContextUtils; +import org.chromium.base.PackageUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.task.AsyncTask; import org.chromium.chrome.browser.AppHooks; -import org.chromium.chrome.browser.banners.InstallerDelegate; import org.chromium.chrome.browser.metrics.WebApkUma; import org.chromium.webapk.lib.common.WebApkConstants; @@ -149,8 +148,7 @@ } private boolean isWebApkInstalled(String packageName) { - PackageManager packageManager = ContextUtils.getApplicationContext().getPackageManager(); - return InstallerDelegate.isInstalled(packageManager, packageName); + return PackageUtils.isPackageInstalled(ContextUtils.getApplicationContext(), packageName); } private native void nativeOnInstallFinished(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java index 5170c19..55beb511 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java
@@ -6,14 +6,13 @@ import android.content.Context; import android.content.SharedPreferences; -import android.content.pm.PackageManager; import android.text.TextUtils; import org.chromium.base.ContextUtils; +import org.chromium.base.PackageUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.task.AsyncTask; -import org.chromium.chrome.browser.banners.InstallerDelegate; import org.chromium.chrome.browser.browsing_data.UrlFilter; import org.chromium.chrome.browser.browsing_data.UrlFilterBridge; import org.chromium.webapk.lib.common.WebApkConstants; @@ -178,12 +177,11 @@ * */ public List<String> findWebApksWithPendingUpdate() { ArrayList<String> webApkIdsWithPendingUpdate = new ArrayList<String>(); - PackageManager packageManager = ContextUtils.getApplicationContext().getPackageManager(); for (HashMap.Entry<String, WebappDataStorage> entry : mStorages.entrySet()) { WebappDataStorage storage = entry.getValue(); if (!TextUtils.isEmpty(storage.getPendingUpdateRequestPath()) - && InstallerDelegate.isInstalled( - packageManager, storage.getWebApkPackageName())) { + && PackageUtils.isPackageInstalled(ContextUtils.getApplicationContext(), + storage.getWebApkPackageName())) { webApkIdsWithPendingUpdate.add(entry.getKey()); } } @@ -233,7 +231,8 @@ // deprecated naming scheme and that the WebApk is still installed. The former is // necessary as we migrate away from the old naming scheme and garbage collect. if (entry.getKey().startsWith(WebApkConstants.WEBAPK_ID_PREFIX) - && isWebApkInstalled(webApkPackage)) { + && PackageUtils.isPackageInstalled( + ContextUtils.getApplicationContext(), webApkPackage)) { continue; } } else if ((currentTime - storage.getLastUsedTimeMs()) @@ -300,14 +299,6 @@ urlFilter.destroy(); } - /** - * Returns true if the given WebAPK is installed. - */ - private boolean isWebApkInstalled(String webApkPackage) { - PackageManager packageManager = ContextUtils.getApplicationContext().getPackageManager(); - return InstallerDelegate.isInstalled(packageManager, webApkPackage); - } - private static SharedPreferences openSharedPreferences() { return ContextUtils.getApplicationContext().getSharedPreferences( REGISTRY_FILE_NAME, Context.MODE_PRIVATE);
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 24ac097..c61fc9c9 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -176,12 +176,6 @@ <message name="IDS_TEXT_OFF" desc="Text indicating that an option is turned off. [CHAR-LIMIT=20]"> Off </message> - <message name="IDS_SHOW" desc="Generic label to show content for a feature. [CHAR-LIMIT=20]"> - Show - </message> - <message name="IDS_HIDE" desc="Generic label to hide content for a feature. [CHAR-LIMIT=20]"> - Hide - </message> <message name="IDS_LEARN_MORE" desc="Generic label for menu item to learn more about a feature. [CHAR-LIMIT=32]"> Learn more </message> @@ -1415,6 +1409,30 @@ <message name="IDS_PREFS_TRACING_ACTIVE_SUMMARY" translateable="false" desc="The summary of a text preference shown when a Chrome trace is being recorded."> A trace is being recorded. Use the notification to stop and share the result. </message> + <message name="IDS_PREFS_TRACING_DEFAULT_CATEGORIES_TITLE" translateable="false" desc="Title of a preference for selecting the enabled default tracing categories."> + Default categories + </message> + <message name="IDS_PREFS_TRACING_NON_DEFAULT_CATEGORIES_TITLE" translateable="false" desc="Title of a preference for selecting the enabled disabled-by-default tracing categories."> + Disabled-by-default categories + </message> + <message name="IDS_PREFS_TRACING_CATEGORIES_SUMMARY" translateable="false" desc="The summary of a preference for selecting the enabled categories."> + <ph name="NUM_ENABLED_CATEGORIES">%1$d<ex>3</ex></ph> out of <ph name="NUM_TOTAL_CATEGORIES">%2$d<ex>20</ex></ph> enabled + </message> + <message name="IDS_PREFS_TRACING_CATEGORY_SELECTION_TITLE" translateable="false" desc="Title for the trace category selection preferences page. [CHAR-LIMIT=32]"> + Select categories + </message> + <message name="IDS_PREFS_TRACING_MODE_TITLE" translateable="false" desc="Title of a preference for changing the tracing mode."> + Tracing mode + </message> + <message name="IDS_PREFS_TRACING_MODE_RECORD_UNTIL_FULL" translateable="false" desc="Title for the tracing mode entry that records data until the buffer is full."> + Record until full + </message> + <message name="IDS_PREFS_TRACING_MODE_RECORD_AS_MUCH_AS_POSSIBLE" translateable="false" desc="Title for the tracing mode entry that records as much data as possible."> + Record until full (large buffer) + </message> + <message name="IDS_PREFS_TRACING_MODE_RECORD_CONTINUOUSLY" translateable="false" desc="Title for the tracing mode entry that records data continuously into a ring buffer."> + Record continuously + </message> <!-- Tracing notifications (not translated, since part of developer preferences) --> <message name="IDS_TRACING_NOTIFICATIONS_DISABLED" translateable="false" desc="Message of a toast shown when tracing could not be started because the Chrome app's notifications are disabled."> @@ -2153,9 +2171,6 @@ </message> <!-- App banner strings --> - <message name="IDS_APP_BANNER_INSTALLING" desc="Button text indicating that an application is being installed. [CHAR-LIMIT=25]"> - Installing… - </message> <message name="IDS_APP_BANNER_OPEN" desc="Text that indicates that clicking on the button will launch an application. [CHAR-LIMIT=25]"> Open </message>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_am.xtb b/chrome/android/java/strings/translations/android_chrome_strings_am.xtb index 0c5d54b..944a996 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_am.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_am.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />ቅንብሮች<ph name="END_LINK1" />ን በማንኛውም ጊዜ ማበጀት ይችላሉ። Chromeን እና እንደ ትርጉም፣ ፍለጋ እና ማስታወቂያዎች ያሉ ሌሎች የGoogle አገልግሎቶችን ግላዊነት ለማላበስ Google እርስዎ በሚጎበኟቸው ጣቢያዎች ላይ ያለ ይዘትን እና የአሰሳ እንቅስቃሴ ሊጠቀም ይችላል።</translation> <translation id="2328985652426384049">መግባት አልተቻለም</translation> <translation id="2342981853652716282">የእርስዎን ዕልባቶች፣ የይለፍ ቃላት እና በሁሉም የእርስዎ መሣሪያዎች ላይ ተጨማሪ ለማግኘት ወደ Chrome በመለያ ይግቡ።</translation> -<translation id="2343328333327081434">በመጫን ላይ…</translation> <translation id="2349710944427398404">መለያዎች፣ ዕልባቶች እና የተቀመጡ ቅንብሮችን ጨምሮ Chrome የተጠቀመው ጠቅላላ ውሂብ</translation> <translation id="2351097562818989364">የትርጉም ቅንብሮችዎ ዳግም እንዲጀምሩ ተደርገዋል።</translation> <translation id="2359808026110333948">ቀጥል</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ar.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ar.xtb index 9d94a3f..0435a50 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ar.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ar.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">يمكن لك أو لوالديك تخصيص <ph name="BEGIN_LINK1" />الإعدادات<ph name="END_LINK1" /> في أي وقت. قد تستخدم Google محتوى المواقع الإلكترونية التي تزورها وتفاعلات المتصفّح ونشاطه لتخصيص Chrome وخدمات Google، مثل "ترجمة" و"بحث" والإعلانات.</translation> <translation id="2328985652426384049">تعذر تسجيل الدخول</translation> <translation id="2342981853652716282">سجّل الدخول إلى Chrome للحصول غلى الإشارات المرجعية وكلمات المرور والمزيد على جميع أجهزتك.</translation> -<translation id="2343328333327081434">جارٍ التثبيت...</translation> <translation id="2349710944427398404">إجمالي البيانات المُستخدَمة من قِبل Chrome، بما في ذلك الحسابات والإشارات المرجعية والإعدادات المحفوظة</translation> <translation id="2351097562818989364">تم إعادة ضبط إعداداتك للترجمة.</translation> <translation id="2359808026110333948">المتابعة</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_bg.xtb b/chrome/android/java/strings/translations/android_chrome_strings_bg.xtb index c04d701..8a0be465 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_bg.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_bg.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Настройките<ph name="END_LINK1" /> могат да бъдат персонализирани от вас или родителите ви по всяко време. Може да използваме съдържанието на посещаваните от вас сайтове, активността в браузъра и взаимодействията с него, за да персонализираме Chrome и услуги на Google, като Преводач, Търсене и рекламите.</translation> <translation id="2328985652426384049">Влизането в профила не е възможно</translation> <translation id="2342981853652716282">Влезте в Chrome, за да получите отметките, паролите и другите си неща на всичките си устройства.</translation> -<translation id="2343328333327081434">Инсталира се…</translation> <translation id="2349710944427398404">Общо място в хранилището, което се използва от Chrome, включително за профили, отметки и запазени настройки</translation> <translation id="2351097562818989364">Настройките ви за превод са нулирани.</translation> <translation id="2359808026110333948">Напред</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_bn.xtb b/chrome/android/java/strings/translations/android_chrome_strings_bn.xtb index 8bd5d04..72ab7e7 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_bn.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_bn.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />সেটিংস<ph name="END_LINK1" /> যেকোনও সময় আপনি বা আপনার অভিভাবক কাস্টমাইজ করতে পারবেন। Google, আপনার দেখা সাইটগুলির কন্টেন্ট, ব্রাউজার ইন্টার্যাকশন এবং অ্যাক্টিভিটি ব্যবহার করে Chrome এবং অন্যান্য Google পরিষেবা যেমন অনুবাদ, সার্চ ও বিজ্ঞাপনগুলি ব্যক্তিগতকৃত করতে পারে।</translation> <translation id="2328985652426384049">সাইন ইন করতে পারছেন না</translation> <translation id="2342981853652716282">আপনার বুকমার্ক, পাসওয়ার্ড, এবং অন্যান্য জিনিস আপনার সমস্ত ডিভাইসে পেতে Chrome এ সাইন-ইন করুন।</translation> -<translation id="2343328333327081434">ইনস্টল হচ্ছে...</translation> <translation id="2349710944427398404">অ্যাকাউন্ট, বুকমার্ক, এবং সংরক্ষণ করা সেটিংস সহ Chrome এর দ্বারা ব্যবহৃত মোট ডেটা</translation> <translation id="2351097562818989364">আপনার অনুবাদ সেটিংস আবার সেট করা হয়েছে৷</translation> <translation id="2359808026110333948">অবিরত</translation> @@ -550,7 +549,7 @@ <translation id="5240817131241497236">Chrome-এর মধ্যে যে সেটিংসের মাধ্যমে সিঙ্ক, ব্যাক্তিগতকরণ এবং অন্যান্য Google পরিষেবাগুলি নিয়ন্ত্রিত হয় সেটিতে পরিবর্তন করা হয়েছে। এর ফলে আপনার বর্তমান সেটিংস প্রভাবিত হতে পারে।</translation> <translation id="5264003212305142034"><ph name="BEGIN_LINK1" />সেটিংস<ph name="END_LINK1" /> যেকোনও সময় কাস্টমাইজ করা যায়। .Google আপনার দেখা সাইটগুলির কন্টেন্ট, এছাড়া ব্রাউজারের অ্যাক্টিভিটি ও ইন্টার্যাকশন ব্যবহার করে Chrome এবং অন্যান্য Google পরিষেবা যেমন অনুবাদ, সার্চ ও বিজ্ঞাপনগুলি ব্যক্তিগতকৃত করতে পারে।</translation> <translation id="5271967389191913893">ডিভাইস ডাউনলোড করা সামগ্রী খুলতে পারবে না৷</translation> -<translation id="5274381992091475657">অটোফিল সহায়ক</translation> +<translation id="5274381992091475657">অটোফিল অ্যাসিস্ট্যান্ট</translation> <translation id="528192093759286357">উপর থেকে টেনে আনুন এবং পূর্ণ স্ক্রিন থেকে বেরিয়ে যেতে পিছনে ফেরার বোতাম স্পর্শ করুন।</translation> <translation id="5284584623296338184">আপনার বুকমার্ক, ইতিহাস, পাসওয়ার্ড এবং অন্যান্য সেটিংসে করা পরিবর্তন আর আপনার Google অ্যাকাউন্টের সাথে সিঙ্ক করা হবে না। অবশ্য, আপনার বিদ্যমান ডেটা আপনার Google অ্যাকাউন্টে সঞ্চিত থাকবে।</translation> <translation id="5300589172476337783">দেখান</translation> @@ -660,7 +659,7 @@ <translation id="5962718611393537961">সঙ্কুচিত করতে আলতো চাপুন</translation> <translation id="5990142338020175451">ভাল পৃষ্ঠার সাজেশনের মতো আরও ব্যক্তিগত Google পরিষেবা</translation> <translation id="6000066717592683814">Google কে রাখুন</translation> -<translation id="6001839398155993679">চলুন যাই</translation> +<translation id="6001839398155993679">শুরু করা যাক</translation> <translation id="6005538289190791541">প্রস্তাবিত পাসওয়ার্ড</translation> <translation id="6039379616847168523">পরবর্তী ট্যাবে চলে যান</translation> <translation id="6040143037577758943">বন্ধ</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ca.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ca.xtb index fd9e43b2..9121418 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ca.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ca.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Tu o els teus pares podeu personalitzar la <ph name="BEGIN_LINK1" />configuració<ph name="END_LINK1" /> en qualsevol moment. Google pot utilitzar contingut dels llocs web que visites, així com l'activitat i les interaccions al navegador per personalitzar Chrome i els serveis de Google, com ara el Traductor, la Cerca i els anuncis.</translation> <translation id="2328985652426384049">No es pot iniciar la sessió</translation> <translation id="2342981853652716282">Inicia la sessió a Chrome per accedir a les teves adreces d'interès, les contrasenyes i altres continguts des de tots els teus dispositius.</translation> -<translation id="2343328333327081434">Instal·lant…</translation> <translation id="2349710944427398404">Dades totals utilitzades per Chrome, com ara comptes, adreces d'interès i opcions de configuració desades</translation> <translation id="2351097562818989364">S'ha restablert la configuració del Traductor.</translation> <translation id="2359808026110333948">Continua</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_cs.xtb b/chrome/android/java/strings/translations/android_chrome_strings_cs.xtb index 0ba33ae..d47a96b 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_cs.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_cs.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Nastavení<ph name="END_LINK1" /> lze kdykoliv upravit. Google může používat obsah na webech, které navštěvujete, interakce s prohlížečem a aktivity k personalizaci prohlížeče Chrome a služeb Google, jako jsou Překladač, Vyhledávání a reklamy.</translation> <translation id="2328985652426384049">Přihlášení se nezdařilo</translation> <translation id="2342981853652716282">Chcete-li mít své záložky, hesla a další obsah na všech zařízeních, přihlaste se do Chromu.</translation> -<translation id="2343328333327081434">Instalace…</translation> <translation id="2349710944427398404">Celkové množství dat využívané prohlížečem Chrome, včetně účtů, záložek a uložených nastavení</translation> <translation id="2351097562818989364">Nastavení překladů bylo resetováno.</translation> <translation id="2359808026110333948">Pokračovat</translation> @@ -221,6 +220,7 @@ <translation id="2586657967955657006">Schránka</translation> <translation id="2587052924345400782">Je dostupná novější verze</translation> <translation id="2593272815202181319">Neproporcionální</translation> +<translation id="2610239185026711824">Navrhnout heslo</translation> <translation id="2612676031748830579">Číslo karty</translation> <translation id="2621115761605608342">Povolit JavaScript pro konkrétní web.</translation> <translation id="2625189173221582860">Heslo bylo zkopírováno</translation> @@ -709,6 +709,7 @@ <translation id="6378173571450987352">Podrobnosti: Seřazeno podle množství využitých dat</translation> <translation id="6383961787135158834">Vymazat úložiště webů…</translation> <translation id="6388207532828177975">Vymazat a resetovat</translation> +<translation id="6393156038355142111">Navrhnout silné heslo</translation> <translation id="6393863479814692971">Chrome pro tento web potřebuje oprávnění k přístupu k fotoaparátu a mikrofonu.</translation> <translation id="6395288395575013217">ODKAZ</translation> <translation id="6404511346730675251">Upravit záložku</translation> @@ -890,6 +891,7 @@ <translation id="773466115871691567">Stránky v jazyce <ph name="SOURCE_LANGUAGE" /> vždy překládat</translation> <translation id="7735672056998735387"><ph name="SPACE_FREE" /> (<ph name="SPACE_OTHER" />)</translation> <translation id="773905249182896430">Chrání vás a vaše zařízení před nebezpečnými weby</translation> +<translation id="7759822418208302953">Ukončování asistenta automatického vyplňování</translation> <translation id="7762668264895820836">SD karta <ph name="SD_CARD_NUMBER" /></translation> <translation id="7764225426217299476">Přidat adresu</translation> <translation id="7765158879357617694">Přesunout</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_da.xtb b/chrome/android/java/strings/translations/android_chrome_strings_da.xtb index 8c041f6d..ef1cb1d 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_da.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_da.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Indstillinger<ph name="END_LINK1" /> kan tilpasses af dig eller dine forældre når som helst. Google kan bruge indholdet på de websites, du besøger, samt browserinteraktioner og -aktivitet til at tilpasse Chrome og Google-tjenester såsom Oversæt, Søgning og annoncer.</translation> <translation id="2328985652426384049">Det er ikke muligt at logge ind</translation> <translation id="2342981853652716282">Log ind på Chrome for at få dine bogmærker, adgangskoder og meget mere på alle dine enheder.</translation> -<translation id="2343328333327081434">Installerer…</translation> <translation id="2349710944427398404">Samlet mængde data, som Chrome anvender, herunder konti, bogmærker og gemte indstillinger</translation> <translation id="2351097562818989364">Dine oversættelsesindstillinger er nulstillet.</translation> <translation id="2359808026110333948">Fortsæt</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_de.xtb b/chrome/android/java/strings/translations/android_chrome_strings_de.xtb index 3043e71..e94858f 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_de.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_de.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Die <ph name="BEGIN_LINK1" />Einstellungen<ph name="END_LINK1" /> können von dir oder deinen Eltern jederzeit angepasst werden. Google kann die Inhalte der von dir besuchten Websites, Browserinteraktionen und Browseraktivitäten nutzen, um Chrome und andere Google-Dienste wie Google Übersetzer, die Google-Suche und Werbung zu personalisieren.</translation> <translation id="2328985652426384049">Anmeldung nicht möglich</translation> <translation id="2342981853652716282">Melden Sie sich in Chrome an, um Daten wie Lesezeichen und Passwörter auf allen Ihren Geräten zu nutzen.</translation> -<translation id="2343328333327081434">Wird installiert…</translation> <translation id="2349710944427398404">Gesamtdaten, die von Chrome verwendet werden, wie Konten, Lesezeichen und gespeicherte Einstellungen</translation> <translation id="2351097562818989364">Übersetzungseinstellungen zurückgesetzt</translation> <translation id="2359808026110333948">Weiter</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_el.xtb b/chrome/android/java/strings/translations/android_chrome_strings_el.xtb index c3b5d2c..7c6252f4 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_el.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_el.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Εσύ ή οι γονείς σου μπορείτε να προσαρμόσετε τις <ph name="BEGIN_LINK1" />Ρυθμίσεις<ph name="END_LINK1" /> ανά πάσα στιγμή. Η Google μπορεί να χρησιμοποιεί το περιεχόμενο σε ιστοτόπους που επισκέπτεσαι, αλληλεπιδράσεις με το πρόγραμμα περιήγησης και τη δραστηριότητά σου για να προσαρμόσει το Chrome και υπηρεσίες Google όπως η Μετάφραση, η Αναζήτηση και οι διαφημίσεις.</translation> <translation id="2328985652426384049">Δεν είναι δυνατή η σύνδεση</translation> <translation id="2342981853652716282">Συνδεθείτε στο Chrome, για να έχετε τους σελιδοδείκτες, τους κωδικούς πρόσβασης κ.ά. σε όλες τις συσκευές σας.</translation> -<translation id="2343328333327081434">Εγκατάσταση…</translation> <translation id="2349710944427398404">Σύνολο δεδομένων που χρησιμοποιούνται από το Chrome, συμπεριλαμβανομένων των λογαριασμών, των σελιδοδεικτών και των αποθηκευμένων ρυθμίσεων</translation> <translation id="2351097562818989364">Έγινε επαναφορά ρυθμίσεων μετάφρασης.</translation> <translation id="2359808026110333948">Συνέχεια</translation> @@ -221,6 +220,7 @@ <translation id="2586657967955657006">Πρόχειρο</translation> <translation id="2587052924345400782">Διατίθεται νεότερη έκδοση</translation> <translation id="2593272815202181319">Monospace</translation> +<translation id="2610239185026711824">Πρόταση κωδικού πρόσβασης</translation> <translation id="2612676031748830579">Αριθμός κάρτας</translation> <translation id="2621115761605608342">Να επιτρέπεται η JavaScript για έναν συγκεκριμένο ιστότοπο.</translation> <translation id="2625189173221582860">Ο κωδικός πρόσβασης αντιγράφηκε</translation> @@ -709,6 +709,7 @@ <translation id="6378173571450987352">Λεπτομέρειες: Ταξινομήθηκαν βάσει του όγκου των δεδομένων που χρησιμοποιήθηκαν</translation> <translation id="6383961787135158834">Διαγρ. αποθ. χώρ. ιστότ…</translation> <translation id="6388207532828177975">Διαγραφή και επαναφορά</translation> +<translation id="6393156038355142111">Πρόταση ισχυρού κωδικού πρόσβασης</translation> <translation id="6393863479814692971">Το Chrome χρειάζεται άδεια, για να αποκτήσει πρόσβαση στην κάμερα και το μικρόφωνο για αυτόν τον ιστότοπο.</translation> <translation id="6395288395575013217">ΣΥΝΔΕΣΜΟΣ</translation> <translation id="6404511346730675251">Επεξεργασία σελιδοδείκτη</translation> @@ -890,6 +891,7 @@ <translation id="773466115871691567">Να μεταφράζονται πάντα οι σελίδες προς τα <ph name="SOURCE_LANGUAGE" /></translation> <translation id="7735672056998735387"><ph name="SPACE_FREE" /> (<ph name="SPACE_OTHER" />)</translation> <translation id="773905249182896430">Προστατεύει εσάς και τη συσκευή σας από επικίνδυνους ιστοτόπους</translation> +<translation id="7759822418208302953">Διακοπή Βοηθού αυτόματης συμπλήρωσης</translation> <translation id="7762668264895820836">Κάρτα SD <ph name="SD_CARD_NUMBER" /></translation> <translation id="7764225426217299476">Προσθήκη διεύθυνσης</translation> <translation id="7765158879357617694">Μεταφορά</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_en-GB.xtb b/chrome/android/java/strings/translations/android_chrome_strings_en-GB.xtb index 61d6509..b74edbd 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_en-GB.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_en-GB.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised by you or your parents at any time. Google may use content on sites that you visit, as well as browsing activity and interactions, to personalise Chrome and Google services such as Translate, Search and ads.</translation> <translation id="2328985652426384049">Can’t sign in</translation> <translation id="2342981853652716282">Sign in to Chrome to get your bookmarks, passwords and more on all your devices.</translation> -<translation id="2343328333327081434">Installing…</translation> <translation id="2349710944427398404">Total data used by Chrome, including accounts, bookmarks and saved settings</translation> <translation id="2351097562818989364">Your translate settings have been reset.</translation> <translation id="2359808026110333948">Continue</translation> @@ -221,6 +220,7 @@ <translation id="2586657967955657006">Clipboard</translation> <translation id="2587052924345400782">Newer version is available</translation> <translation id="2593272815202181319">Monospace</translation> +<translation id="2610239185026711824">Suggest password</translation> <translation id="2612676031748830579">Card number</translation> <translation id="2621115761605608342">Allow JavaScript for a specific site.</translation> <translation id="2625189173221582860">Password copied</translation> @@ -709,6 +709,7 @@ <translation id="6378173571450987352">Details: Sorted by amount of data used</translation> <translation id="6383961787135158834">Clear Site Storage…</translation> <translation id="6388207532828177975">Clear & reset</translation> +<translation id="6393156038355142111">Suggest strong password</translation> <translation id="6393863479814692971">Chrome needs permission to access your camera and microphone for this site.</translation> <translation id="6395288395575013217">LINK</translation> <translation id="6404511346730675251">Edit bookmark</translation> @@ -890,6 +891,7 @@ <translation id="773466115871691567">Always translate pages in <ph name="SOURCE_LANGUAGE" /></translation> <translation id="7735672056998735387"><ph name="SPACE_FREE" /> (<ph name="SPACE_OTHER" />)</translation> <translation id="773905249182896430">Protects you and your device from dangerous sites</translation> +<translation id="7759822418208302953">Auto-fill Assistant stopping</translation> <translation id="7762668264895820836">SD Card <ph name="SD_CARD_NUMBER" /></translation> <translation id="7764225426217299476">Add address</translation> <translation id="7765158879357617694">Move</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_es-419.xtb b/chrome/android/java/strings/translations/android_chrome_strings_es-419.xtb index 91fc02f..8a7f6fd 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_es-419.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_es-419.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Tú o tus padres pueden modificar la <ph name="BEGIN_LINK1" />Configuración<ph name="END_LINK1" /> en cualquier momento. Es posible que usemos contenido de los sitios que visitas (así como tus interacciones y actividad de navegación) a fin de personalizar Chrome y otros servicios de Google, como el Traductor, la Búsqueda y los anuncios.</translation> <translation id="2328985652426384049">No puedes acceder</translation> <translation id="2342981853652716282">Accede a tu cuenta en Chrome para obtener tus favoritos, contraseñas y mucho más desde todos tus dispositivos.</translation> -<translation id="2343328333327081434">Instalando…</translation> <translation id="2349710944427398404">Cantidad total de datos que usa Chrome, lo que incluye las cuentas, favoritos y opciones de configuración guardadas</translation> <translation id="2351097562818989364">Se restableció la configuración de traducción.</translation> <translation id="2359808026110333948">Continuar</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_es.xtb b/chrome/android/java/strings/translations/android_chrome_strings_es.xtb index c74ecfc3..523924a 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_es.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_es.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Tú o tus padres podéis personalizar la <ph name="BEGIN_LINK1" />configuración<ph name="END_LINK1" /> en cualquier momento. Google puede utilizar el contenido de los sitios web que visites y la actividad e interacciones de navegación para personalizar Chrome y otros servicios de Google, como el Traductor, la Búsqueda y los anuncios.</translation> <translation id="2328985652426384049">No se puede iniciar sesión</translation> <translation id="2342981853652716282">Inicia sesión en Chrome para sincronizar los marcadores, las contraseñas y mucho más en todos tus dispositivos.</translation> -<translation id="2343328333327081434">Instalando…</translation> <translation id="2349710944427398404">Datos totales utilizados por Chrome, incluidos los marcadores, las cuentas y la configuración guardada</translation> <translation id="2351097562818989364">Se han restablecido tus ajustes de traducción.</translation> <translation id="2359808026110333948">Continuar</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_et.xtb b/chrome/android/java/strings/translations/android_chrome_strings_et.xtb index bc25b538..8be36ace 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_et.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_et.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Sina või su vanemad saavad <ph name="BEGIN_LINK1" />seadeid<ph name="END_LINK1" /> igal ajal kohandada. Google võib kasutada teie külastatavate saitide sisu, brauseri interaktsioone ja tegevusi Chrome'i ja Google'i teenuste, näiteks tõlke, otsingu ja reklaamide täiustamiseks.</translation> <translation id="2328985652426384049">Ei saa sisse logida</translation> <translation id="2342981853652716282">Logige Chrome'i sisse, et kõikides oma seadmetes kasutada järjehoidjaid, paroole ja muud.</translation> -<translation id="2343328333327081434">Installimine</translation> <translation id="2349710944427398404">Chrome'i kasutatav andmemaht kokku, sh kontod, järjehoidjad ja salvestatud seaded</translation> <translation id="2351097562818989364">Teie tõlkeseaded on lähtestatud.</translation> <translation id="2359808026110333948">Jätka</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_fa.xtb b/chrome/android/java/strings/translations/android_chrome_strings_fa.xtb index 6077a69..5a27fbc 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_fa.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_fa.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">شما یا والدینتان میتوانید در هرزمانی <ph name="BEGIN_LINK1" />تنظیمات<ph name="END_LINK1" /> را سفارشی کنید. ممکن است Google از محتوای موجود در سایتهایی که بازدید میکنید و تعاملات و فعالیت مرورگر برای شخصیسازی Chrome و سرویسهای Google (مانند «مترجم»، «جستجو» و آگهیها) استفاده کند.</translation> <translation id="2328985652426384049">ورود به سیستم امکانپذیر نیست</translation> <translation id="2342981853652716282">برای دریافت نشانکها، گذرواژهها و موارد دیگر در همه دستگاههایتان، به سیستم Chrome وارد شوید.</translation> -<translation id="2343328333327081434">در حال نصب…</translation> <translation id="2349710944427398404">کل دادههای استفادهشده توسط Chrome، شامل حسابها، نشانکها و تنظیمات ذخیرهشده</translation> <translation id="2351097562818989364">تنظیمات ترجمه شما بازنشانی شده است.</translation> <translation id="2359808026110333948">ادامه</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_fi.xtb b/chrome/android/java/strings/translations/android_chrome_strings_fi.xtb index a67ab80..4da78da 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_fi.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_fi.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Sinä tai huoltajasi voivat muuttaa <ph name="BEGIN_LINK1" />asetuksia<ph name="END_LINK1" /> milloin tahansa. Google saattaa käyttää käyttämiesi sivustojen sisältöä ja selaintoimintoja Chromen, Kääntäjän, Haun, mainosten ja muiden Google-palveluiden personointiin.</translation> <translation id="2328985652426384049">Kirjautuminen epäonnistui</translation> <translation id="2342981853652716282">Kirjaudu sisään Chromeen, jotta voit käyttää kirjanmerkkejäsi, salasanojasi ja muita asetuksiasi kaikilla laitteillasi.</translation> -<translation id="2343328333327081434">Asennetaan…</translation> <translation id="2349710944427398404">Chromen käyttämän tallennustilan kokonaismäärä, mukaan lukien tilit, kirjanmerkit ja tallennetut asetukset.</translation> <translation id="2351097562818989364">Käännösasetukset on nollattu.</translation> <translation id="2359808026110333948">Jatka</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_fil.xtb b/chrome/android/java/strings/translations/android_chrome_strings_fil.xtb index 536b355..b5a31ba9 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_fil.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_fil.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Mako-customize mo o ng iyong mga magulang ang <ph name="BEGIN_LINK1" />Mga Setting<ph name="END_LINK1" /> anumang oras. Maaaring gamitin ng Google ang content sa mga sites na binibisita mo, mga pakikipag-ugnayan at aktibidad sa browser para i-personalize ang Chrome at ang mga serbisyo ng Google tulad ng Translate, Search, at mga ad.</translation> <translation id="2328985652426384049">Hindi makapag-sign in</translation> <translation id="2342981853652716282">Mag-sign in sa Chrome upang makuha ang iyong mga bookmark, password, at higit pa sa lahat ng device mo.</translation> -<translation id="2343328333327081434">Ini-install…</translation> <translation id="2349710944427398404">Kabuuang data na ginagamit ng Chrome, kabilang ang mga account, bookmark at naka-save na setting</translation> <translation id="2351097562818989364">Na-reset ang iyong mga setting sa pag-translate.</translation> <translation id="2359808026110333948">Magpatuloy</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_fr.xtb b/chrome/android/java/strings/translations/android_chrome_strings_fr.xtb index a6534fb..43f41fd4 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_fr.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_fr.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Nous pouvons nous appuyer sur le contenu des sites que tu consultes, ainsi que sur tes activités de navigation et tes interactions avec le navigateur pour personnaliser Chrome, les annonces qui te sont proposées et d'autres de nos services comme Google Traduction et la recherche Google. Sache toutefois que tes parents ou toi pouvez personnaliser les <ph name="BEGIN_LINK1" />paramètres<ph name="END_LINK1" /> à tout moment.</translation> <translation id="2328985652426384049">Impossible de se connecter</translation> <translation id="2342981853652716282">Connectez-vous à Chrome pour accéder à vos favoris, mots de passe et bien plus sur tous vos appareils.</translation> -<translation id="2343328333327081434">Installation…</translation> <translation id="2349710944427398404">Espace de stockage utilisé pour l'ensemble des données Chrome, y compris les comptes, favoris et paramètres enregistrés</translation> <translation id="2351097562818989364">Les paramètres de traduction ont été réinitialisés.</translation> <translation id="2359808026110333948">Continuer</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_gu.xtb b/chrome/android/java/strings/translations/android_chrome_strings_gu.xtb index 2388f63..cdfa541e 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_gu.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_gu.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">તમે અથવા તમારા માતાપિતા <ph name="BEGIN_LINK1" />સેટિંગ<ph name="END_LINK1" />ને કોઈપણ સમયે કસ્ટમાઇઝ કરી શકો છે. Google તમે મુલાકાત લીધેલ સાઇટના કન્ટેન્ટનો તથા બ્રાઉઝિંગ ક્રિયાપ્રતિક્રિયા અને પ્રવૃત્તિનો ઉપયોગ Chrome અને Google સેવાઓ જેમ કે અનુવાદ, શોધ અને જાહેરાતોને વ્યક્તિગત બનાવવા માટે કરી શકે છે.</translation> <translation id="2328985652426384049">સાઇન ઇન કરી શકાતું નથી</translation> <translation id="2342981853652716282">તમારા બધા ઉપકરણો પર તમારા બુકમાર્ક, પાસવર્ડ અને બીજુ ઘણું મેળવવા માટે Chromeમાં સાઇન ઇન કરો.</translation> -<translation id="2343328333327081434">ઇન્સ્ટોલ કરે છે...</translation> <translation id="2349710944427398404">Chrome દ્વારા ઉપયોગમાં લેવાયેલ કુલ સ્ટોરેજ, એકાઉન્ટ્સ, બુકમાર્ક્સ અને સાચવેલ સેટિંગ્સ સહિત</translation> <translation id="2351097562818989364">તમારી અનુવાદ સેટિંગ્સ ફરીથી સેટ કરવામાં આવી છે.</translation> <translation id="2359808026110333948">ચાલુ રાખો</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_hi.xtb b/chrome/android/java/strings/translations/android_chrome_strings_hi.xtb index 64e1dba..e7adbc9 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_hi.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_hi.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />सेटिंग<ph name="END_LINK1" /> को आप या आपके अभिभावक कभी भी अपनी पसंद के मुताबिक बना सकते हैं. Chrome और अनुवाद, सर्च जैसी Google सेवाओं साथ ही विज्ञापनों को आपकी पसंद के मुताबिक आपको दिखाने के लिए Google उन साइटों की सामग्री जिन पर आप गए हैं, ब्राउज़र इंटरैक्शन और गतिविधि का इस्तेमाल कर सकता है.</translation> <translation id="2328985652426384049">साइन इन नहीं कर सकते</translation> <translation id="2342981853652716282">अपने सभी डिवाइस पर अपने बुकमार्क, पासवर्ड आदि पाने के लिए Chrome में प्रवेश करें.</translation> -<translation id="2343328333327081434">इंस्टॉल जारी...</translation> <translation id="2349710944427398404">Chrome द्वारा उपयोग किया गया कुल डेटा, जिसमें खाते, बुकमार्क और सहेजी गईं सेटिंग शामिल हैं</translation> <translation id="2351097562818989364">आपकी अनुवाद सेटिंग रीसेट कर दी गई हैं.</translation> <translation id="2359808026110333948">जारी रखें</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_hr.xtb b/chrome/android/java/strings/translations/android_chrome_strings_hr.xtb index 0c777a0..158b165 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_hr.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_hr.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Postavke<ph name="END_LINK1" /> možete prilagoditi u bilo kojem trenutku ili ih mogu prilagoditi vaši roditelji. Google može upotrebljavati sadržaj na web-lokacijama koje posjećujete, vaše interakcije u pregledniku i aktivnost pregledavanja kako bi prilagodio Chrome i Googleove usluge kao što su Prevoditelj, Pretraživanje i oglasi.</translation> <translation id="2328985652426384049">Prijava nije moguća</translation> <translation id="2342981853652716282">Prijavite se na Chrome kako biste mogli pristupati svojim oznakama, zaporkama i ostalom na svim svojim uređajima.</translation> -<translation id="2343328333327081434">Instaliranje…</translation> <translation id="2349710944427398404">Ukupna količina podataka koju Chrome upotrebljava, uključujući račune, oznake i spremljene postavke.</translation> <translation id="2351097562818989364">Vaše su postavke prevođenja vraćene na zadano.</translation> <translation id="2359808026110333948">Nastavi</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_hu.xtb b/chrome/android/java/strings/translations/android_chrome_strings_hu.xtb index 48b36c09..6e43a24f 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_hu.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_hu.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">A <ph name="BEGIN_LINK1" />Beállításokat<ph name="END_LINK1" /> bármikor személyre szabhatod, illetve ezt a szüleid is megtehetik. A Google felhasználhatja az általad felkeresett webhelyeken lévő tartalmakat, a böngészési interakciókat és tevékenységeket a Chrome és az egyéb Google-szolgáltatások (például a Fordító, a Keresés és a megjelenő hirdetések) személyre szabásához.</translation> <translation id="2328985652426384049">Nem sikerült a bejelentkezés</translation> <translation id="2342981853652716282">Jelentkezzen be a Chrome-ba, hogy az összes eszközén hozzáférhessen könyvjelzőihez, jelszavaihoz és más beállításaihoz.</translation> -<translation id="2343328333327081434">Telepítés…</translation> <translation id="2349710944427398404">A Chrome által használt teljes adatmennyiség, beleértve a fiókokat, könyvjelzőket és mentett beállításokat is</translation> <translation id="2351097562818989364">A fordítási beállítások visszaállítása megtörtént.</translation> <translation id="2359808026110333948">Folytatás</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_id.xtb b/chrome/android/java/strings/translations/android_chrome_strings_id.xtb index 4b75515c..3d45789e 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_id.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_id.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Setelan<ph name="END_LINK1" /> dapat disesuaikan oleh kamu atau orang tua kapan saja. Google dapat menggunakan konten di situs yang kamu buka, serta interaksi dan aktivitas browser untuk mempersonalisasi Chrome dan layanan Google seperti Terjemahan, Penelusuran, dan iklan.</translation> <translation id="2328985652426384049">Tidak dapat login</translation> <translation id="2342981853652716282">Login ke Chrome untuk mendapatkan bookmark, sandi, dan lainnya di semua perangkat Anda.</translation> -<translation id="2343328333327081434">Memasang...</translation> <translation id="2349710944427398404">Total data yang digunakan oleh Chrome, termasuk akun, bookmark, dan setelan yang tersimpan</translation> <translation id="2351097562818989364">Setelan terjemah telah disetel ulang.</translation> <translation id="2359808026110333948">Lanjut</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_it.xtb b/chrome/android/java/strings/translations/android_chrome_strings_it.xtb index e799b2f..84268542 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_it.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_it.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Le <ph name="BEGIN_LINK1" />impostazioni<ph name="END_LINK1" /> possono essere personalizzate da te o dai tuoi genitori in qualsiasi momento. Google potrebbe usare i contenuti dei siti che visiti, le attività e le interazioni con il browser per personalizzare Chrome e altri servizi Google come Traduttore, Ricerca e gli annunci.</translation> <translation id="2328985652426384049">Impossibile eseguire l'accesso</translation> <translation id="2342981853652716282">Accedi a Chrome per trovare i tuoi preferiti, le password e altre impostazioni su tutti i tuoi dispositivi.</translation> -<translation id="2343328333327081434">Installazione…</translation> <translation id="2349710944427398404">Dati totali utilizzati da Chrome, tra cui account, preferiti e impostazioni salvate</translation> <translation id="2351097562818989364">Le impostazioni di traduzione sono state reimpostate.</translation> <translation id="2359808026110333948">Continua</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_iw.xtb b/chrome/android/java/strings/translations/android_chrome_strings_iw.xtb index c980555..d798ed2 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_iw.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_iw.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">לך ולהורים שלך יש תמיד אפשרות להתאים אישית את <ph name="BEGIN_LINK1" />ההגדרות<ph name="END_LINK1" />. Google עשויה להשתמש בתוכן מאתרים שאליהם נכנסת, באינטראקציות בדפדפן ובפעילות גלישה כדי להתאים אישית את Chrome ואת שירותי Google, כמו Translate, החיפוש ומודעות.</translation> <translation id="2328985652426384049">אי אפשר להיכנס לחשבון</translation> <translation id="2342981853652716282">היכנס אל Chrome כדי לקבל גישה אל הסימניות, הסיסמאות ונתונים נוספים בכל המכשירים שלך.</translation> -<translation id="2343328333327081434">מתקין...</translation> <translation id="2349710944427398404">סך כל הנתונים שבהם משתמש Chrome, כולל חשבונות, סימניות והגדרות שמורות</translation> <translation id="2351097562818989364">הגדרות התרגום שלך אופסו.</translation> <translation id="2359808026110333948">המשך</translation> @@ -510,7 +509,7 @@ <translation id="4915549754973153784"><ph name="BEGIN_LINK" />קבל עזרה<ph name="END_LINK" /> בזמן חיפוש התקנים…</translation> <translation id="4943872375798546930">אין תוצאות</translation> <translation id="4958708863221495346"><ph name="URL_OF_THE_CURRENT_TAB" /> משתף את המסך שלך</translation> -<translation id="4961107849584082341">אפשר לתרגם את הדף הזה לכל שפה</translation> +<translation id="4961107849584082341">אפשר לתרגם את הדף הזה לשפה כלשהי</translation> <translation id="4961334780091921942">גישה אל הסיסמאות, ההיסטוריה ונתונים נוספים בכל המכשירים</translation> <translation id="4961700429721424617">אתה יוצא מחשבון המנוהל על-ידי <ph name="MANAGED_DOMAIN" />. פעולה זו תמחק את הנתונים שלך ב-Chrome מהמכשיר הזה, אבל הם יישארו בחשבון Google שלך.</translation> <translation id="497421865427891073">המשך קדימה</translation> @@ -616,7 +615,7 @@ <translation id="5684874026226664614">אופס. לא ניתן היה לתרגם את הדף הזה.</translation> <translation id="5686790454216892815">שם הקובץ ארוך מדי</translation> <translation id="5689516760719285838">מיקום</translation> -<translation id="569536719314091526">דרך לחצן האפשרויות הנוספות אפשר לתרגם את הדף הזה לכל שפה</translation> +<translation id="569536719314091526">דרך לחצן האפשרויות הנוספות אפשר לתרגם את הדף הזה לשפה כלשהי</translation> <translation id="5719837394786370183">דפים שאתה מציג בכרטיסיות גלישה בסתר לא יישמרו בהיסטוריית הדפדפן, אחסון קובצי ה-cookie או היסטוריית החיפושים לאחר שתסגור את כל הכרטיסיות של גלישה בסתר. קבצים שתוריד או סימניות שתיצור יישמרו. עם זאת, אינך בלתי נראה. מעבר למצב גלישה בסתר אינו מסתיר את הגלישה שלך מהמעסיק, ספק שירות האינטרנט או האתרים שבהם אתה מבקר.</translation> @@ -832,7 +831,7 @@ <translation id="7250468141469952378">נבחרו <ph name="ITEM_COUNT" /></translation> <translation id="7253272406652746122">הוסף חשבון Google מהדף 'חשבונות' שבאפליקציית ההגדרות של המכשיר.</translation> <translation id="7274013316676448362">אתר חסום</translation> -<translation id="728491846437309531">Google Assistant יכול לעזור לך לבצע באינטרנט דברים במהירות רבה יותר ובקלות רבה יותר</translation> +<translation id="728491846437309531">Google Assistant יכול לעזור לך לבצע דברים באינטרנט בצורה קלה ומהירה יותר</translation> <translation id="729975465115245577">אין במכשיר אפליקציה לאחסון קובץ הסיסמאות.</translation> <translation id="7302081693174882195">פרטים: מיון לפי נפח הנתונים שנחסכו</translation> <translation id="7333031090786104871">עדיין מוסיף את האתר הקודם</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ja.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ja.xtb index e1390f19..4e3d832 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ja.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ja.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />設定<ph name="END_LINK1" />は、ユーザー自身またはユーザーの保護者がいつでも変更できます。Google は、Chrome やその他の Google サービス(翻訳、検索、広告など)をカスタマイズする目的で、ユーザーがアクセスしたサイトのコンテンツ、ユーザーの閲覧行動や操作を使用することがあります。</translation> <translation id="2328985652426384049">ログインできません</translation> <translation id="2342981853652716282">Chrome にログインすれば、ブックマーク、パスワード、その他の設定をどの端末からでもご利用いただけます。</translation> -<translation id="2343328333327081434">インストール中...</translation> <translation id="2349710944427398404">Chrome が使用するデータ全体(アカウント、ブックマーク、保存済みの設定など)</translation> <translation id="2351097562818989364">翻訳設定をリセットしました。</translation> <translation id="2359808026110333948">続行</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_kn.xtb b/chrome/android/java/strings/translations/android_chrome_strings_kn.xtb index 334ece8..65d523b7 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_kn.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_kn.xtb
@@ -187,7 +187,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು<ph name="END_LINK1" /> ಯಾವ ಸಮಯದಲ್ಲಾದರೂ ನೀವು ಅಥವಾ ನಿಮ್ಮ ಪೋಷಕರು ಕಸ್ಟಮೈಸ್ ಮಾಡಬಹುದು. ಅನುವಾದ, ಹುಡುಕಾಟ ಮತ್ತು ಜಾಹೀರಾತುಗಳಂತಹ Google ಸೇವೆಗಳನ್ನು ಮತ್ತು Chrome ಅನ್ನು ವೈಯಕ್ತೀಕರಿಸಲು ನೀವು ಭೇಟಿ ನೀಡುವ ಸೈಟ್ಗಳಲ್ಲಿನ ವಿಷಯ, ಬ್ರೌಸರ್ನೊಂದಿಗಿನ ಸಂವಾದಗಳು ಹಾಗೂ ಚಟುವಟಿಕೆಗಳನ್ನು Google ಬಳಸಬಹುದು.</translation> <translation id="2328985652426384049">ಸೈನ್ ಇನ್ ಆಗಲು ಸಾಧ್ಯವಿಲ್ಲ</translation> <translation id="2342981853652716282">ನಿಮ್ಮ ಬುಕ್ಮಾರ್ಕ್ಗಳು, ಪಾಸ್ವರ್ಡ್ಗಳು ಮತ್ತು ಇನ್ನಷ್ಟನ್ನು ನಿಮ್ಮ ಎಲ್ಲಾ ಸಾಧನಗಳಲ್ಲಿ ಪಡೆದುಕೊಳ್ಳಲು Chrome ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ.</translation> -<translation id="2343328333327081434">ಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ...</translation> <translation id="2349710944427398404">ಖಾತೆಗಳು, ಬುಕ್ಮಾರ್ಕ್ಗಳು ಮತ್ತು ಉಳಿಸಿದ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಒಳಗೊಂಡಂತೆ Chrome ಬಳಸಿದ ಒಟ್ಟು ಡೇಟಾ</translation> <translation id="2351097562818989364">ನಿಮ್ಮ ಅನುವಾದ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಮರು ಹೊಂದಿಸಲಾಗಿದೆ.</translation> <translation id="2359808026110333948">ಮುಂದುವರಿಸು</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ko.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ko.xtb index 16ad23c..bff8f73 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ko.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ko.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">언제든지 나 또는 부모님이 <ph name="BEGIN_LINK1" />설정<ph name="END_LINK1" />을 변경할 수 있습니다. Google에서 Chrome 및 번역, 검색과 같은 기타 Google 서비스, 광고를 맞춤설정하기 위해 사용자가 방문한 사이트의 콘텐츠, 탐색 활동, 상호작용 기록을 사용할 수 있습니다.</translation> <translation id="2328985652426384049">로그인할 수 없음</translation> <translation id="2342981853652716282">Chrome에 로그인하여 모든 기기에서 내 북마크, 비밀번호 등을 사용하세요.</translation> -<translation id="2343328333327081434">설치 중...</translation> <translation id="2349710944427398404">계정, 북마크, 저장된 설정 등 Chrome에서 사용한 전체 데이터</translation> <translation id="2351097562818989364">번역 설정이 재설정되었습니다.</translation> <translation id="2359808026110333948">계속</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_lt.xtb b/chrome/android/java/strings/translations/android_chrome_strings_lt.xtb index aa76965..20e2386 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_lt.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_lt.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Nustatymus<ph name="END_LINK1" /> jūs arba jūsų tėvai galite tinkinti bet kuriuo metu. „Google“ gali naudoti jūsų lankomų svetainių turinį, naršyklės sąveikas ir veiklą suasmenindama „Chrome“ ir kitas „Google“ paslaugas, pvz., Vertėją, Paiešką ir skelbimus.</translation> <translation id="2328985652426384049">Nepavyksta prisijungti</translation> <translation id="2342981853652716282">Prisijunkite prie „Chrome“, kad galėtumėte naudoti žymes, slaptažodžius ir kitus nustatymus visuose įrenginiuose.</translation> -<translation id="2343328333327081434">Diegiama...</translation> <translation id="2349710944427398404">Bendras „Chrome“ naudojamų duomenų kiekis, įskaitant paskyras, žymes ir išsaugotus nustatymus</translation> <translation id="2351097562818989364">Vertimo nustatymai buvo nustatyti iš naujo.</translation> <translation id="2359808026110333948">Tęsti</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_lv.xtb b/chrome/android/java/strings/translations/android_chrome_strings_lv.xtb index 5fc61c56..b6f98c1 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_lv.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_lv.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Jūs vai jūsu vecāki jebkurā laikā var mainīt <ph name="BEGIN_LINK1" />iestatījumus<ph name="END_LINK1" />. Google var izmantot jūsu apmeklēto vietņu saturu, pārlūkā veiktās mijiedarbības un darbības, lai personalizētu pārlūku Chrome un tādus Google pakalpojumus kā Tulkotājs, Meklēšana un reklāmas.</translation> <translation id="2328985652426384049">Nevar pierakstīties</translation> <translation id="2342981853652716282">Pierakstieties pārlūkā Chrome, lai iegūtu savas grāmatzīmes, paroles un citu saturu visās savās ierīcēs.</translation> -<translation id="2343328333327081434">Instalēšana...</translation> <translation id="2349710944427398404">Kopējais pārlūkā Chrome izmantoto datu apjoms, ieskaitot kontus, grāmatzīmes un saglabātos iestatījumus</translation> <translation id="2351097562818989364">Tulkošanas iestatījumi ir atiestatīti.</translation> <translation id="2359808026110333948">Turpināt</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ml.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ml.xtb index a5b79c6..46594cd0 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ml.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ml.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">നിങ്ങൾക്കോ നിങ്ങളുടെ രക്ഷിതാക്കൾക്കോ ഏത് സമയത്തും <ph name="BEGIN_LINK1" />ക്രമീകരണം<ph name="END_LINK1" /> ഇഷ്ടാനുസൃതമാക്കാം. Translate, തിരയൽ, പരസ്യങ്ങൾ പോലുള്ള Google സേവനങ്ങൾ വ്യക്തിപരമാക്കാൻ, Chrome നിങ്ങൾ സന്ദർശിക്കുന്ന സൈറ്റുകളിലെ ഉള്ളടക്കം, ബ്രൗസർ ഇടപെടലുകൾ, ആക്റ്റിവിറ്റി എന്നിവ Google ഉപയോഗിച്ചേക്കാം.</translation> <translation id="2328985652426384049">സൈൻ ഇൻ ചെയ്യാനാകില്ല</translation> <translation id="2342981853652716282">നിങ്ങളുടെ ബുക്ക്മാർക്കുകളും പാസ്വേഡുകളും മറ്റും എല്ലാ ഉപകരണങ്ങളിലും ലഭ്യമാക്കുന്നതിന് Chrome-ൽ സൈൻ ഇൻ ചെയ്യുക.</translation> -<translation id="2343328333327081434">ഇൻസ്റ്റാളുചെയ്യുന്നു...</translation> <translation id="2349710944427398404">അക്കൗണ്ടുകളും ബുക്ക്മാർക്കുകളും സംരക്ഷിച്ച ക്രമീകരണവും ഉൾപ്പെടെ Chrome ഉപയോഗിക്കുന്ന മൊത്തം വിവരങ്ങൾ</translation> <translation id="2351097562818989364">നിങ്ങളുടെ വിവർത്തന ക്രമീകരണം റീസെറ്റുചെയ്തു.</translation> <translation id="2359808026110333948">തുടരൂ</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_mr.xtb b/chrome/android/java/strings/translations/android_chrome_strings_mr.xtb index 8bc3db24..7bcd1e4 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_mr.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_mr.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">तुम्ही किंवा तुमचे पालक कधीही <ph name="BEGIN_LINK1" />सेटिंग्ज<ph name="END_LINK1" /> कस्टमाइझ करू शकता. Chrome आणि भाषांतर, शोध आणि जाहिरातींसारख्या Google सेवा पर्सनलाइझ करण्यासाठी Google तुम्ही भेट देत असलेल्या साइटवरील आशय, ब्राउझर परस्परसंवाद आणि अॅक्टिव्हिटी वापरू शकते.</translation> <translation id="2328985652426384049">साइन इन करू शकत नाही</translation> <translation id="2342981853652716282">तुमच्या सर्व डिव्हाइसवर तुमचे बुकमार्क, पासवर्ड आणि अधिक मिळवण्यासाठी Chromeमध्ये साइन इन करा.</translation> -<translation id="2343328333327081434">इंस्टॉल करीत आहे...</translation> <translation id="2349710944427398404">खाती, बुकमार्क आणि सेव्ह केलेल्या सेटिंग्जसह, Chrome ने वापरलेला एकूण डेटा</translation> <translation id="2351097562818989364">आपल्या भाषांतर सेटिंग्ज रीसेट करण्यात आल्या आहेत.</translation> <translation id="2359808026110333948">सुरू ठेवा</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ms.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ms.xtb index bc02421..8eca43da 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ms.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ms.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Tetapan<ph name="END_LINK1" /> boleh disesuaikan oleh anda atau ibu bapa anda pada bila-bila masa. Google boleh menggunakan kandungan di tapak yang anda lawati, interaksi dan aktiviti penyemak imbas untuk memperibadikan Chrome dan perkhidmatan Google seperti Terjemahan, Carian dan iklan.</translation> <translation id="2328985652426384049">Tidak dapat log masuk</translation> <translation id="2342981853652716282">Log masuk ke Chrome untuk mendapatkan penanda halaman, kata laluan anda dan pelbagai lagi pada semua peranti anda.</translation> -<translation id="2343328333327081434">Memasang...</translation> <translation id="2349710944427398404">Jumlah data yang digunakan oleh Chrome, termasuk akaun, penanda halaman dan tetapan yang disimpan</translation> <translation id="2351097562818989364">Tetapan terjemahan anda telah ditetapkan semula.</translation> <translation id="2359808026110333948">Teruskan</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_nl.xtb b/chrome/android/java/strings/translations/android_chrome_strings_nl.xtb index b883941..13ff3d66 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_nl.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_nl.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">De <ph name="BEGIN_LINK1" />instellingen<ph name="END_LINK1" /> kunnen op elk gewenst moment door jou of je ouders worden aangepast. Google kan content op sites die je bezoekt en je browseractiviteit en interacties gebruiken om Chrome en andere Google-services (zoals Translate, Zoeken en advertenties) te personaliseren.</translation> <translation id="2328985652426384049">Kan niet inloggen</translation> <translation id="2342981853652716282">Log in bij Chrome om je bladwijzers, wachtwoorden en meer op al je apparaten op te halen.</translation> -<translation id="2343328333327081434">Installeren…</translation> <translation id="2349710944427398404">Totale gegevens gebruikt door Chrome, inclusief accounts, bladwijzers en opgeslagen instellingen</translation> <translation id="2351097562818989364">Je vertaalinstellingen zijn opnieuw ingesteld.</translation> <translation id="2359808026110333948">Doorgaan</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_no.xtb b/chrome/android/java/strings/translations/android_chrome_strings_no.xtb index 491b3ff..dac12a0d 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_no.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_no.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Du kan tilpasse <ph name="BEGIN_LINK1" />innstillingene<ph name="END_LINK1" /> når som helst. Google kan bruke innhold på nettsteder du besøker, nettleserinteraksjoner og annen aktivitet for å gi Chrome og Google-tjenester (som Oversetter, Søk og annonser) et personlig preg.</translation> <translation id="2328985652426384049">Kan ikke logge på</translation> <translation id="2342981853652716282">Logg på Chrome for å hente blant annet bokmerkene og passordene dine på alle enhetene du bruker.</translation> -<translation id="2343328333327081434">Installerer …</translation> <translation id="2349710944427398404">Total datamengde som brukes av Chrome, deriblant kontoer, bokmerker og lagrede innstillinger</translation> <translation id="2351097562818989364">Oversettelsesinnstillingene dine er tilbakestilt.</translation> <translation id="2359808026110333948">Fortsett</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_pl.xtb b/chrome/android/java/strings/translations/android_chrome_strings_pl.xtb index a592015..534f4ac 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_pl.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_pl.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Ustawienia<ph name="END_LINK1" /> możesz zmienić w dowolnym momencie, mogą je też zmienić Twoi rodzice. Google może używać zawartości niektórych odwiedzanych przez Ciebie stron oraz informacji o Twojej aktywności i interakcjach w przeglądarce, by personalizować Chrome i inne usługi Google takie jak Tłumacz, wyszukiwarka czy reklamy.</translation> <translation id="2328985652426384049">Nie można się zalogować</translation> <translation id="2342981853652716282">Zaloguj się w Chrome, by mieć dostęp do swoich zakładek, haseł i innych ustawień na wszystkich swoich urządzeniach.</translation> -<translation id="2343328333327081434">Instaluję…</translation> <translation id="2349710944427398404">Łączna ilość danych używanych przez Chrome, w tym konta, zakładki i zapisane ustawienia</translation> <translation id="2351097562818989364">Ustawienia tłumaczenia zostały zresetowane.</translation> <translation id="2359808026110333948">Dalej</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_pt-BR.xtb b/chrome/android/java/strings/translations/android_chrome_strings_pt-BR.xtb index a89db52..1e3d98c 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_pt-BR.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_pt-BR.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">As <ph name="BEGIN_LINK1" />configurações<ph name="END_LINK1" /> podem ser personalizadas por você ou seus pais a qualquer momento. O Google pode usar o conteúdo dos sites que você visita, as interações do navegador e as atividades para personalizar o Chrome e os serviços do Google, como o Tradutor, a Pesquisa e os anúncios.</translation> <translation id="2328985652426384049">Não consigo fazer login</translation> <translation id="2342981853652716282">Faça login no Chrome para ver seus favoritos, senhas e muito mais em todos os seus dispositivos.</translation> -<translation id="2343328333327081434">Instalando...</translation> <translation id="2349710944427398404">Total de dados utilizados pelo Chrome, incluindo contas, favoritos e configurações salvas</translation> <translation id="2351097562818989364">As configurações de tradução foram redefinidas.</translation> <translation id="2359808026110333948">Continuar</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_pt-PT.xtb b/chrome/android/java/strings/translations/android_chrome_strings_pt-PT.xtb index 6ecaca4..d47ac222a 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_pt-PT.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_pt-PT.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Tu ou os teus pais podem personalizar as <ph name="BEGIN_LINK1" />Definições<ph name="END_LINK1" /> em qualquer altura. A Google pode utilizar conteúdos nos sites que visitas, assim como as interações e a atividade com o navegador, para personalizar o Chrome e outros serviços Google, como o Tradutor, a Pesquisa e os anúncios.</translation> <translation id="2328985652426384049">Não é possível iniciar sessão</translation> <translation id="2342981853652716282">Inicie sessão no Chrome para obter os seus marcadores, palavras-passe e muito mais em todos os dispositivos.</translation> -<translation id="2343328333327081434">A instalar...</translation> <translation id="2349710944427398404">Total de dados utilizados pelo Chrome, incluindo contas, marcadores e definições guardadas</translation> <translation id="2351097562818989364">As definições de tradução foram repostas.</translation> <translation id="2359808026110333948">Continuar</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ro.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ro.xtb index fa38480..e9c49784 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ro.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ro.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Setările<ph name="END_LINK1" /> pot fi personalizate de tine sau de părinții tăi oricând. Google poate folosi conținutul de pe site-urile pe care le accesezi, interacțiunile cu browserul și activitatea pentru a personaliza Chrome și servicii Google precum Traducere, Căutare și anunțuri.</translation> <translation id="2328985652426384049">Nu se poate conecta</translation> <translation id="2342981853652716282">Conectează-te la Chrome pentru a accesa marcajele, parolele și altele pe toate dispozitivele tale.</translation> -<translation id="2343328333327081434">Se instalează…</translation> <translation id="2349710944427398404">Totalul datelor folosite de Chrome, inclusiv conturile, marcajele și setările salvate</translation> <translation id="2351097562818989364">Setările de traducere au fost resetate.</translation> <translation id="2359808026110333948">Continuă</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ru.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ru.xtb index 890eb0a..ebd7c3ce 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ru.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ru.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Для персонализации рекламы, Chrome и таких сервисов Google, как Переводчик и Поиск, могут использоваться данные с сайтов, которые вы посещаете, а также история просмотров и действий в браузере. Вы можете изменить <ph name="BEGIN_LINK1" />настройки<ph name="END_LINK1" /> в любой момент или попросить родителей сделать это.</translation> <translation id="2328985652426384049">Не удается войти</translation> <translation id="2342981853652716282">Войдите в Chrome, чтобы синхронизировать закладки, пароли и другую информацию на всех ваших устройствах.</translation> -<translation id="2343328333327081434">Установка…</translation> <translation id="2349710944427398404">Общее количество данных Chrome, включая аккаунты, закладки и сохраненные настройки</translation> <translation id="2351097562818989364">Настройки перевода сброшены</translation> <translation id="2359808026110333948">Далее</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_sk.xtb b/chrome/android/java/strings/translations/android_chrome_strings_sk.xtb index 6653d288..9ff8fd7e 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_sk.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_sk.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Nastavenia<ph name="END_LINK1" /> môžeš ty alebo tvoji rodičia kedykoľvek prispôsobiť. Google môže použiť obsah na weboch, ktoré navštíviš, interakcie a aktivitu v prehliadači na prispôsobenie Chromu a služieb Googlu, ako sú Prekladač, Vyhľadávanie a reklamy.</translation> <translation id="2328985652426384049">Nedá sa prihlásiť</translation> <translation id="2342981853652716282">Prihláste sa do Chromu a získajte svoje záložky, heslá a ďalšie nastavenia na všetkých zariadeniach.</translation> -<translation id="2343328333327081434">Inštaluje sa…</translation> <translation id="2349710944427398404">Celkové dáta využívané Chromom vrátane účtov, záložiek a uložených nastavení</translation> <translation id="2351097562818989364">Nastavenia prekladov boli resetované.</translation> <translation id="2359808026110333948">Pokračovať</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_sl.xtb b/chrome/android/java/strings/translations/android_chrome_strings_sl.xtb index b81336c..da2f9fe 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_sl.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_sl.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Nastavitve<ph name="END_LINK1" /> lahko ti ali tvoji starši kadar koli prilagodite. Google lahko vsebino na spletnih mestih, ki jih obiščeš, interakcije z brskalnikom in dejavnost v brskalniku uporabi za prilagajanje Chroma in Googlovih storitev, kot so Prevajalnik, Iskanje Google in oglasi.</translation> <translation id="2328985652426384049">Ne morem se prijaviti</translation> <translation id="2342981853652716282">Prijavite se v Chrome, če želite dostopati do svojih zaznamkov, gesel in drugega v vseh napravah.</translation> -<translation id="2343328333327081434">Nameščanje ...</translation> <translation id="2349710944427398404">Skupna količina podatkov, ki jih uporablja Chrome, vključno z računi, zaznamki in shranjenimi nastavitvami.</translation> <translation id="2351097562818989364">Nastavitve za prevajanje so ponastavljene.</translation> <translation id="2359808026110333948">Nadaljuj</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_sr.xtb b/chrome/android/java/strings/translations/android_chrome_strings_sr.xtb index c089157..c37f48e 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_sr.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_sr.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Подешавања<ph name="END_LINK1" /> увек можеш да прилагодиш ти или родитељи. Google може да користи садржај на сајтовима које посећујеш, интеракције са прегледачима и активности у њима да би персонализовао Chrome и Google услуге као што су Преводилац, Претрага и огласи.</translation> <translation id="2328985652426384049">Не могу да се пријавим</translation> <translation id="2342981853652716282">Пријавите се у Chrome да би вам обележивачи, лозинке и други садржај били доступни на свим уређајима.</translation> -<translation id="2343328333327081434">Инсталира се...</translation> <translation id="2349710944427398404">Сви подаци које користи Chrome, укључујући налоге, обележиваче и сачувана подешавања</translation> <translation id="2351097562818989364">Подешавања за превођење су ресетована.</translation> <translation id="2359808026110333948">Настави</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_sv.xtb b/chrome/android/java/strings/translations/android_chrome_strings_sv.xtb index bcf10aa..4d28b4f0 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_sv.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_sv.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Inställningarna<ph name="END_LINK1" /> kan anpassas av dig eller dina föräldrar när som helst. Google kan anpassa Chrome och tjänster från Google som Översätt, Sök och annonser utifrån innehållet på webbplatser du besöker, vad du interagerar med i webbläsaren och annan aktivitet.</translation> <translation id="2328985652426384049">Det gick inte att logga in</translation> <translation id="2342981853652716282">Logga in i Chrome om du vill få dina bokmärken, lösenord med mera på alla dina enheter.</translation> -<translation id="2343328333327081434">Installerar …</translation> <translation id="2349710944427398404">Total data som används av Chrome, inklusive konton, bokmärken och sparade inställningar</translation> <translation id="2351097562818989364">Översättningsinställningarna har återställts.</translation> <translation id="2359808026110333948">Fortsätt</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_sw.xtb b/chrome/android/java/strings/translations/android_chrome_strings_sw.xtb index 2624455..668e48b 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_sw.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_sw.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Wewe au wazazi wako wanaweza kubadilisha <ph name="BEGIN_LINK1" />Mipangilio<ph name="END_LINK1" /> wakati wowote. Google inaweza kutumia maudhui kwenye tovuti unazotembelea, matumizi ya kivinjari na shughuli za kuweka mapendeleo kwenye huduma za Chrome na Google kama vile Tafsiri, Tafuta na Google na matangazo</translation> <translation id="2328985652426384049">Imeshindwa kuingia katika akaunti</translation> <translation id="2342981853652716282">Ingia katika Chrome ili upate alamisho, manenosiri yako na mengine mengi kwenye vifaa vyako vyote.</translation> -<translation id="2343328333327081434">Inasakinisha...</translation> <translation id="2349710944427398404">Jumla ya data iliyotumiwa na Chrome, ikiwa ni pamoja na akaunti, alamisho na mipangilio iliyohifadhiwa</translation> <translation id="2351097562818989364">Mipangilio yako ya kutafsiri imewekwa upya.</translation> <translation id="2359808026110333948">Endelea</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ta.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ta.xtb index bac6929..03b001b 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_ta.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_ta.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">எப்போது வேண்டுமானாலும் நீங்கள் அல்லது உங்கள் பெற்றோர், <ph name="BEGIN_LINK1" />அமைப்புகளைத்<ph name="END_LINK1" /> தனிப்பயனாக்கலாம். Chrome, மொழியாக்கம், தேடல், விளம்பரங்கள் போன்ற Google சேவைகளைத் தனிப்பயனாக்க, நீங்கள் பார்வையிடும் தளங்களில் உள்ள உள்ளடக்கம், உலாவி உரையாடல்கள், மேற்கொள்ளும் செயல்பாடு ஆகியவற்றை Google பயன்படுத்தக்கூடும்.</translation> <translation id="2328985652426384049">உள்நுழைய முடியவில்லை</translation> <translation id="2342981853652716282">உங்கள் எல்லாச் சாதனங்களிலும் உங்கள் புத்தகக்குறிகள், கடவுச்சொற்கள் மற்றும் பலவற்றைப் பெற, Chrome இல் உள்நுழையவும்.</translation> -<translation id="2343328333327081434">நிறுவுகிறது...</translation> <translation id="2349710944427398404">கணக்குகள், புத்தகக்குறிகள், சேமித்த அமைப்புகள் உள்பட Chrome பயன்படுத்தும் மொத்தத் தரவு</translation> <translation id="2351097562818989364">உங்களின் மொழியாக்க அமைப்புகள் மீட்டமைக்கப்பட்டன.</translation> <translation id="2359808026110333948">தொடர்க</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_te.xtb b/chrome/android/java/strings/translations/android_chrome_strings_te.xtb index c59123b..8ded3fb 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_te.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_te.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281"><ph name="BEGIN_LINK1" />సెట్టింగ్లను<ph name="END_LINK1" /> మీరు లేదా మీ తల్లిదండ్రులు ఎప్పుడైనా అనుకూలీకరించవచ్చు. Google మీరు సందర్శించే సైట్ల్లోని కంటెంట్, బ్రౌజర్ పరస్పర చర్యలు మరియు కార్యకలాపం ఉపయోగించడం ద్వారా Chromeని మరియు అనువాదం, శోధన మరియు ప్రకటనలు వంటి Google సేవలను వ్యక్తిగతీకరించవచ్చు.</translation> <translation id="2328985652426384049">సైన్ ఇన్ చేయడం సాధ్యపడదు</translation> <translation id="2342981853652716282">మీ పరికరాలన్నింటిలో మీ బుక్మార్క్లు, పాస్వర్డ్లు మరియు మరిన్నింటిని పొందడం కోసం Chromeకు సైన్ ఇన్ చేయండి.</translation> -<translation id="2343328333327081434">ఇన్స్టాల్ చేస్తోంది…</translation> <translation id="2349710944427398404">ఖాతాలు, బుక్మార్క్లు మరియు సేవ్ చేసిన సెట్టింగ్లతో సహా Chrome ద్వారా ఉపయోగించబడిన మొత్తం డేటా</translation> <translation id="2351097562818989364">మీ అనువాద సెట్టింగ్లు రీసెట్ చేయబడ్డాయి.</translation> <translation id="2359808026110333948">కొనసాగు</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_th.xtb b/chrome/android/java/strings/translations/android_chrome_strings_th.xtb index de01259..b18069f4 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_th.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_th.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">คุณหรือผู้ปกครองปรับแต่ง<ph name="BEGIN_LINK1" />การตั้งค่า<ph name="END_LINK1" />ได้ทุกเมื่อ Google อาจใช้เนื้อหาในเว็บไซต์ที่คุณเข้าชม รวมถึงการโต้ตอบและกิจกรรมในเบราว์เซอร์เพื่อปรับ Chrome และบริการของ Google อย่างเช่น แปลภาษา, Search และโฆษณาให้เหมาะกับคุณ</translation> <translation id="2328985652426384049">ลงชื่อเข้าใช้ไม่ได้</translation> <translation id="2342981853652716282">ลงชื่อเข้าใช้ Chrome เพื่อรับบุ๊กมาร์ก รหัสผ่าน และข้อมูลอื่นๆ ในอุปกรณ์ทุกเครื่องของคุณ</translation> -<translation id="2343328333327081434">กำลังติดตั้ง…</translation> <translation id="2349710944427398404">ข้อมูลทั้งหมดที่ Chrome ใช้ รวมถึงบัญชี บุ๊กมาร์ก และการตั้งค่าที่บันทึกไว้</translation> <translation id="2351097562818989364">รีเซ็ตการตั้งค่าการแปลภาษาของคุณแล้ว</translation> <translation id="2359808026110333948">ดำเนินการต่อ</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_tr.xtb b/chrome/android/java/strings/translations/android_chrome_strings_tr.xtb index 31008fa..6039ee3 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_tr.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_tr.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Siz veya ebeveynleriniz <ph name="BEGIN_LINK1" />Ayarlar<ph name="END_LINK1" />'ı istediğiniz zaman özelleştirebilirsiniz. Chrome'u ve diğer Google hizmetlerini (Çeviri, Arama, reklamlar gibi) kişiselleştirmek için Google, ziyaret ettiğiniz sitelerdeki içeriği, tarayıcı etkileşimlerini ve etkinlikleri kullanabilir.</translation> <translation id="2328985652426384049">Oturum açılamıyor</translation> <translation id="2342981853652716282">Tüm cihazlarınızda yer işaretlerinizi, şifrelerinizi almak ve daha pek çok şey yapmak için Chrome'da oturum açın.</translation> -<translation id="2343328333327081434">Yükleniyor…</translation> <translation id="2349710944427398404">Hesaplar, yer işaretleri ve kayıtlı ayarlar da dahil olmak üzere Chrome tarafından kullanılan tüm veriler</translation> <translation id="2351097562818989364">Çeviri ayarlarınız sıfırlandı.</translation> <translation id="2359808026110333948">Devam Et</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_uk.xtb b/chrome/android/java/strings/translations/android_chrome_strings_uk.xtb index 6daf1d26..f70cfea 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_uk.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_uk.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Ви або ваші батьки можете будь-коли змінювати <ph name="BEGIN_LINK1" />налаштування<ph name="END_LINK1" />. Google може використовувати вміст відвіданих сайтів, дані веб-перегляду й інші дії, щоб персоналізувати Chrome та сервіси Google, як-от Перекладач, Пошук і оголошення.</translation> <translation id="2328985652426384049">Не вдається ввійти</translation> <translation id="2342981853652716282">Увійдіть в обліковий запис у Chrome, щоб мати доступ до своїх закладок, паролів та інших даних на всіх пристроях.</translation> -<translation id="2343328333327081434">Встановлення…</translation> <translation id="2349710944427398404">Усі дані, які використовує Chrome, зокрема облікові записи, закладки та збережені налаштування</translation> <translation id="2351097562818989364">Налаштування перекладу скинуто.</translation> <translation id="2359808026110333948">Продовжити</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_vi.xtb b/chrome/android/java/strings/translations/android_chrome_strings_vi.xtb index 5020ff98..1793a23 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_vi.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_vi.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">Bạn hoặc cha mẹ bạn có thể tùy chỉnh mục <ph name="BEGIN_LINK1" />Cài đặt<ph name="END_LINK1" /> bất cứ lúc nào. Google có thể sử dụng nội dung trên các trang web bạn truy cập, hoạt động và các tương tác trên trình duyệt để cá nhân hóa Chrome và các dịch vụ của Google, chẳng hạn như Dịch, Tìm kiếm và quảng cáo.</translation> <translation id="2328985652426384049">Không thể đăng nhập</translation> <translation id="2342981853652716282">Đăng nhập vào Chrome để nhận dấu trang, mật khẩu và nhiều nội dung khác trên tất cả các thiết bị của bạn.</translation> -<translation id="2343328333327081434">Đang cài đặt…</translation> <translation id="2349710944427398404">Tổng số dữ liệu mà Chrome sử dụng, bao gồm tài khoản, dấu trang và cài đặt đã lưu</translation> <translation id="2351097562818989364">Đã đặt lại cài đặt dịch của bạn.</translation> <translation id="2359808026110333948">Tiếp tục</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_zh-CN.xtb b/chrome/android/java/strings/translations/android_chrome_strings_zh-CN.xtb index 5eb279b..310346f 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_zh-CN.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_zh-CN.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">您或您的父母随时可以自定义<ph name="BEGIN_LINK1" />设置<ph name="END_LINK1" />。Google 可能会根据您访问的网站上的内容、您在浏览器中的互动行为和活动,为您提供个性化的 Chrome 体验和其他 Google 服务体验(例如翻译、搜索和广告)。</translation> <translation id="2328985652426384049">无法登录</translation> <translation id="2342981853652716282">登录 Chrome 即可将您的书签、密码等同步到您的所有设备上。</translation> -<translation id="2343328333327081434">正在安装…</translation> <translation id="2349710944427398404">Chrome 所使用的数据总量,包括帐号、书签和已保存的设置</translation> <translation id="2351097562818989364">您的翻译设置已重置。</translation> <translation id="2359808026110333948">继续</translation>
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_zh-TW.xtb b/chrome/android/java/strings/translations/android_chrome_strings_zh-TW.xtb index cf838b6..585ef0c 100644 --- a/chrome/android/java/strings/translations/android_chrome_strings_zh-TW.xtb +++ b/chrome/android/java/strings/translations/android_chrome_strings_zh-TW.xtb
@@ -186,7 +186,6 @@ <translation id="2325181368089033281">你或你的父母隨時可調整<ph name="BEGIN_LINK1" />設定<ph name="END_LINK1" />。Google 可能會根據你所造訪網站的內容、瀏覽器互動行為和瀏覽活動,提供個人化的 Chrome 體驗和 Google 服務體驗,例如翻譯、搜尋和廣告。</translation> <translation id="2328985652426384049">無法登入</translation> <translation id="2342981853652716282">無論使用任何裝置,只要登入 Chrome,即可取得你的書籤、密碼,並沿用其他設定。</translation> -<translation id="2343328333327081434">安裝中…</translation> <translation id="2349710944427398404">Chrome 使用的資料總量,包括帳戶、書籤和儲存的設定</translation> <translation id="2351097562818989364">您的翻譯設定已重設。</translation> <translation id="2359808026110333948">繼續</translation>
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 6b3bced1..5391a5ec 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -50,7 +50,6 @@ "java/src/org/chromium/chrome/browser/IntentHelper.java", "java/src/org/chromium/chrome/browser/IntentHeadersRecorder.java", "java/src/org/chromium/chrome/browser/ItemChooserDialog.java", - "java/src/org/chromium/chrome/browser/JavascriptAppModalDialog.java", "java/src/org/chromium/chrome/browser/KeyboardShortcuts.java", "java/src/org/chromium/chrome/browser/DelayedScreenLockIntentHandler.java", "java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java", @@ -120,7 +119,7 @@ "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingCoordinator.java", "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardExtensionSizeManager.java", "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingMediator.java", - "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessoryBridge.java", + "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingBridge.java", "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetCoordinator.java", "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetMediator.java", "java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetProperties.java", @@ -144,7 +143,6 @@ "java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java", "java/src/org/chromium/chrome/browser/banners/AppData.java", "java/src/org/chromium/chrome/browser/banners/AppDetailsDelegate.java", - "java/src/org/chromium/chrome/browser/banners/InstallerDelegate.java", "java/src/org/chromium/chrome/browser/banners/SwipableOverlayView.java", "java/src/org/chromium/chrome/browser/browsing_data/UrlFilter.java", "java/src/org/chromium/chrome/browser/browsing_data/UrlFilterBridge.java", @@ -738,7 +736,6 @@ "java/src/org/chromium/chrome/browser/incognito/IncognitoTabSnapshotController.java", "java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java", "java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java", - "java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java", "java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java", "java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java", "java/src/org/chromium/chrome/browser/infobar/CardDetail.java", @@ -814,7 +811,9 @@ "java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java", "java/src/org/chromium/chrome/browser/invalidation/InvalidationServiceFactory.java", "java/src/org/chromium/chrome/browser/invalidation/UniqueIdInvalidationClientNameGenerator.java", - "java/src/org/chromium/chrome/browser/jsdialog/JavascriptModalDialogView.java", + "java/src/org/chromium/chrome/browser/jsdialog/JavascriptAppModalDialog.java", + "java/src/org/chromium/chrome/browser/jsdialog/JavascriptDialogCustomView.java", + "java/src/org/chromium/chrome/browser/jsdialog/JavascriptModalDialog.java", "java/src/org/chromium/chrome/browser/jsdialog/JavascriptTabModalDialog.java", "java/src/org/chromium/chrome/browser/language/LanguageAskPrompt.java", "java/src/org/chromium/chrome/browser/lifecycle/Destroyable.java", @@ -1129,7 +1128,6 @@ "java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxResultsAdapter.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestion.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsList.java", - "java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionAnswer.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListViewBinder.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionView.java", @@ -1305,6 +1303,7 @@ "java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java", "java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionDataUseItem.java", "java/src/org/chromium/chrome/browser/preferences/developer/DeveloperPreferences.java", + "java/src/org/chromium/chrome/browser/preferences/developer/TracingCategoriesPreferences.java", "java/src/org/chromium/chrome/browser/preferences/developer/TracingPreferences.java", "java/src/org/chromium/chrome/browser/preferences/download/DownloadDirectoryAdapter.java", "java/src/org/chromium/chrome/browser/preferences/download/DownloadLocationPreference.java", @@ -1817,7 +1816,6 @@ "javatests/src/org/chromium/chrome/browser/ItemChooserDialogTest.java", "javatests/src/org/chromium/chrome/browser/JavaScriptEvalChromeTest.java", "javatests/src/org/chromium/chrome/browser/MainActivityWithURLTest.java", - "javatests/src/org/chromium/chrome/browser/ModalDialogTest.java", "javatests/src/org/chromium/chrome/browser/NavigateTest.java", "javatests/src/org/chromium/chrome/browser/NavigationBarColorControllerTest.java", "javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java", @@ -1862,7 +1860,6 @@ "javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessoryIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessorySheetViewTest.java", "javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java", - "javatests/src/org/chromium/chrome/browser/banners/InstallerDelegateTest.java", "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java", "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkModelTest.java", "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoTest.java", @@ -1983,6 +1980,7 @@ "javatests/src/org/chromium/chrome/browser/invalidation/ChromeBrowserSyncAdapterTest.java", "javatests/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsControllerTest.java", "javatests/src/org/chromium/chrome/browser/invalidation/InvalidationServiceTest.java", + "javatests/src/org/chromium/chrome/browser/jsdialog/JavascriptAppModalDialogTest.java", "javatests/src/org/chromium/chrome/browser/jsdialog/JavascriptTabModalDialogTest.java", "javatests/src/org/chromium/chrome/browser/locale/DefaultSearchEngineDialogHelperTest.java", "javatests/src/org/chromium/chrome/browser/locale/DefaultSearchEngineDialogHelperUtils.java", @@ -2057,7 +2055,6 @@ "javatests/src/org/chromium/chrome/browser/omnibox/OmniboxUrlEmphasizerTest.java", "javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java", "javatests/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeaderTest.java", - "javatests/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionAnswerTest.java", "javatests/src/org/chromium/chrome/browser/omnibox/suggestions/VoiceSuggestionProviderTest.java", "javatests/src/org/chromium/chrome/browser/page_info/ConnectionInfoPopupTest.java", "javatests/src/org/chromium/chrome/browser/page_info/PageInfoControllerTest.java", @@ -2369,18 +2366,21 @@ "junit/src/org/chromium/chrome/browser/media/router/ChromeMediaRouterSinkObservationTest.java", "junit/src/org/chromium/chrome/browser/media/router/ChromeMediaRouterTestBase.java", "junit/src/org/chromium/chrome/browser/media/router/DiscoveryCallbackTest.java", + "junit/src/org/chromium/chrome/browser/media/router/JSONTestUtils.java", "junit/src/org/chromium/chrome/browser/media/router/TestUtils.java", "junit/src/org/chromium/chrome/browser/media/router/cast/CastMediaRouteProviderTest.java", "junit/src/org/chromium/chrome/browser/media/router/cast/CastMediaSourceTest.java", "junit/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandlerTest.java", "junit/src/org/chromium/chrome/browser/media/router/cast/ChromeCastSessionManagerTest.java", - "junit/src/org/chromium/chrome/browser/media/router/cast/JSONTestUtils.java", "junit/src/org/chromium/chrome/browser/media/router/caf/MediaRouterTestHelper.java", "junit/src/org/chromium/chrome/browser/media/router/caf/ShadowMediaRouter.java", "junit/src/org/chromium/chrome/browser/media/router/caf/ShadowCastContext.java", + "junit/src/org/chromium/chrome/browser/media/router/caf/ShadowCastMediaSource.java", "junit/src/org/chromium/chrome/browser/media/router/caf/BaseSessionControllerTest.java", "junit/src/org/chromium/chrome/browser/media/router/caf/CastSessionControllerTest.java", "junit/src/org/chromium/chrome/browser/media/router/caf/CafBaseMediaRouteProviderTest.java", + "junit/src/org/chromium/chrome/browser/media/router/caf/CafMediaRouteProviderTest.java", + "junit/src/org/chromium/chrome/browser/media/router/caf/CafMessageHandlerTest.java", "junit/src/org/chromium/chrome/browser/media/ui/MediaImageManagerTest.java", "junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationActionsUpdatedTest.java", "junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationButtonComputationTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ModalDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ModalDialogTest.java deleted file mode 100644 index 93a3fc1..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ModalDialogTest.java +++ /dev/null
@@ -1,481 +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. - -package org.chromium.chrome.browser; - -import android.content.DialogInterface; -import android.support.test.filters.MediumTest; -import android.support.v7.app.AlertDialog; -import android.util.Log; -import android.view.View; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.EditText; - -import org.junit.Assert; -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.CallbackHelper; -import org.chromium.base.test.util.CommandLineFlags.Add; -import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.RetryOnFailure; -import org.chromium.base.test.util.UrlUtils; -import org.chromium.chrome.R; -import org.chromium.chrome.test.ChromeActivityTestRule; -import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.content_public.browser.GestureStateListener; -import org.chromium.content_public.browser.test.util.Criteria; -import org.chromium.content_public.browser.test.util.CriteriaHelper; -import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer; -import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper; -import org.chromium.content_public.browser.test.util.TouchCommon; -import org.chromium.content_public.browser.test.util.WebContentsUtils; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; - -/** - * Test suite for displaying and functioning of modal dialogs. - */ -@RunWith(ChromeJUnit4ClassRunner.class) -@RetryOnFailure -@Add({"disable-features=TabModalJsDialog", ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -public class ModalDialogTest { - @Rule - public ChromeActivityTestRule<ChromeActivity> mActivityTestRule = - new ChromeActivityTestRule<>(ChromeActivity.class); - - private static final String TAG = "ModalDialogTest"; - private static final String EMPTY_PAGE = UrlUtils.encodeHtmlDataUri( - "<html><title>Modal Dialog Test</title><p>Testcase.</p></title></html>"); - private static final String BEFORE_UNLOAD_URL = UrlUtils.encodeHtmlDataUri("<html>" - + "<head><script>window.onbeforeunload=function() {" - + "return 'Are you sure?';" - + "};</script></head></html>"); - - @Before - public void setUp() throws InterruptedException { - mActivityTestRule.startMainActivityWithURL(EMPTY_PAGE); - } - - /** - * Verifies modal alert-dialog appearance and that JavaScript execution is - * able to continue after dismissal. - */ - @Test - @MediumTest - @Feature({"Browser", "Main"}) - public void testAlertModalDialog() - throws InterruptedException, TimeoutException, ExecutionException { - final OnEvaluateJavaScriptResultHelper scriptEvent = - executeJavaScriptAndWaitForDialog("alert('Hello Android!');"); - - JavascriptAppModalDialog jsDialog = getCurrentDialog(); - Assert.assertNotNull("No dialog showing.", jsDialog); - - clickOk(jsDialog); - Assert.assertTrue("JavaScript execution should continue after closing prompt.", - scriptEvent.waitUntilHasValue()); - } - - /** - * Verifies that clicking on a button twice doesn't crash. - */ - @Test - @MediumTest - @Feature({"Browser", "Main"}) - public void testAlertModalDialogWithTwoClicks() - throws InterruptedException, TimeoutException, ExecutionException { - OnEvaluateJavaScriptResultHelper scriptEvent = - executeJavaScriptAndWaitForDialog("alert('Hello Android');"); - JavascriptAppModalDialog jsDialog = getCurrentDialog(); - Assert.assertNotNull("No dialog showing.", jsDialog); - - clickOk(jsDialog); - clickOk(jsDialog); - - Assert.assertTrue("JavaScript execution should continue after closing prompt.", - scriptEvent.waitUntilHasValue()); - } - - /** - * Verifies that modal confirm-dialogs display, two buttons are visible and - * the return value of [Ok] equals true, [Cancel] equals false. - */ - @Test - @MediumTest - @Feature({"Browser", "Main"}) - public void testConfirmModalDialog() - throws InterruptedException, TimeoutException, ExecutionException { - OnEvaluateJavaScriptResultHelper scriptEvent = - executeJavaScriptAndWaitForDialog("confirm('Android');"); - - JavascriptAppModalDialog jsDialog = getCurrentDialog(); - Assert.assertNotNull("No dialog showing.", jsDialog); - - Button[] buttons = getAlertDialogButtons(jsDialog.getDialogForTest()); - Assert.assertNotNull("No cancel button in confirm dialog.", buttons[0]); - Assert.assertEquals( - "Cancel button is not visible.", View.VISIBLE, buttons[0].getVisibility()); - if (buttons[1] != null) { - Assert.assertNotSame("Neutral button visible when it should not.", View.VISIBLE, - buttons[1].getVisibility()); - } - Assert.assertNotNull("No OK button in confirm dialog.", buttons[2]); - Assert.assertEquals("OK button is not visible.", View.VISIBLE, buttons[2].getVisibility()); - - clickOk(jsDialog); - Assert.assertTrue("JavaScript execution should continue after closing dialog.", - scriptEvent.waitUntilHasValue()); - - String resultString = scriptEvent.getJsonResultAndClear(); - Assert.assertEquals("Invalid return value.", "true", resultString); - - // Try again, pressing cancel this time. - scriptEvent = executeJavaScriptAndWaitForDialog("confirm('Android');"); - jsDialog = getCurrentDialog(); - Assert.assertNotNull("No dialog showing.", jsDialog); - - clickCancel(jsDialog); - Assert.assertTrue("JavaScript execution should continue after closing dialog.", - scriptEvent.waitUntilHasValue()); - - resultString = scriptEvent.getJsonResultAndClear(); - Assert.assertEquals("Invalid return value.", "false", resultString); - } - - /** - * Verifies that modal prompt-dialogs display and the result is returned. - */ - @Test - @MediumTest - @Feature({"Browser", "Main"}) - public void testPromptModalDialog() - throws InterruptedException, TimeoutException, ExecutionException { - final String promptText = "Hello Android!"; - final OnEvaluateJavaScriptResultHelper scriptEvent = - executeJavaScriptAndWaitForDialog("prompt('Android', 'default');"); - - final JavascriptAppModalDialog jsDialog = getCurrentDialog(); - Assert.assertNotNull("No dialog showing.", jsDialog); - - // Set the text in the prompt field of the dialog. - boolean result = ThreadUtils.runOnUiThreadBlocking(() -> { - EditText prompt = (EditText) jsDialog.getDialogForTest().findViewById( - org.chromium.chrome.R.id.js_modal_dialog_prompt); - if (prompt == null) return false; - prompt.setText(promptText); - return true; - }); - Assert.assertTrue("Failed to find prompt view in prompt dialog.", result); - - clickOk(jsDialog); - Assert.assertTrue("JavaScript execution should continue after closing prompt.", - scriptEvent.waitUntilHasValue()); - - String resultString = scriptEvent.getJsonResultAndClear(); - Assert.assertEquals("Invalid return value.", '"' + promptText + '"', resultString); - } - - /** - * Verifies that message content in a dialog is only focusable if the message itself is long - * enough to require scrolling. - */ - @Test - @MediumTest - @Feature({"Browser", "Main"}) - public void testAlertModalDialogMessageFocus() - throws InterruptedException, TimeoutException, ExecutionException { - assertScrollViewFocusabilityInAlertDialog("alert('Short message!');", false); - - assertScrollViewFocusabilityInAlertDialog( - "alert(new Array(200).join('Long message!'));", true); - } - - private void assertScrollViewFocusabilityInAlertDialog( - final String jsAlertScript, final boolean expectedFocusability) - throws InterruptedException, TimeoutException, ExecutionException { - final OnEvaluateJavaScriptResultHelper scriptEvent = - executeJavaScriptAndWaitForDialog(jsAlertScript); - - final JavascriptAppModalDialog jsDialog = getCurrentDialog(); - Assert.assertNotNull("No dialog showing.", jsDialog); - - final String errorMessage = - "Scroll view focusability was incorrect. Expected: " + expectedFocusability; - - CriteriaHelper.pollUiThread(new Criteria(errorMessage) { - @Override - public boolean isSatisfied() { - return jsDialog.getDialogForTest() - .findViewById(R.id.js_modal_dialog_scroll_view) - .isFocusable() - == expectedFocusability; - } - }); - - clickOk(jsDialog); - Assert.assertTrue("JavaScript execution should continue after closing prompt.", - scriptEvent.waitUntilHasValue()); - } - - private static class TapGestureStateListener implements GestureStateListener { - private CallbackHelper mCallbackHelper = new CallbackHelper(); - - public int getCallCount() { - return mCallbackHelper.getCallCount(); - } - - public void waitForTap(int currentCallCount) throws InterruptedException, TimeoutException { - mCallbackHelper.waitForCallback(currentCallCount); - } - - @Override - public void onSingleTap(boolean consumed) { - mCallbackHelper.notifyCalled(); - } - } - - /** - * Taps on a view and waits for a callback. - */ - private void tapViewAndWait() throws InterruptedException, TimeoutException { - final TapGestureStateListener tapGestureStateListener = new TapGestureStateListener(); - int callCount = tapGestureStateListener.getCallCount(); - WebContentsUtils.getGestureListenerManager(mActivityTestRule.getWebContents()) - .addListener(tapGestureStateListener); - - TouchCommon.singleClickView(mActivityTestRule.getActivity().getActivityTab().getView()); - tapGestureStateListener.waitForTap(callCount); - } - - /** - * Verifies beforeunload dialogs are shown and they block/allow navigation - * as appropriate. - */ - @Test - @MediumTest - @Feature({"Browser", "Main"}) - public void testBeforeUnloadDialog() - throws InterruptedException, TimeoutException, ExecutionException { - mActivityTestRule.loadUrl(BEFORE_UNLOAD_URL); - // JavaScript onbeforeunload dialogs require a user gesture. - tapViewAndWait(); - executeJavaScriptAndWaitForDialog("history.back();"); - - JavascriptAppModalDialog jsDialog = getCurrentDialog(); - Assert.assertNotNull("No dialog showing.", jsDialog); - checkButtonPresenceVisibilityText(jsDialog, 0, R.string.cancel, "Cancel"); - clickCancel(jsDialog); - - Assert.assertEquals(BEFORE_UNLOAD_URL, - mActivityTestRule.getActivity().getCurrentWebContents().getLastCommittedUrl()); - executeJavaScriptAndWaitForDialog("history.back();"); - - jsDialog = getCurrentDialog(); - Assert.assertNotNull("No dialog showing.", jsDialog); - checkButtonPresenceVisibilityText(jsDialog, 2, R.string.leave, "Leave"); - - final TestCallbackHelperContainer.OnPageFinishedHelper onPageLoaded = - getActiveTabTestCallbackHelperContainer().getOnPageFinishedHelper(); - int callCount = onPageLoaded.getCallCount(); - clickOk(jsDialog); - onPageLoaded.waitForCallback(callCount); - Assert.assertEquals(EMPTY_PAGE, - mActivityTestRule.getActivity().getCurrentWebContents().getLastCommittedUrl()); - } - - /** - * Verifies that when showing a beforeunload dialogs as a result of a page - * reload, the correct UI strings are used. - */ - @Test - @MediumTest - @Feature({"Browser", "Main"}) - public void testBeforeUnloadOnReloadDialog() - throws InterruptedException, TimeoutException, ExecutionException { - mActivityTestRule.loadUrl(BEFORE_UNLOAD_URL); - // JavaScript onbeforeunload dialogs require a user gesture. - tapViewAndWait(); - executeJavaScriptAndWaitForDialog("window.location.reload();"); - - JavascriptAppModalDialog jsDialog = getCurrentDialog(); - Assert.assertNotNull("No dialog showing.", jsDialog); - - checkButtonPresenceVisibilityText(jsDialog, 0, R.string.cancel, "Cancel"); - checkButtonPresenceVisibilityText(jsDialog, 2, R.string.reload, "Reload"); - } - - /** - * Verifies that repeated dialogs give the option to disable dialogs - * altogether and then that disabling them works. - */ - @Test - @MediumTest - @Feature({"Browser", "Main"}) - public void testDisableRepeatedDialogs() - throws InterruptedException, TimeoutException, ExecutionException { - OnEvaluateJavaScriptResultHelper scriptEvent = - executeJavaScriptAndWaitForDialog("alert('Android');"); - - // Show a dialog once. - JavascriptAppModalDialog jsDialog = getCurrentDialog(); - Assert.assertNotNull("No dialog showing.", jsDialog); - - clickCancel(jsDialog); - scriptEvent.waitUntilHasValue(); - - // Show it again, it should have the option to suppress subsequent dialogs. - scriptEvent = executeJavaScriptAndWaitForDialog("alert('Android');"); - jsDialog = getCurrentDialog(); - Assert.assertNotNull("No dialog showing.", jsDialog); - final AlertDialog dialog = jsDialog.getDialogForTest(); - String errorMessage = ThreadUtils.runOnUiThreadBlocking(() -> { - final CheckBox suppress = (CheckBox) dialog.findViewById( - org.chromium.chrome.R.id.suppress_js_modal_dialogs); - if (suppress == null) return "Suppress checkbox not found."; - if (suppress.getVisibility() != View.VISIBLE) { - return "Suppress checkbox is not visible."; - } - suppress.setChecked(true); - return null; - }); - Assert.assertNull(errorMessage, errorMessage); - clickCancel(jsDialog); - scriptEvent.waitUntilHasValue(); - - scriptEvent.evaluateJavaScriptForTests( - mActivityTestRule.getActivity().getCurrentWebContents(), "alert('Android');"); - Assert.assertTrue( - "No further dialog boxes should be shown.", scriptEvent.waitUntilHasValue()); - } - - /** - * Displays a dialog and closes the tab in the background before attempting - * to accept the dialog. Verifies that the dialog is dismissed when the tab - * is closed. - */ - @Test - @MediumTest - @Feature({"Browser", "Main"}) - public void testDialogDismissedAfterClosingTab() { - executeJavaScriptAndWaitForDialog("alert('Android')"); - - ThreadUtils.runOnUiThreadBlocking(() -> { - ChromeActivity activity = mActivityTestRule.getActivity(); - activity.getCurrentTabModel().closeTab(activity.getActivityTab()); - }); - - // Closing the tab should have dismissed the dialog. - CriteriaHelper.pollInstrumentationThread(new JavascriptAppModalDialogShownCriteria( - "The dialog should have been dismissed when its tab was closed.", false)); - } - - /** - * Asynchronously executes the given code for spawning a dialog and waits - * for the dialog to be visible. - */ - private OnEvaluateJavaScriptResultHelper executeJavaScriptAndWaitForDialog(String script) { - return executeJavaScriptAndWaitForDialog(new OnEvaluateJavaScriptResultHelper(), script); - } - - /** - * Given a JavaScript evaluation helper, asynchronously executes the given - * code for spawning a dialog and waits for the dialog to be visible. - */ - private OnEvaluateJavaScriptResultHelper executeJavaScriptAndWaitForDialog( - final OnEvaluateJavaScriptResultHelper helper, String script) { - helper.evaluateJavaScriptForTests( - mActivityTestRule.getActivity().getCurrentWebContents(), script); - CriteriaHelper.pollInstrumentationThread(new JavascriptAppModalDialogShownCriteria( - "Could not spawn or locate a modal dialog.", true)); - return helper; - } - - /** - * Returns an array of the 3 buttons for this dialog, in the order - * BUTTON_NEGATIVE, BUTTON_NEUTRAL and BUTTON_POSITIVE. Any of these values - * can be null. - */ - private Button[] getAlertDialogButtons(final AlertDialog dialog) throws ExecutionException { - return ThreadUtils.runOnUiThreadBlocking(() -> { - final Button[] buttons = new Button[3]; - buttons[0] = dialog.getButton(DialogInterface.BUTTON_NEGATIVE); - buttons[1] = dialog.getButton(DialogInterface.BUTTON_NEUTRAL); - buttons[2] = dialog.getButton(DialogInterface.BUTTON_POSITIVE); - return buttons; - }); - } - - /** - * Returns the current JavaScript modal dialog showing or null if no such dialog is currently - * showing. - */ - private JavascriptAppModalDialog getCurrentDialog() throws ExecutionException { - return ThreadUtils.runOnUiThreadBlocking( - () -> JavascriptAppModalDialog.getCurrentDialogForTest()); - } - - private static class JavascriptAppModalDialogShownCriteria extends Criteria { - private final boolean mShouldBeShown; - - public JavascriptAppModalDialogShownCriteria(String error, boolean shouldBeShown) { - super(error); - mShouldBeShown = shouldBeShown; - } - - @Override - public boolean isSatisfied() { - try { - return ThreadUtils.runOnUiThreadBlocking(() -> { - final boolean isShown = - JavascriptAppModalDialog.getCurrentDialogForTest() != null; - return mShouldBeShown == isShown; - }); - } catch (ExecutionException e) { - Log.e(TAG, "Failed to getCurrentDialog", e); - return false; - } - } - } - - /** - * Simulates pressing the OK button of the passed dialog. - */ - private void clickOk(JavascriptAppModalDialog dialog) { - clickButton(dialog, DialogInterface.BUTTON_POSITIVE); - } - - /** - * Simulates pressing the Cancel button of the passed dialog. - */ - private void clickCancel(JavascriptAppModalDialog dialog) { - clickButton(dialog, DialogInterface.BUTTON_NEGATIVE); - } - - private void clickButton(final JavascriptAppModalDialog dialog, final int whichButton) { - ThreadUtils.runOnUiThreadBlocking(() -> dialog.onClick(null, whichButton)); - } - - private void checkButtonPresenceVisibilityText( - JavascriptAppModalDialog jsDialog, int buttonIndex, - int expectedTextResourceId, String readableName) throws ExecutionException { - final Button[] buttons = getAlertDialogButtons(jsDialog.getDialogForTest()); - final Button button = buttons[buttonIndex]; - Assert.assertNotNull("No '" + readableName + "' button in confirm dialog.", button); - Assert.assertEquals("'" + readableName + "' button is not visible.", View.VISIBLE, - button.getVisibility()); - Assert.assertEquals("'" + readableName + "' button has wrong text", - mActivityTestRule.getActivity().getResources().getString(expectedTextResourceId), - button.getText().toString()); - } - - private TestCallbackHelperContainer getActiveTabTestCallbackHelperContainer() { - return new TestCallbackHelperContainer(mActivityTestRule.getWebContents()); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java index 0369698..b0ce507 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
@@ -6,7 +6,6 @@ import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE; -import android.content.DialogInterface; import android.content.pm.ActivityInfo; import android.graphics.Point; import android.os.Build; @@ -50,6 +49,8 @@ import org.chromium.chrome.browser.compositor.layouts.phone.StackLayout; import org.chromium.chrome.browser.compositor.layouts.phone.stack.Stack; import org.chromium.chrome.browser.compositor.layouts.phone.stack.StackTab; +import org.chromium.chrome.browser.jsdialog.JavascriptTabModalDialog; +import org.chromium.chrome.browser.modaldialog.ModalDialogView; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; @@ -205,7 +206,6 @@ @Test @MediumTest @RetryOnFailure - @CommandLineFlags.Add("disable-features=TabModalJsDialog") public void testAlertDialogDoesNotChangeActiveModel() throws InterruptedException { mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); mActivityTestRule.newIncognitoTabFromMenu(); @@ -217,27 +217,26 @@ + "})()", null)); - final AtomicReference<JavascriptAppModalDialog> dialog = - new AtomicReference<>(); + final AtomicReference<JavascriptTabModalDialog> dialog = new AtomicReference<>(); CriteriaHelper.pollInstrumentationThread(new Criteria() { @Override public boolean isSatisfied() { - dialog.set(JavascriptAppModalDialog.getCurrentDialogForTest()); + dialog.set(getCurrentAlertDialog()); return dialog.get() != null; } }); ThreadUtils.runOnUiThreadBlocking( - () -> dialog.get().onClick(null, DialogInterface.BUTTON_POSITIVE)); + () -> dialog.get().onClick(ModalDialogView.ButtonType.POSITIVE)); dialog.set(null); CriteriaHelper.pollInstrumentationThread(new Criteria() { @Override public boolean isSatisfied() { - return JavascriptAppModalDialog.getCurrentDialogForTest() == null; + return getCurrentAlertDialog() == null; } }); @@ -1974,4 +1973,13 @@ pageLoadedCallbacks[i].waitForCallback(0); } } + + private JavascriptTabModalDialog getCurrentAlertDialog() { + return (JavascriptTabModalDialog) ThreadUtils.runOnUiThreadBlockingNoException(() -> { + ModalDialogView dialogView = mActivityTestRule.getActivity() + .getModalDialogManager() + .getCurrentDialogForTest(); + return dialogView != null ? dialogView.getController() : null; + }); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java index a23a828..df1c767 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
@@ -11,7 +11,6 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.support.test.InstrumentationRegistry; @@ -29,9 +28,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentMatchers; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.mockito.quality.Strictness; @@ -190,7 +187,6 @@ @Before public void setUp() throws Exception { AppBannerManager.setIsSupported(true); - InstallerDelegate.setPackageManagerForTesting(mPackageManager); ShortcutHelper.setDelegateForTests(new ShortcutHelper.Delegate() { @Override public void addShortcutToHomescreen(String title, Bitmap icon, Intent shortcutIntent) { @@ -280,11 +276,6 @@ private void runFullNativeInstallPathway( String url, String expectedReferrer, String expectedTitle) throws Exception { - // Say that the package isn't installed. - Mockito.when(mPackageManager.getPackageInfo( - ArgumentMatchers.anyString(), ArgumentMatchers.anyInt())) - .thenThrow(new PackageManager.NameNotFoundException()); - // Visit a site that requests a banner. Tab tab = mTabbedActivityTestRule.getActivity().getActivityTab(); resetEngagementForUrl(url, 0); @@ -314,39 +305,10 @@ InstrumentationRegistry.getInstrumentation().addMonitor(activityMonitor); TouchCommon.singleClickView(button); - // Wait for the infobar to register that the app is installing. - final String installingText = InstrumentationRegistry.getTargetContext().getString( - R.string.app_banner_installing); - CriteriaHelper.pollInstrumentationThread(new Criteria() { - @Override - public boolean isSatisfied() { - return InstrumentationRegistry.getInstrumentation().checkMonitorHit( - activityMonitor, 1) - && TextUtils.equals(button.getText(), installingText); - } - }); - // If we expect an update of the page title via JavaScript, wait until the change happens. if (expectedTitle != null) { new TabTitleObserver(tab, expectedTitle).waitForTitleUpdate(3); } - - // Say that the package is installed. Infobar should say that the app is ready to open. - Mockito.reset(mPackageManager); - PackageInfo info = new PackageInfo(); - info.packageName = NATIVE_APP_PACKAGE; - Mockito.when(mPackageManager.getPackageInfo( - ArgumentMatchers.anyString(), ArgumentMatchers.anyInt())) - .thenReturn(info); - - final String openText = - InstrumentationRegistry.getTargetContext().getString(R.string.app_banner_open); - CriteriaHelper.pollInstrumentationThread(new Criteria() { - @Override - public boolean isSatisfied() { - return TextUtils.equals(button.getText(), openText); - } - }); } private void triggerWebAppBanner(ChromeActivityTestRule<? extends ChromeActivity> rule, @@ -561,9 +523,10 @@ "call_stashed_prompt_on_click_verify_appinstalled"), NATIVE_APP_BLANK_REFERRER, true); - // The appinstalled event should fire (and cause the title to change). - new TabTitleObserver(mTabbedActivityTestRule.getActivity().getActivityTab(), - "Got appinstalled: listener, attr") + // The userChoice promise should resolve (and cause the title to change). appinstalled is + // not fired for native apps + new TabTitleObserver( + mTabbedActivityTestRule.getActivity().getActivityTab(), "Got userChoice: accepted") .waitForTitleUpdate(3); } @@ -731,8 +694,8 @@ public void testFullNativeInstallPathwayFromUrl() throws Exception { runFullNativeInstallPathway( WebappTestPage.getNonServiceWorkerUrlWithManifestAndAction( - mTestServer, NATIVE_APP_MANIFEST_WITH_URL, "verify_appinstalled"), - NATIVE_APP_REFERRER, "Got appinstalled: listener, attr"); + mTestServer, NATIVE_APP_MANIFEST_WITH_URL, "call_prompt_delayed"), + NATIVE_APP_REFERRER, "Got userChoice: accepted"); } @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/InstallerDelegateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/InstallerDelegateTest.java deleted file mode 100644 index 441e684..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/InstallerDelegateTest.java +++ /dev/null
@@ -1,172 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.banners; - -import android.content.pm.PackageInfo; -import android.os.HandlerThread; -import android.support.test.filters.SmallTest; -import android.test.mock.MockPackageManager; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.BaseJUnit4ClassRunner; -import org.chromium.base.test.util.RetryOnFailure; -import org.chromium.content_public.browser.test.util.Criteria; -import org.chromium.content_public.browser.test.util.CriteriaHelper; - -/** - * Tests the InstallerDelegate to make sure that it functions correctly and responds to changes - * in the PackageManager. - */ -@RunWith(BaseJUnit4ClassRunner.class) -public class InstallerDelegateTest implements InstallerDelegate.Observer { - private static final String MOCK_PACKAGE_NAME = "mock.package.name"; - - /** - * Returns a mocked set of installed packages. - */ - public static class TestPackageManager extends MockPackageManager { - public boolean isInstalled; - - @Override - public PackageInfo getPackageInfo(String packageName, int flags) - throws NameNotFoundException { - if (!isInstalled) { - throw new NameNotFoundException(); - } - PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = MOCK_PACKAGE_NAME; - return packageInfo; - } - } - - private TestPackageManager mPackageManager; - private InstallerDelegate mTestDelegate; - private HandlerThread mThread; - - // Variables for tracking the result. - private boolean mResultFinished; - private InstallerDelegate mResultDelegate; - private boolean mResultSuccess; - private boolean mInstallStarted; - - @Override - public void onInstallIntentCompleted(InstallerDelegate delegate, boolean isInstalling) { - Assert.assertTrue(isInstalling); - } - - @Override - public void onInstallFinished(InstallerDelegate delegate, boolean success) { - mResultDelegate = delegate; - mResultSuccess = success; - mResultFinished = true; - Assert.assertTrue(mInstallStarted); - } - - @Override - public void onApplicationStateChanged(InstallerDelegate delegate, int newState) {} - - @Before - public void setUp() throws Exception { - mPackageManager = new TestPackageManager(); - InstallerDelegate.setPackageManagerForTesting(mPackageManager); - - // Create a thread for the InstallerDelegate to run on. We need this thread because the - // InstallerDelegate's handler fails to be processed otherwise. - mThread = new HandlerThread("InstallerDelegateTest thread"); - mThread.start(); - mTestDelegate = new InstallerDelegate(mThread.getLooper(), this); - - // Clear out the results from last time. - mResultDelegate = null; - mResultSuccess = false; - mResultFinished = false; - } - - @After - public void tearDown() throws Exception { - mThread.quit(); - } - - private void startMonitoring() { - mTestDelegate.startMonitoring(MOCK_PACKAGE_NAME); - mInstallStarted = true; - } - - private void checkResults(boolean expectedResult) { - CriteriaHelper.pollInstrumentationThread(new Criteria() { - @Override - public boolean isSatisfied() { - return !mTestDelegate.isRunning() && mResultFinished; - } - }); - - Assert.assertEquals(expectedResult, mResultSuccess); - Assert.assertEquals(mTestDelegate, mResultDelegate); - } - - /** - * Tests what happens when the InstallerDelegate detects that the package has successfully - * been installed. - */ - @Test - @SmallTest - public void testInstallSuccessful() { - mTestDelegate.setTimingForTests(1, 5000); - startMonitoring(); - - Assert.assertFalse(mResultSuccess); - Assert.assertNull(mResultDelegate); - Assert.assertFalse(mResultFinished); - - mPackageManager.isInstalled = true; - checkResults(true); - } - - /** - * Tests what happens when the InstallerDelegate task is canceled. - */ - @Test - @SmallTest - public void testInstallWaitUntilCancel() { - mTestDelegate.setTimingForTests(1, 5000); - startMonitoring(); - - Assert.assertFalse(mResultSuccess); - Assert.assertNull(mResultDelegate); - Assert.assertFalse(mResultFinished); - - mTestDelegate.cancel(); - checkResults(false); - } - - /** - * Tests what happens when the InstallerDelegate times out. - */ - @Test - @SmallTest - public void testInstallTimeout() { - mTestDelegate.setTimingForTests(1, 50); - startMonitoring(); - checkResults(false); - } - - /** - * Makes sure that the runnable isn't called until returning from start(). - */ - @Test - @SmallTest - @RetryOnFailure - public void testRunnableRaceCondition() { - mPackageManager.isInstalled = true; - mTestDelegate.setTimingForTests(1, 5000); - startMonitoring(); - checkResults(true); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java index 5ce67cd..cbd6bd50e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -42,7 +42,6 @@ import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.filters.SmallTest; -import android.support.test.uiautomator.UiDevice; import android.support.v7.content.res.AppCompatResources; import android.text.TextUtils; import android.view.Menu; @@ -78,7 +77,6 @@ import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.R; -import org.chromium.chrome.browser.AppHooksModule; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeSwitches; @@ -90,7 +88,6 @@ import org.chromium.chrome.browser.browserservices.BrowserSessionContentUtils; import org.chromium.chrome.browser.browserservices.Origin; import org.chromium.chrome.browser.browserservices.OriginVerifier; -import org.chromium.chrome.browser.dependency_injection.ModuleFactoryOverrides; import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.firstrun.FirstRunStatus; import org.chromium.chrome.browser.history.BrowsingHistoryBridge; @@ -120,7 +117,6 @@ import org.chromium.chrome.test.util.browser.contextmenu.ContextMenuUtils; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.WebContentsObserver; -import org.chromium.content_public.browser.test.util.ClickUtils; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.DOMUtils; @@ -128,14 +124,12 @@ import org.chromium.content_public.browser.test.util.WebContentsUtils; import org.chromium.net.test.EmbeddedTestServer; import org.chromium.net.test.util.TestWebServer; -import org.chromium.ui.base.PageTransition; import org.chromium.ui.mojom.WindowOpenDisposition; import org.chromium.ui.test.util.UiRestriction; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -226,9 +220,6 @@ PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX); LibraryLoader.getInstance().ensureInitialized(LibraryProcessType.PROCESS_BROWSER); mWebServer = TestWebServer.start(); - - ModuleFactoryOverrides.setOverride(AppHooksModule.Factory.class, - CustomTabsDynamicModuleTestUtils.AppHooksModuleForTest::new); } @After @@ -245,8 +236,6 @@ if (handler != null) handler.hideAppMenu(); }); mWebServer.shutdown(); - - ModuleFactoryOverrides.clearOverrides(); } private CustomTabActivity getActivity() { @@ -1121,119 +1110,6 @@ } } - private void runAndWaitForActivityStopped(Runnable runnable) - throws TimeoutException, InterruptedException { - CallbackHelper cctHiddenCallback = new CallbackHelper(); - ActivityStateListener listener = (activity, newState) -> { - if (activity == mCustomTabActivityTestRule.getActivity() - && (newState == ActivityState.STOPPED || newState == ActivityState.DESTROYED)) { - cctHiddenCallback.notifyCalled(); - } - }; - ApplicationStatus.registerStateListenerForAllActivities(listener); - - runnable.run(); - cctHiddenCallback.waitForCallback("Hide cct", 0); - ApplicationStatus.unregisterActivityStateListener(listener); - } - - /** - This test executes the following workflow assuming dynamic module has been loaded succesfully: - - moduleManagedUrl1 -> nav1.1 -> nav1.2 -> modulemanagedUrl2 -> nav2.1 -> nav2.2 - - User hits the "close button", therefore goes back to modulemanagedUrl2 - - User hits the Android back button, going returning to nav1.2 - - User hits the "close button" again, going return to moduleManagedUrl1 - - User hits the Android back button thereby closes CCT. - */ - @Test - @SmallTest - @EnableFeatures(ChromeFeatureList.CCT_MODULE) - public void testCloseButtonBehaviourWithDynamicModule() - throws InterruptedException, ExecutionException, TimeoutException { - String moduleManagedUrl1 = "https://www.google.com/search?q=cat"; - String moduleManagedUrl2 = "https://www.google.com/search?q=dog"; - - Intent intent = CustomTabsDynamicModuleTestUtils.makeDynamicModuleIntent( - moduleManagedUrl1, "^https://www.google.com/search.*"); - - // Open CCT with moduleManagedUrl1 and navigate - // moduleManagedUrl1 -> nav1.1 - nav1.2 -> modulemanagedUrl2 -> nav2.1 -> nav2.2 - mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); - CustomTabActivity cctActivity = mCustomTabActivityTestRule.getActivity(); - - mCustomTabActivityTestRule.loadUrlInTab(mTestPage, PageTransition.LINK, - cctActivity.getActivityTab()); - mCustomTabActivityTestRule.loadUrlInTab(mTestPage2, PageTransition.LINK, - cctActivity.getActivityTab()); - mCustomTabActivityTestRule.loadUrlInTab(moduleManagedUrl2, PageTransition.TYPED, - cctActivity.getActivityTab()); - mCustomTabActivityTestRule.loadUrlInTab(mTestPage, PageTransition.LINK, - cctActivity.getActivityTab()); - mCustomTabActivityTestRule.loadUrlInTab(mTestPage2, PageTransition.LINK, - cctActivity.getActivityTab()); - - // click the close button and wait while tab page loaded - ClickUtils.clickButton(cctActivity.findViewById(R.id.close_button)); - ChromeTabUtils.waitForTabPageLoaded(cctActivity.getActivityTab(), (String) null); - - // close button returns back to moduleManagedUrl2 - Assert.assertEquals(moduleManagedUrl2, cctActivity.getActivityTab().getUrl()); - - // press the back button and wait while tab page loaded - UiDevice mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - mDevice.pressBack(); - ChromeTabUtils.waitForTabPageLoaded(cctActivity.getActivityTab(), (String) null); - - // the back button returns to nav1.2 - Assert.assertEquals(mTestPage2, cctActivity.getActivityTab().getUrl()); - - // click the close button and wait while tab page loaded - ClickUtils.clickButton(cctActivity.findViewById(R.id.close_button)); - ChromeTabUtils.waitForTabPageLoaded(cctActivity.getActivityTab(), (String) null); - - // close button returns back to moduleManagedUrl1 - Assert.assertEquals(moduleManagedUrl1, cctActivity.getActivityTab().getUrl()); - - // press back button and while cct is hidden - runAndWaitForActivityStopped(mDevice::pressBack); - } - - /** - This test executes the following workflow assuming dynamic module has not been loaded: - - moduleManagedUrl1 -> nav1.1 - nav1.2 -> modulemanagedUrl2 -> nav2.1 -> nav2.2 - - User hits the close button, thereby closes CCT - */ - @Test - @SmallTest - public void testCloseButtonBehaviourWithoutDynamicModule() - throws InterruptedException, ExecutionException, TimeoutException { - String moduleManagedUrl1 = "https://www.google.com/search?q=cat"; - String moduleManagedUrl2 = "https://www.google.com/search?q=dog"; - - // Open CCT with moduleManagedUrl1 and navigate - // moduleManagedUrl1 -> nav1.1 - nav1.2 -> modulemanagedUrl2 -> nav2.1 -> nav2.2 - - Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent( - InstrumentationRegistry.getTargetContext(), moduleManagedUrl1); - mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); - CustomTabActivity cctActivity = mCustomTabActivityTestRule.getActivity(); - - mCustomTabActivityTestRule.loadUrlInTab(mTestPage, PageTransition.LINK, - cctActivity.getActivityTab()); - mCustomTabActivityTestRule.loadUrlInTab(mTestPage2, PageTransition.LINK, - cctActivity.getActivityTab()); - mCustomTabActivityTestRule.loadUrlInTab(moduleManagedUrl2, PageTransition.LINK, - cctActivity.getActivityTab()); - mCustomTabActivityTestRule.loadUrlInTab(mTestPage, PageTransition.LINK, - cctActivity.getActivityTab()); - mCustomTabActivityTestRule.loadUrlInTab(mTestPage2, PageTransition.LINK, - cctActivity.getActivityTab()); - - // click close button and wait while cct is hidden - runAndWaitForActivityStopped(() -> - ClickUtils.clickButton(cctActivity.findViewById(R.id.close_button))); - } - @Test @SmallTest @RetryOnFailure
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/jsdialog/JavascriptAppModalDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/jsdialog/JavascriptAppModalDialogTest.java new file mode 100644 index 0000000..5f79e174 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/jsdialog/JavascriptAppModalDialogTest.java
@@ -0,0 +1,279 @@ +// 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.jsdialog; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.matcher.ViewMatchers.isChecked; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; + +import android.support.test.filters.MediumTest; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.Log; +import org.chromium.base.ThreadUtils; +import org.chromium.base.test.util.CallbackHelper; +import org.chromium.base.test.util.CommandLineFlags.Add; +import org.chromium.base.test.util.Feature; +import org.chromium.base.test.util.RetryOnFailure; +import org.chromium.base.test.util.UrlUtils; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.test.ChromeActivityTestRule; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.content_public.browser.GestureStateListener; +import org.chromium.content_public.browser.test.util.Criteria; +import org.chromium.content_public.browser.test.util.CriteriaHelper; +import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer; +import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper; +import org.chromium.content_public.browser.test.util.TouchCommon; +import org.chromium.content_public.browser.test.util.WebContentsUtils; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + +/** + * Test suite for displaying and functioning of app modal JavaScript onbeforeunload dialogs. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +@RetryOnFailure +@Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +public class JavascriptAppModalDialogTest { + @Rule + public ChromeActivityTestRule<ChromeActivity> mActivityTestRule = + new ChromeActivityTestRule<>(ChromeActivity.class); + + private static final String TAG = "JSAppModalDialogTest"; + private static final String EMPTY_PAGE = UrlUtils.encodeHtmlDataUri( + "<html><title>Modal Dialog Test</title><p>Testcase.</p></title></html>"); + private static final String BEFORE_UNLOAD_URL = UrlUtils.encodeHtmlDataUri("<html>" + + "<head><script>window.onbeforeunload=function() {" + + "return 'Are you sure?';" + + "};</script></head></html>"); + + @Before + public void setUp() throws InterruptedException { + mActivityTestRule.startMainActivityWithURL(EMPTY_PAGE); + } + + /** + * Verifies beforeunload dialogs are shown and they block/allow navigation + * as appropriate. + */ + @Test + @MediumTest + @Feature({"Browser", "Main"}) + public void testBeforeUnloadDialog() + throws InterruptedException, TimeoutException, ExecutionException { + mActivityTestRule.loadUrl(BEFORE_UNLOAD_URL); + // JavaScript onbeforeunload dialogs require a user gesture. + tapViewAndWait(); + executeJavaScriptAndWaitForDialog("history.back();"); + + // Click cancel and verify that the url is the same. + JavascriptAppModalDialog jsDialog = getCurrentDialog(); + Assert.assertNotNull("No dialog showing.", jsDialog); + onView(withText(R.string.cancel)).perform(click()); + + Assert.assertEquals(BEFORE_UNLOAD_URL, + mActivityTestRule.getActivity().getCurrentWebContents().getLastCommittedUrl()); + executeJavaScriptAndWaitForDialog("history.back();"); + + jsDialog = getCurrentDialog(); + Assert.assertNotNull("No dialog showing.", jsDialog); + + // Click leave and verify that the url is changed. + final TestCallbackHelperContainer.OnPageFinishedHelper onPageLoaded = + getActiveTabTestCallbackHelperContainer().getOnPageFinishedHelper(); + int callCount = onPageLoaded.getCallCount(); + onView(withText(R.string.leave)).perform(click()); + onPageLoaded.waitForCallback(callCount); + Assert.assertEquals(EMPTY_PAGE, + mActivityTestRule.getActivity().getCurrentWebContents().getLastCommittedUrl()); + } + + /** + * Verifies that when showing a beforeunload dialogs as a result of a page + * reload, the correct UI strings are used. + */ + @Test + @MediumTest + @Feature({"Browser", "Main"}) + public void testBeforeUnloadOnReloadDialog() + throws InterruptedException, TimeoutException, ExecutionException { + mActivityTestRule.loadUrl(BEFORE_UNLOAD_URL); + // JavaScript onbeforeunload dialogs require a user gesture. + tapViewAndWait(); + executeJavaScriptAndWaitForDialog("window.location.reload();"); + + JavascriptAppModalDialog jsDialog = getCurrentDialog(); + Assert.assertNotNull("No dialog showing.", jsDialog); + + onView(withText(R.string.cancel)).check(matches(isDisplayed())); + onView(withText(R.string.reload)).check(matches(isDisplayed())); + } + + /** + * Verifies that repeated dialogs give the option to disable dialogs + * altogether and then that disabling them works. + */ + @Test + @MediumTest + @Feature({"Browser", "Main"}) + public void testDisableRepeatedDialogs() + throws InterruptedException, TimeoutException, ExecutionException { + mActivityTestRule.loadUrl(BEFORE_UNLOAD_URL); + // JavaScript onbeforeunload dialogs require a user gesture. + tapViewAndWait(); + executeJavaScriptAndWaitForDialog("history.back();"); + + // Show a dialog once. + JavascriptAppModalDialog jsDialog = getCurrentDialog(); + Assert.assertNotNull("No dialog showing.", jsDialog); + onView(withText(R.string.cancel)).perform(click()); + Assert.assertEquals(BEFORE_UNLOAD_URL, + mActivityTestRule.getActivity().getCurrentWebContents().getLastCommittedUrl()); + + // Show it again, it should have the option to suppress subsequent dialogs. + OnEvaluateJavaScriptResultHelper resultHelper = + executeJavaScriptAndWaitForDialog("history.back();"); + jsDialog = getCurrentDialog(); + Assert.assertNotNull("No dialog showing.", jsDialog); + onView(withId(R.id.suppress_js_modal_dialogs)) + .check(matches(isDisplayed())) + .perform(click()) + .check(matches(isChecked())); + onView(withText(R.string.cancel)).perform(click()); + Assert.assertEquals(BEFORE_UNLOAD_URL, + mActivityTestRule.getActivity().getCurrentWebContents().getLastCommittedUrl()); + + // Try showing a dialog again and verify it is not shown. + resultHelper.evaluateJavaScriptForTests( + mActivityTestRule.getWebContents(), "history.back();"); + jsDialog = getCurrentDialog(); + Assert.assertNull("Dialog should not be showing.", jsDialog); + } + + /** + * Displays a dialog and closes the tab in the background before attempting + * to accept the dialog. Verifies that the dialog is dismissed when the tab + * is closed. + */ + @Test + @MediumTest + @Feature({"Browser", "Main"}) + public void testDialogDismissedAfterClosingTab() + throws InterruptedException, TimeoutException, ExecutionException { + mActivityTestRule.loadUrl(BEFORE_UNLOAD_URL); + // JavaScript onbeforeunload dialogs require a user gesture. + tapViewAndWait(); + executeJavaScriptAndWaitForDialog("history.back();"); + + ThreadUtils.runOnUiThreadBlocking(() -> { + ChromeActivity activity = mActivityTestRule.getActivity(); + activity.getCurrentTabModel().closeTab(activity.getActivityTab()); + }); + + // Closing the tab should have dismissed the dialog. + CriteriaHelper.pollInstrumentationThread(new JavascriptAppModalDialogShownCriteria( + "The dialog should have been dismissed when its tab was closed.", false)); + } + + /** + * Taps on a view and waits for a callback. + */ + private void tapViewAndWait() throws InterruptedException, TimeoutException { + final TapGestureStateListener tapGestureStateListener = new TapGestureStateListener(); + int callCount = tapGestureStateListener.getCallCount(); + WebContentsUtils.getGestureListenerManager(mActivityTestRule.getWebContents()) + .addListener(tapGestureStateListener); + + TouchCommon.singleClickView(mActivityTestRule.getActivity().getActivityTab().getView()); + tapGestureStateListener.waitForTap(callCount); + } + + /** + * Asynchronously executes the given code for spawning a dialog and waits + * for the dialog to be visible. + */ + private OnEvaluateJavaScriptResultHelper executeJavaScriptAndWaitForDialog(String script) { + return executeJavaScriptAndWaitForDialog(new OnEvaluateJavaScriptResultHelper(), script); + } + + /** + * Given a JavaScript evaluation helper, asynchronously executes the given + * code for spawning a dialog and waits for the dialog to be visible. + */ + private OnEvaluateJavaScriptResultHelper executeJavaScriptAndWaitForDialog( + final OnEvaluateJavaScriptResultHelper helper, String script) { + helper.evaluateJavaScriptForTests( + mActivityTestRule.getActivity().getCurrentWebContents(), script); + CriteriaHelper.pollInstrumentationThread(new JavascriptAppModalDialogShownCriteria( + "Could not spawn or locate a modal dialog.", true)); + return helper; + } + + /** + * Returns the current JavaScript modal dialog showing or null if no such dialog is currently + * showing. + */ + private JavascriptAppModalDialog getCurrentDialog() throws ExecutionException { + return ThreadUtils.runOnUiThreadBlocking( + () -> JavascriptAppModalDialog.getCurrentDialogForTest()); + } + + private static class TapGestureStateListener implements GestureStateListener { + private CallbackHelper mCallbackHelper = new CallbackHelper(); + + public int getCallCount() { + return mCallbackHelper.getCallCount(); + } + + public void waitForTap(int currentCallCount) throws InterruptedException, TimeoutException { + mCallbackHelper.waitForCallback(currentCallCount); + } + + @Override + public void onSingleTap(boolean consumed) { + mCallbackHelper.notifyCalled(); + } + } + + private static class JavascriptAppModalDialogShownCriteria extends Criteria { + private final boolean mShouldBeShown; + + public JavascriptAppModalDialogShownCriteria(String error, boolean shouldBeShown) { + super(error); + mShouldBeShown = shouldBeShown; + } + + @Override + public boolean isSatisfied() { + try { + return ThreadUtils.runOnUiThreadBlocking(() -> { + final boolean isShown = + JavascriptAppModalDialog.getCurrentDialogForTest() != null; + return mShouldBeShown == isShown; + }); + } catch (ExecutionException e) { + Log.e(TAG, "Failed to getCurrentDialog", e); + return false; + } + } + } + + private TestCallbackHelperContainer getActiveTabTestCallbackHelperContainer() { + return new TestCallbackHelperContainer(mActivityTestRule.getWebContents()); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/jsdialog/JavascriptTabModalDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/jsdialog/JavascriptTabModalDialogTest.java index e35ef97b..98420e6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/jsdialog/JavascriptTabModalDialogTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/jsdialog/JavascriptTabModalDialogTest.java
@@ -47,17 +47,14 @@ import java.util.concurrent.TimeoutException; /** - * Test suite for displaying and functioning of JavaScript tab modal dialogs. Some of the tests - * are identical to ModalDialogTest.java and some are for tab-modal features. + * Test suite for displaying and functioning of tab modal JavaScript alert, confirm and prompt. */ @RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags. -Add({"enable-features=TabModalJsDialog", ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) public class JavascriptTabModalDialogTest { @Rule public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); - private static final String TAG = "JsTabModalDialogTest"; private static final String EMPTY_PAGE = UrlUtils.encodeHtmlDataUri( "<html><title>Modal Dialog Test</title><p>Testcase.</p></title></html>"); private static final String OTHER_PAGE = UrlUtils.encodeHtmlDataUri( @@ -193,6 +190,9 @@ mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); assertScrollViewFocusabilityInAlertDialog( "alert(new Array(200).join('Long message!'));", true); + + // Reset to portrait mode. + mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } private void assertScrollViewFocusabilityInAlertDialog(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogManagerTest.java index edefe617..ecb88f01 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/modaldialog/ModalDialogManagerTest.java
@@ -17,6 +17,7 @@ import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.not; +import android.content.res.Resources; import android.support.test.InstrumentationRegistry; import android.support.test.espresso.Espresso; import android.support.test.filters.SmallTest; @@ -38,6 +39,8 @@ import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.modaldialog.ModalDialogManager.ModalDialogType; +import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; @@ -762,11 +765,20 @@ } } }; - final ModalDialogView.Params p = new ModalDialogView.Params(); - p.title = Integer.toString(index); - p.positiveButtonTextId = R.string.ok; - p.negativeButtonTextId = R.string.cancel; - return new ModalDialogView(controller, p); + Resources resources = mActivity.getResources(); + final PropertyModel model = + new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) + .with(ModalDialogProperties.CONTROLLER, controller) + .with(ModalDialogProperties.TITLE, Integer.toString(index)) + .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, + R.string.ok) + .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, + R.string.cancel) + .build(); + + ModalDialogView dialogView = new ModalDialogView(mActivity); + PropertyModelChangeProcessor.create(model, dialogView, new ModalDialogViewBinder()); + return dialogView; }); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionAnswerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionAnswerTest.java deleted file mode 100644 index 68c4691..0000000 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionAnswerTest.java +++ /dev/null
@@ -1,133 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.omnibox.suggestions; - -import android.support.test.filters.SmallTest; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.chromium.base.test.BaseJUnit4ClassRunner; - -@RunWith(BaseJUnit4ClassRunner.class) -public class SuggestionAnswerTest { - @Test - @SmallTest - public void testMalformedJsonReturnsNull() { - String json = "} malformed json {"; - SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json); - Assert.assertNull(answer); - } - - @Test - @SmallTest - public void testEmpyJsonReturnsNull() { - String json = ""; - SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json); - Assert.assertNull(answer); - } - - @Test - @SmallTest - public void testOneLineReturnsNull() { - String json = "{ 'l': [" - + " { 'il': { 't': [{ 't': 'text', 'tt': 8 }] } }, " - + "] }"; - SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json); - Assert.assertNull(answer); - } - - @Test - @SmallTest - public void testTwoLinesDoesntReturnNull() { - String json = "{ 'l': [" - + " { 'il': { 't': [{ 't': 'text', 'tt': 8 }] } }, " - + " { 'il': { 't': [{ 't': 'other text', 'tt': 5 }] } }" - + "] }"; - SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json); - Assert.assertNotNull(answer); - } - - @Test - @SmallTest - public void testThreeLinesReturnsNull() { - String json = "{ 'l': [" - + " { 'il': { 't': [{ 't': 'text', 'tt': 8 }] } }, " - + " { 'il': { 't': [{ 't': 'other text', 'tt': 5 }] } }" - + " { 'il': { 't': [{ 't': 'yet more text', 'tt': 13 }] } }" - + "] }"; - SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json); - Assert.assertNull(answer); - } - - @Test - @SmallTest - public void testFiveLinesReturnsNull() { - String json = "{ 'l': [" - + " { 'il': { 't': [{ 't': 'line 1', 'tt': 0 }] } }, " - + " { 'il': { 't': [{ 't': 'line 2', 'tt': 5 }] } }" - + " { 'il': { 't': [{ 't': 'line 3', 'tt': 13 }] } }" - + " { 'il': { 't': [{ 't': 'line 4', 'tt': 14 }] } }" - + " { 'il': { 't': [{ 't': 'line 5', 'tt': 5 }] } }" - + "] }"; - SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json); - Assert.assertNull(answer); - } - - @Test - @SmallTest - public void testPropertyPresence() { - String json = "{ 'l': [" - + " { 'il': { 't': [{ 't': 'text', 'tt': 8 }, { 't': 'moar', 'tt': 0 }], " - + " 'i': { 'd': 'http://example.com/foo.jpg' } } }, " - + " { 'il': { 't': [{ 't': 'other text', 'tt': 5 }], " - + " 'at': { 't': 'slatfotf', 'tt': 42 }, " - + " 'st': { 't': 'oh hi, Mark', 'tt': 7666 } } } " - + "] }"; - SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json); - - SuggestionAnswer.ImageLine firstLine = answer.getFirstLine(); - Assert.assertEquals(2, firstLine.getTextFields().size()); - Assert.assertFalse(firstLine.hasAdditionalText()); - Assert.assertFalse(firstLine.hasStatusText()); - Assert.assertTrue(firstLine.hasImage()); - - SuggestionAnswer.ImageLine secondLine = answer.getSecondLine(); - Assert.assertEquals(1, secondLine.getTextFields().size()); - Assert.assertTrue(secondLine.hasAdditionalText()); - Assert.assertTrue(secondLine.hasStatusText()); - Assert.assertFalse(secondLine.hasImage()); - } - - @Test - @SmallTest - public void testContents() { - String json = "{ 'l': [" - + " { 'il': { 't': [{ 't': 'text', 'tt': 8 }, { 't': 'moar', 'tt': 0 }], " - + " 'at': { 't': 'hi there', 'tt': 7 } } }, " - + " { 'il': { 't': [{ 't': 'ftw', 'tt': 6006 }], " - + " 'st': { 't': 'shop S-Mart', 'tt': 666 }, " - + " 'i': { 'd': '//Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGlj' } } } " - + "] }"; - SuggestionAnswer answer = SuggestionAnswer.parseAnswerContents(json); - - SuggestionAnswer.ImageLine firstLine = answer.getFirstLine(); - Assert.assertEquals("text", firstLine.getTextFields().get(0).getText()); - Assert.assertEquals(8, firstLine.getTextFields().get(0).getType()); - Assert.assertEquals("moar", firstLine.getTextFields().get(1).getText()); - Assert.assertEquals(0, firstLine.getTextFields().get(1).getType()); - Assert.assertEquals("hi there", firstLine.getAdditionalText().getText()); - Assert.assertEquals(7, firstLine.getAdditionalText().getType()); - - SuggestionAnswer.ImageLine secondLine = answer.getSecondLine(); - Assert.assertEquals("ftw", secondLine.getTextFields().get(0).getText()); - Assert.assertEquals(6006, secondLine.getTextFields().get(0).getType()); - Assert.assertEquals("shop S-Mart", secondLine.getStatusText().getText()); - Assert.assertEquals(666, secondLine.getStatusText().getType()); - Assert.assertEquals( - "https://Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGlj", secondLine.getImage()); - } -}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/VoiceSuggestionProviderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/VoiceSuggestionProviderTest.java index 6106da8..a11422f7 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/VoiceSuggestionProviderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/VoiceSuggestionProviderTest.java
@@ -40,8 +40,8 @@ List<MatchClassification> classifications = new ArrayList<>(); classifications.add(new MatchClassification(0, MatchClassificationStyle.NONE)); return new OmniboxSuggestion(OmniboxSuggestionType.SEARCH_SUGGEST, true, 0, 1, text, - classifications, null, classifications, null, null, "", "http://www.google.com", - false, false); + classifications, null, classifications, null, "", "http://www.google.com", false, + false); } private static List<OmniboxSuggestion> createDummySuggestions(String... texts) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java index 30eecb06..18c5692 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java
@@ -336,9 +336,10 @@ protected void clickCardUnmaskButtonAndWait(final int dialogButtonId, CallbackHelper helper) throws InterruptedException, TimeoutException { int callCount = helper.getCallCount(); - ThreadUtils.runOnUiThreadBlocking( - (Runnable) () -> mCardUnmaskPrompt.getDialogForTest().getButton( - dialogButtonId).performClick()); + ThreadUtils.runOnUiThreadBlocking((Runnable) () + -> mCardUnmaskPrompt.getDialogForTest() + .getButtonForTesting(dialogButtonId) + .performClick()); helper.waitForCallback(callCount); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/developer/TracingPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/developer/TracingPreferencesTest.java index d1028e1..47d63b8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/developer/TracingPreferencesTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/developer/TracingPreferencesTest.java
@@ -8,13 +8,19 @@ import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; +import android.app.AlertDialog; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; +import android.preference.CheckBoxPreference; +import android.preference.ListPreference; +import android.preference.Preference; import android.preference.PreferenceFragment; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.filters.SmallTest; import android.support.v4.app.NotificationCompat; +import android.util.Pair; import org.junit.After; import org.junit.Assert; @@ -41,12 +47,14 @@ import org.chromium.chrome.browser.tracing.TracingNotificationManager; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.util.ActivityUtils; import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.notifications.MockNotificationManagerProxy; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; import java.io.File; +import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; @@ -100,6 +108,41 @@ }, scaleTimeout(15000) /* maxTimeoutMs */, 50 /* checkIntervalMs */); } + private void waitForTracingControllerInitialization(PreferenceFragment fragment) + throws Exception { + final Preference defaultCategoriesPref = + fragment.findPreference(TracingPreferences.UI_PREF_DEFAULT_CATEGORIES); + final Preference nonDefaultCategoriesPref = + fragment.findPreference(TracingPreferences.UI_PREF_NON_DEFAULT_CATEGORIES); + final Preference modePref = fragment.findPreference(TracingPreferences.UI_PREF_MODE); + final Preference startTracingButton = + fragment.findPreference(TracingPreferences.UI_PREF_START_RECORDING); + + CallbackHelper callbackHelper = new CallbackHelper(); + ThreadUtils.runOnUiThreadBlocking(() -> { + if (TracingController.getInstance().getState() + == TracingController.State.INITIALIZING) { + // Controls should be disabled while initializing. + Assert.assertFalse(defaultCategoriesPref.isEnabled()); + Assert.assertFalse(nonDefaultCategoriesPref.isEnabled()); + Assert.assertFalse(modePref.isEnabled()); + Assert.assertFalse(startTracingButton.isEnabled()); + + TracingController.getInstance().addObserver(new TracingController.Observer() { + @Override + public void onTracingStateChanged(@TracingController.State int state) { + callbackHelper.notifyCalled(); + TracingController.getInstance().removeObserver(this); + } + }); + return; + } + // Already initialized. + callbackHelper.notifyCalled(); + }); + callbackHelper.waitForCallback(0 /* currentCallCount */); + } + @Test @MediumTest @Feature({"Preferences"}) @@ -114,30 +157,13 @@ final ButtonPreference startTracingButton = (ButtonPreference) fragment.findPreference( TracingPreferences.UI_PREF_START_RECORDING); - // Wait for TracingController to initialize and button to get enabled. - CallbackHelper callbackHelper = new CallbackHelper(); - ThreadUtils.runOnUiThreadBlocking(() -> { - if (TracingController.getInstance().getState() - == TracingController.State.INITIALIZING) { - Assert.assertFalse(startTracingButton.isEnabled()); - TracingController.getInstance().addObserver(new TracingController.Observer() { - @Override - public void onTracingStateChanged(@TracingController.State int state) { - callbackHelper.notifyCalled(); - TracingController.getInstance().removeObserver(this); - } - }); - return; - } - // Already initialized. - callbackHelper.notifyCalled(); - }); - callbackHelper.waitForCallback(0 /* currentCallCount */); + waitForTracingControllerInitialization(fragment); // Setting to IDLE state tries to dismiss the (non-existent) notification. waitForNotificationManagerMutation(); Assert.assertEquals(0, mMockNotificationManager.getNotifications().size()); + CallbackHelper callbackHelper = new CallbackHelper(); ThreadUtils.runOnUiThreadBlocking(() -> { Assert.assertEquals( TracingController.State.IDLE, TracingController.getInstance().getState()); @@ -180,7 +206,7 @@ }); // Wait for state change to RECORDING. - callbackHelper.waitForCallback(1 /* currentCallCount */); + callbackHelper.waitForCallback(0 /* currentCallCount */); // Recording started, a notification with a stop button should be displayed. Notification notification = waitForNotification().notification; @@ -191,7 +217,7 @@ // Initiate stopping the recording and wait for state changes to STOPPING and STOPPED. stopIntent.send(); - callbackHelper.waitForCallback(2 /* currentCallCount */, 2 /* numberOfCallsToWaitFor */, + callbackHelper.waitForCallback(1 /* currentCallCount */, 2 /* numberOfCallsToWaitFor */, scaleTimeout(15000) /* timeout */, TimeUnit.MILLISECONDS); // Notification should be replaced twice, once with an "is stopping" notification and then @@ -211,7 +237,7 @@ // Discard the trace and wait for state change back to IDLE. deleteIntent.send(); - callbackHelper.waitForCallback(4 /* currentCallCount */); + callbackHelper.waitForCallback(3 /* currentCallCount */); // The temporary file should be deleted. Assert.assertFalse(tempFile.exists()); @@ -238,24 +264,7 @@ (TextMessagePreference) fragment.findPreference( TracingPreferences.UI_PREF_TRACING_STATUS); - // Wait for TracingController to initialize. - CallbackHelper callbackHelper = new CallbackHelper(); - ThreadUtils.runOnUiThreadBlocking(() -> { - if (TracingController.getInstance().getState() - == TracingController.State.INITIALIZING) { - Assert.assertFalse(startTracingButton.isEnabled()); - TracingController.getInstance().addObserver(new TracingController.Observer() { - @Override - public void onTracingStateChanged(@TracingController.State int state) { - callbackHelper.notifyCalled(); - TracingController.getInstance().removeObserver(this); - } - }); - return; - } - callbackHelper.notifyCalled(); - }); - callbackHelper.waitForCallback(0 /* currentCallCount */); + waitForTracingControllerInitialization(fragment); Assert.assertFalse(startTracingButton.isEnabled()); Assert.assertEquals(context.getString(R.string.tracing_notifications_disabled), @@ -263,4 +272,108 @@ mMockNotificationManager.setNotificationsEnabled(true); } + + @Test + @MediumTest + @Feature({"Preferences"}) + @Features.EnableFeatures(ChromeFeatureList.DEVELOPER_PREFERENCES) + public void testSelectCategories() throws Exception { + Context context = ContextUtils.getApplicationContext(); + // We need a renderer so that its tracing categories will be populated. + mActivityTestRule.startMainActivityOnBlankPage(); + Preferences activity = + mActivityTestRule.startPreferences(TracingPreferences.class.getName()); + final PreferenceFragment fragment = (PreferenceFragment) activity.getFragmentForTest(); + final Preference defaultCategoriesPref = + fragment.findPreference(TracingPreferences.UI_PREF_DEFAULT_CATEGORIES); + final Preference nonDefaultCategoriesPref = + fragment.findPreference(TracingPreferences.UI_PREF_NON_DEFAULT_CATEGORIES); + + waitForTracingControllerInitialization(fragment); + + ThreadUtils.runOnUiThreadBlocking(() -> { + Assert.assertTrue(defaultCategoriesPref.isEnabled()); + Assert.assertTrue(nonDefaultCategoriesPref.isEnabled()); + }); + + // Lists preferences for categories of a specific type and an example category name each. + List<Pair<Preference, String>> categoriesPrefs = + Arrays.asList(new Pair<>(defaultCategoriesPref, "toplevel"), + new Pair<>(nonDefaultCategoriesPref, "disabled-by-default-cc.debug")); + for (Pair<Preference, String> categoriesPrefAndSampleCategory : categoriesPrefs) { + Preference categoriesPref = categoriesPrefAndSampleCategory.first; + String sampleCategoryName = categoriesPrefAndSampleCategory.second; + + // Click the preference, which should open a new preferences fragment in a new activity. + Preferences categoriesActivity = ActivityUtils.waitForActivity( + InstrumentationRegistry.getInstrumentation(), Preferences.class, () -> { + ThreadUtils.runOnUiThreadBlocking(() -> { + PreferencesTest.clickPreference(fragment, categoriesPref); + }); + }); + + PreferenceFragment categoriesFragment = + (PreferenceFragment) categoriesActivity.getFragmentForTest(); + Assert.assertEquals(TracingCategoriesPreferences.class, categoriesFragment.getClass()); + + CheckBoxPreference sampleCategoryPref = + (CheckBoxPreference) categoriesFragment.findPreference(sampleCategoryName); + Assert.assertNotNull(sampleCategoryPref); + + boolean originallyEnabled = + TracingPreferences.getEnabledCategories().contains(sampleCategoryName); + Assert.assertEquals(originallyEnabled, sampleCategoryPref.isChecked()); + + // Simulate selecting / deselecting the category. + ThreadUtils.runOnUiThreadBlocking(() -> { + PreferencesTest.clickPreference(categoriesFragment, sampleCategoryPref); + }); + Assert.assertNotEquals(originallyEnabled, sampleCategoryPref.isChecked()); + boolean finallyEnabled = + TracingPreferences.getEnabledCategories().contains(sampleCategoryName); + Assert.assertNotEquals(originallyEnabled, finallyEnabled); + + // Return to original activity. + Preferences originalActivity = ActivityUtils.waitForActivity( + InstrumentationRegistry.getInstrumentation(), Preferences.class, () -> { + ThreadUtils.runOnUiThreadBlocking(() -> { categoriesActivity.finish(); }); + }); + + Assert.assertEquals(activity, originalActivity); + } + } + + @Test + @SmallTest + @Feature({"Preferences"}) + @Features.EnableFeatures(ChromeFeatureList.DEVELOPER_PREFERENCES) + public void testSelectMode() throws Exception { + Context context = ContextUtils.getApplicationContext(); + Preferences activity = + mActivityTestRule.startPreferences(TracingPreferences.class.getName()); + final PreferenceFragment fragment = (PreferenceFragment) activity.getFragmentForTest(); + final ListPreference modePref = + (ListPreference) fragment.findPreference(TracingPreferences.UI_PREF_MODE); + + waitForTracingControllerInitialization(fragment); + + ThreadUtils.runOnUiThreadBlocking(() -> { + Assert.assertTrue(modePref.isEnabled()); + + // By default, the "record-until-full" mode is selected. + Assert.assertEquals("record-until-full", TracingPreferences.getSelectedTracingMode()); + + // Clicking the pref should open a dialog. + PreferencesTest.clickPreference(fragment, modePref); + Assert.assertNotNull(modePref.getDialog()); + AlertDialog dialog = (AlertDialog) modePref.getDialog(); + Assert.assertEquals(3, dialog.getListView().getAdapter().getCount()); + modePref.getDialog().dismiss(); + + // Simulate changing the mode. + modePref.getOnPreferenceChangeListener().onPreferenceChange( + modePref, "record-continuously"); + Assert.assertEquals("record-continuously", TracingPreferences.getSelectedTracingMode()); + }); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java index f6eb566..08ecd5c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java
@@ -284,7 +284,7 @@ PreferenceScreen preferenceScreen = preferenceFragment.getPreferenceScreen(); int preferenceCount = preferenceScreen.getPreferenceCount(); - ArrayList<String> actualKeys = new ArrayList<String>(); + ArrayList<String> actualKeys = new ArrayList<>(); for (int index = 0; index < preferenceCount; index++) { Preference preference = preferenceScreen.getPreference(index); String key = preference.getKey(); @@ -373,6 +373,36 @@ } /** + * Set a cookie and check that it is removed when a site is cleared. + */ + @Test + @SmallTest + @Feature({"Preferences"}) + public void testClearCookies() throws Exception { + final String url = mTestServer.getURL("/chrome/test/data/android/cookie.html"); + + mActivityTestRule.loadUrl(url); + Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + mActivityTestRule.runJavaScriptCodeInCurrentTab("setCookie()"); + Assert.assertEquals( + "\"Foo=Bar\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + + WebsiteAddress address = WebsiteAddress.create(url); + Website website = new Website(address, address); + final Preferences preferenceActivity = startSingleWebsitePreferences(website); + ThreadUtils.runOnUiThreadBlocking(() -> { + SingleWebsitePreferences websitePreferences = + (SingleWebsitePreferences) preferenceActivity.getFragmentForTest(); + websitePreferences.resetSite(); + }); + preferenceActivity.finish(); + + // Load the page again and ensure the cookie is gone. + mActivityTestRule.loadUrl(url); + Assert.assertEquals("\"\"", mActivityTestRule.runJavaScriptCodeInCurrentTab("getCookie()")); + } + + /** * Sets Allow Popups Enabled to be false and make sure it is set correctly. * @throws Exception */ @@ -696,11 +726,7 @@ } private int getTabCount() { - return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Integer>() { - @Override - public Integer call() throws Exception { - return mActivityTestRule.getActivity().getTabModelSelector().getTotalTabCount(); - } - }); + return ThreadUtils.runOnUiThreadBlockingNoException( + () -> mActivityTestRule.getActivity().getTabModelSelector().getTotalTabCount()); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchActivityTest.java index e94080e..59c6364 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/searchwidget/SearchActivityTest.java
@@ -299,11 +299,11 @@ List<MatchClassification> classifications = new ArrayList<>(); classifications.add(new MatchClassification(0, MatchClassificationStyle.NONE)); OmniboxSuggestion mockSuggestion = new OmniboxSuggestion(0, true, 0, 0, - "https://google.com", classifications, "https://google.com", classifications, "", - "", "", "https://google.com", false, false); + "https://google.com", classifications, "https://google.com", classifications, null, + "", "https://google.com", false, false); OmniboxSuggestion mockSuggestion2 = new OmniboxSuggestion(0, true, 0, 0, - "https://android.com", classifications, "https://android.com", classifications, "", - "", "", "https://android.com", false, false); + "https://android.com", classifications, "https://android.com", classifications, + null, "", "https://android.com", false, false); List<OmniboxSuggestion> list = new ArrayList<>(); list.add(mockSuggestion); list.add(mockSuggestion2);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/JSONTestUtils.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/JSONTestUtils.java similarity index 88% rename from chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/JSONTestUtils.java rename to chrome/android/junit/src/org/chromium/chrome/browser/media/router/JSONTestUtils.java index 28e232c..f401ce4 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/JSONTestUtils.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/JSONTestUtils.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.media.router.cast; +package org.chromium.chrome.browser.media.router; import org.json.JSONArray; import org.json.JSONException; @@ -13,7 +13,6 @@ /** * Utilities for comparing JSON objects and strings. - * TODO(zqzhang): Move the class to somewhere more generic. */ public class JSONTestUtils { private static final String TAG = "MediaRouter"; @@ -36,6 +35,7 @@ return true; } + /** Returns whether two JSON arrays are equal. */ public static boolean isJSONArrayEqual(JSONArray expected, JSONArray actual) { try { if (expected.length() != actual.length()) return false; @@ -48,6 +48,7 @@ return true; } + /** Returns whether two JSON objects are equal. */ public static boolean isJSONObjectEqual(Object expected, Object actual) { if (expected == null && actual == null) return true; if (expected == null || actual == null) return false; @@ -74,7 +75,8 @@ } } - static class JSONObjectLike implements ArgumentMatcher<JSONObject> { + /** Matcher to determine whether a JSON object is equal to the expected one. */ + public static class JSONObjectLike implements ArgumentMatcher<JSONObject> { private final JSONObject mExpected; public JSONObjectLike(JSONObject expected) { @@ -92,7 +94,8 @@ } } - static class JSONStringLike implements ArgumentMatcher<String> { + /** Matcher to determine whether a JSON string is equal to the expected one. */ + public static class JSONStringLike implements ArgumentMatcher<String> { private JSONObject mExpected; public JSONStringLike(JSONObject expected) {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/CafBaseMediaRouteProviderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/CafBaseMediaRouteProviderTest.java index 06817707..be61129 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/CafBaseMediaRouteProviderTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/CafBaseMediaRouteProviderTest.java
@@ -50,7 +50,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Map; /** * Robolectric tests for CafBaseMediaRouteProvider. @@ -394,9 +393,9 @@ inOrder.verify(mSessionController).attachToCastSession(mCastSession); inOrder.verify(mSessionController).onSessionStarted(); - assertEquals(mProvider.getRoutes().size(), 1); + assertEquals(mProvider.mRoutes.size(), 1); - MediaRoute route = (MediaRoute) (mProvider.getRoutes().values().toArray()[0]); + MediaRoute route = (MediaRoute) (mProvider.mRoutes.values().toArray()[0]); assertEquals(route.sinkId, "cast-route"); assertEquals(route.sourceId, "source-id"); assertEquals(route.presentationId, "presentation-id"); @@ -586,10 +585,10 @@ } private void assertContainsRoutes(MediaRoute... routes) { - assertEquals(mProvider.getRoutes().size(), routes.length); + assertEquals(mProvider.mRoutes.size(), routes.length); for (MediaRoute route : routes) { - assertEquals(mProvider.getRoutes().get(route.id), route); + assertEquals(mProvider.mRoutes.get(route.id), route); } } @@ -614,9 +613,5 @@ @Override public void joinRoute(String routeId, String presentationId, String origin, int tabId, int nativeRequestId) {} - - public Map<String, MediaRoute> getRoutes() { - return mRoutes; - } } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/CafMediaRouteProviderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/CafMediaRouteProviderTest.java new file mode 100644 index 0000000..329de164 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/CafMediaRouteProviderTest.java
@@ -0,0 +1,444 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.media.router.caf; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyBoolean; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import android.content.Context; +import android.support.v7.media.MediaRouter; + +import com.google.android.gms.cast.framework.CastContext; +import com.google.android.gms.cast.framework.CastSession; +import com.google.android.gms.cast.framework.SessionManager; +import com.google.android.gms.cast.framework.media.RemoteMediaClient; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowLooper; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.media.router.ClientRecord; +import org.chromium.chrome.browser.media.router.MediaRoute; +import org.chromium.chrome.browser.media.router.MediaRouteManager; +import org.chromium.chrome.browser.media.router.MediaSink; +import org.chromium.chrome.browser.media.router.cast.CastMediaSource; + +/** + * Robolectric tests for CafMediaRouteProvider. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE, + shadows = {ShadowMediaRouter.class, ShadowCastContext.class, ShadowLooper.class, + ShadowCastMediaSource.class}) +public class CafMediaRouteProviderTest { + private static final String SUPPORTED_SOURCE = "cast:DEADBEEF"; + + private static final String SUPPORTED_AUTOJOIN_SOURCE = "cast:DEADBEEF" + + "?clientId=12345&autoJoinPolicy=" + CastMediaSource.AUTOJOIN_TAB_AND_ORIGIN_SCOPED; + + private Context mContext; + private CafMediaRouteProvider mProvider; + private MediaRouterTestHelper mMediaRouterHelper; + private MediaRouter mMediaRouter; + private MediaRoute mRoute1; + private MediaRoute mRoute2; + + @Mock + private MediaRouteManager mManager; + @Mock + private CastContext mCastContext; + @Mock + private CastSession mCastSession; + @Mock + private SessionManager mSessionManager; + @Mock + private RemoteMediaClient mRemoteMediaClient; + @Mock + private BaseSessionController mSessionController; + @Mock + private ShadowCastMediaSource.ShadowImplementation mShadowCastMediaSource; + @Mock + private CafMessageHandler mMessageHandler; + @Mock + private CastMediaSource mSource1; + @Mock + private CastMediaSource mSource2; + @Mock + private MediaSink mSink; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + ShadowCastContext.setInstance(mCastContext); + ShadowCastMediaSource.setImplementation(mShadowCastMediaSource); + mMediaRouterHelper = new MediaRouterTestHelper(); + mMediaRouter = MediaRouter.getInstance(mContext); + mProvider = spy(CafMediaRouteProvider.create(mManager)); + mProvider.mMessageHandler = mMessageHandler; + + mRoute1 = new MediaRoute("sink-id", "source-id-1", "presentation-id-1"); + mRoute2 = new MediaRoute("sink-id", "source-id-2", "presentation-id-2"); + doReturn(mSource1).when(mShadowCastMediaSource).from("source-id-1"); + doReturn(mSource2).when(mShadowCastMediaSource).from("source-id-2"); + doReturn("client-id-1").when(mSource1).getClientId(); + doReturn("client-id-2").when(mSource2).getClientId(); + doReturn("app-id-1").when(mSource1).getApplicationId(); + doReturn("app-id-2").when(mSource2).getApplicationId(); + doReturn("sink-id").when(mSink).getId(); + doReturn(mSessionController).when(mProvider).sessionController(); + doReturn(mSessionManager).when(mCastContext).getSessionManager(); + doReturn(mCastSession).when(mSessionController).getSession(); + doReturn(mRemoteMediaClient).when(mCastSession).getRemoteMediaClient(); + } + + @Test + public void testJoinRoute() { + InOrder inOrder = inOrder(mManager); + + doReturn(mSource1).when(mShadowCastMediaSource).from("source-id-1"); + doReturn(mSink).when(mSessionController).getSink(); + doReturn(true).when(mSessionController).isConnected(); + doReturn(true).when(mProvider).canJoinExistingSession( + anyString(), anyString(), anyInt(), any(CastMediaSource.class)); + + // Regular case. + mProvider.joinRoute("source-id-1", "presentation-id-1", "origin", 1, 1); + inOrder.verify(mManager, never()).onRouteRequestError(anyString(), anyInt()); + inOrder.verify(mManager).onRouteCreated( + anyString(), eq("sink-id"), eq(1), eq(mProvider), eq(false)); + assertEquals(mProvider.mRoutes.size(), 1); + MediaRoute route = (MediaRoute) (mProvider.mRoutes.values().toArray()[0]); + assertEquals(route.sinkId, "sink-id"); + assertEquals(route.sourceId, "source-id-1"); + assertEquals(route.presentationId, "presentation-id-1"); + + // No source. + mProvider.mRoutes.clear(); + doReturn(null).when(mShadowCastMediaSource).from("source-id-1"); + + mProvider.joinRoute("source-id-1", "presentation-id-1", "origin", 1, 1); + + verifyRouteRequestError(inOrder, "Unsupported presentation URL", 1); + assertTrue(mProvider.mRoutes.isEmpty()); + + // No client ID. + doReturn(mSource1).when(mShadowCastMediaSource).from("source-id-1"); + doReturn(null).when(mSource1).getClientId(); + + mProvider.joinRoute("source-id-1", "presentation-id-1", "origin", 1, 1); + + verifyRouteRequestError(inOrder, "Unsupported presentation URL", 1); + assertTrue(mProvider.mRoutes.isEmpty()); + + // No session. + doReturn("client-id-1").when(mSource1).getClientId(); + doReturn(false).when(mSessionController).isConnected(); + + mProvider.joinRoute("source-id-1", "presentation-id-1", "origin", 1, 1); + + verifyRouteRequestError(inOrder, "No presentation", 1); + assertTrue(mProvider.mRoutes.isEmpty()); + + // No matching route. + doReturn(true).when(mSessionController).isConnected(); + doReturn(false).when(mProvider).canJoinExistingSession( + anyString(), anyString(), anyInt(), any(CastMediaSource.class)); + + mProvider.joinRoute("source-id-1", "presentation-id-1", "origin", 1, 1); + + verifyRouteRequestError(inOrder, "No matching route", 1); + assertTrue(mProvider.mRoutes.isEmpty()); + } + + @Test + public void testCloseRoute() { + InOrder inOrder = inOrder(mMessageHandler); + + doReturn(mSink).when(mSessionController).getSink(); + + // Regular case when there is active session. + mProvider.addRoute(mRoute1, "origin", 1, 1, false); + doReturn(true).when(mSessionController).isConnected(); + + mProvider.closeRoute(mRoute1.id); + + inOrder.verify(mMessageHandler) + .sendReceiverActionToClient(mRoute1.id, mSink, "client-id-1", "stop"); + assertEquals(mProvider.mRoutes.size(), 1); + assertEquals(mProvider.getClientIdToRecords().size(), 1); + + // Abnormal case when the session controller doesn't have a sink. + doReturn(null).when(mSessionController).getSink(); + + mProvider.closeRoute(mRoute1.id); + + inOrder.verify(mMessageHandler, never()) + .sendReceiverActionToClient( + anyString(), any(MediaSink.class), anyString(), anyString()); + assertEquals(mProvider.mRoutes.size(), 1); + assertEquals(mProvider.getClientIdToRecords().size(), 1); + + // Abnormal case when there is no session. + doReturn(mSink).when(mSessionController).getSink(); + doReturn(false).when(mSessionController).isConnected(); + + mProvider.closeRoute(mRoute1.id); + + inOrder.verify(mMessageHandler, never()) + .sendReceiverActionToClient( + anyString(), any(MediaSink.class), anyString(), anyString()); + assertTrue(mProvider.mRoutes.isEmpty()); + assertTrue(mProvider.getClientIdToRecords().isEmpty()); + } + + @Test + public void testSendStringMessage() { + InOrder inOrder = inOrder(mMessageHandler); + + mProvider.addRoute(mRoute1, "origin", 1, 1, false); + + // A client in record sends a message. + mProvider.sendStringMessage(mRoute1.id, "message"); + inOrder.verify(mMessageHandler).handleMessageFromClient("message"); + + // An unknown client sends a mesasge. + mProvider.sendStringMessage("other-route-id", "message"); + inOrder.verify(mMessageHandler, never()).handleMessageFromClient(anyString()); + } + + @Test + public void testSendMessageToClient() { + InOrder inOrder = inOrder(mManager); + + mProvider.addRoute(mRoute1, "origin", 1, 1, false); + mProvider.getClientIdToRecords().get("client-id-1").isConnected = true; + + // Normal case. + mProvider.sendMessageToClient("client-id-1", "message"); + inOrder.verify(mManager).onMessage(mRoute1.id, "message"); + + // Client is not in record. + mProvider.sendMessageToClient("client-id-unkonwn", "message"); + inOrder.verify(mManager, never()).onMessage(anyString(), anyString()); + + // Message enqueued while client is not connected. + mProvider.getClientIdToRecords().get("client-id-1").isConnected = false; + mProvider.sendMessageToClient("client-id-1", "message"); + inOrder.verify(mManager, never()).onMessage(anyString(), anyString()); + + // Flush message + mProvider.flushPendingMessagesToClient(mProvider.getClientIdToRecords().get("client-id-1")); + inOrder.verify(mManager).onMessage(mRoute1.id, "message"); + } + + @Test + public void testOnSessionStarted() { + InOrder inOrder = inOrder(mSessionController, mRemoteMediaClient); + + doReturn(mSink).when(mSessionController).getSink(); + + // Prepare the pending create route request so super.onSessionStarted() behaves correctly. + mProvider.createRoute( + "source-id-1", "cast-route", "presentation-id", "origin", 1, false, 1); + + mProvider.addRoute(mRoute1, "origin", 1, 1, false); + mProvider.addRoute(mRoute2, "origin", 1, 1, false); + + // Skip adding route when the super.onSessionStarted() is called. + doNothing().when(mProvider).addRoute( + any(MediaRoute.class), anyString(), anyInt(), anyInt(), anyBoolean()); + mProvider.onSessionStarted(mCastSession, "session-id"); + + // Verify super.onSessionStarted() is called. + inOrder.verify(mSessionController).attachToCastSession(mCastSession); + inOrder.verify(mRemoteMediaClient).requestStatus(); + verify(mMessageHandler) + .sendReceiverActionToClient(mRoute1.id, mSink, "client-id-1", "cast"); + verify(mMessageHandler) + .sendReceiverActionToClient(mRoute2.id, mSink, "client-id-2", "cast"); + } + + @Test + public void testRouteManagement() { + // Add the first route. + mProvider.addRoute(mRoute1, "origin-1", 1, 1, false); + assertEquals(mProvider.mRoutes.size(), 1); + assertEquals(mProvider.getClientIdToRecords().size(), 1); + ClientRecord record = mProvider.getClientIdToRecords().get("client-id-1"); + verifyClientRecord(record, mRoute1.id, "client-id-1", "app-id-1", "origin-1", 1, false); + + // Add the second route. + mProvider.addRoute(mRoute2, "origin-2", 2, 2, false); + assertEquals(mProvider.mRoutes.size(), 2); + assertEquals(mProvider.getClientIdToRecords().size(), 2); + record = mProvider.getClientIdToRecords().get("client-id-2"); + verifyClientRecord(record, mRoute2.id, "client-id-2", "app-id-2", "origin-2", 2, false); + + // Add a duplicate route. This addition will be ignored as `mRoute2` is already in record. + // This should never happen in production. + mProvider.addRoute(mRoute2, "origin-3", 3, 3, false); + assertEquals(mProvider.mRoutes.size(), 2); + assertEquals(mProvider.getClientIdToRecords().size(), 2); + record = mProvider.getClientIdToRecords().get("client-id-2"); + verifyClientRecord(record, mRoute2.id, "client-id-2", "app-id-2", "origin-2", 2, false); + + // Remove a route. + ClientRecord lastRecord = mProvider.getClientIdToRecords().get("client-id-1"); + mProvider.removeRoute(mRoute1.id, null); + assertEquals(mProvider.mRoutes.size(), 1); + assertEquals(mProvider.getClientIdToRecords().size(), 1); + record = mProvider.getClientIdToRecords().get("client-id-2"); + verifyClientRecord(record, mRoute2.id, "client-id-2", "app-id-2", "origin-2", 2, false); + assertEquals(mProvider.mLastRemovedRouteRecord, lastRecord); + + // Remove a non-existing route. + mProvider.removeRoute(mRoute1.id, null); + assertEquals(mProvider.mRoutes.size(), 1); + assertEquals(mProvider.getClientIdToRecords().size(), 1); + record = mProvider.getClientIdToRecords().get("client-id-2"); + verifyClientRecord(record, mRoute2.id, "client-id-2", "app-id-2", "origin-2", 2, false); + lastRecord = record; + + // Remove the last route. + mProvider.removeRoute(mRoute2.id, null); + assertTrue(mProvider.mRoutes.isEmpty()); + assertTrue(mProvider.getClientIdToRecords().isEmpty()); + assertEquals(mProvider.mLastRemovedRouteRecord, lastRecord); + } + + @Test + public void testCanJoin_matchingSessionId() { + // Regular case. + doReturn("session-id").when(mSessionController).getSessionId(); + assertTrue(mProvider.canJoinExistingSession( + "cast-session_session-id", "origin", 1, mock(CastMediaSource.class))); + + // The current session ID is null. + doReturn(null).when(mSessionController).getSessionId(); + assertFalse(mProvider.canJoinExistingSession( + "cast-session_session-id", "origin", 1, mock(CastMediaSource.class))); + + // Mismatching session ID. + doReturn("session-id").when(mSessionController).getSessionId(); + assertFalse(mProvider.canJoinExistingSession( + "cast-session_other-session-id", "origin", 1, mock(CastMediaSource.class))); + } + + @Test + public void testAutoJoin_usingLastRemovedRouteRecord() { + doReturn("app-id-1").when(mSource1).getApplicationId(); + doReturn("app-id-1").when(mSource2).getApplicationId(); + doReturn("tab_and_origin_scoped").when(mSource2).getAutoJoinPolicy(); + doReturn(mSource1).when(mSessionController).getSource(); + + mProvider.addRoute(mRoute1, "origin-1", 1, 1, false); + mProvider.removeRoute(mRoute1.id, null); + + // Regular case. + assertTrue(mProvider.canJoinExistingSession("auto-join", "origin-1", 1, mSource2)); + + // Mismatching origin. + assertFalse(mProvider.canJoinExistingSession("auto-join", "origin-2", 1, mSource2)); + + // Mismatching tab id. + assertFalse(mProvider.canJoinExistingSession("auto-join", "origin-1", 2, mSource2)); + } + + @Test + public void testAutoJoin_mismatchingSources() { + doReturn("app-id-1").when(mSource1).getApplicationId(); + doReturn("app-id-1").when(mSource2).getApplicationId(); + doReturn("tab_and_origin_scoped").when(mSource2).getAutoJoinPolicy(); + doReturn(mSource1).when(mSessionController).getSource(); + + mProvider.addRoute(mRoute1, "origin-1", 1, 1, false); + mProvider.removeRoute(mRoute1.id, null); + + // Page scoped auto-join policy. + doReturn("page_scoped").when(mSource2).getAutoJoinPolicy(); + assertFalse(mProvider.canJoinExistingSession("auto-join", "origin-1", 1, mSource2)); + + // Mismatching app ID. + doReturn("tab_and_origin_scoped").when(mSource2).getAutoJoinPolicy(); + doReturn("app-id-2").when(mSource2).getApplicationId(); + assertFalse(mProvider.canJoinExistingSession("auto-join", "origin-1", 1, mSource2)); + } + + @Test + public void testAutoJoin_originScoped() { + doReturn("app-id-1").when(mSource1).getApplicationId(); + doReturn("app-id-1").when(mSource2).getApplicationId(); + doReturn("origin_scoped").when(mSource2).getAutoJoinPolicy(); + doReturn(mSource1).when(mSessionController).getSource(); + + mProvider.addRoute(mRoute1, "origin-1", 1, 1, false); + + // Normal case. + assertTrue(mProvider.canJoinExistingSession("auto-join", "origin-1", 1, mSource2)); + + // Mismatching tab ID is allowed. + assertTrue(mProvider.canJoinExistingSession("auto-join", "origin-1", 2, mSource2)); + + // Mismatching origin is not allowed. + assertFalse(mProvider.canJoinExistingSession("auto-join", "origin-2", 1, mSource2)); + } + + @Test + public void testAutoJoin_tabAndOriginScoped() { + doReturn("app-id-1").when(mSource1).getApplicationId(); + doReturn("app-id-1").when(mSource2).getApplicationId(); + doReturn("tab_and_origin_scoped").when(mSource2).getAutoJoinPolicy(); + doReturn(mSource1).when(mSessionController).getSource(); + + mProvider.addRoute(mRoute1, "origin-1", 1, 1, false); + + // Normal case. + assertTrue(mProvider.canJoinExistingSession("auto-join", "origin-1", 1, mSource2)); + + // Mismatching tab ID is not allowed. + assertFalse(mProvider.canJoinExistingSession("auto-join", "origin-1", 2, mSource2)); + + // Mismatching origin is not allowed. + assertFalse(mProvider.canJoinExistingSession("auto-join", "origin-2", 1, mSource2)); + } + + private void verifyRouteRequestError(InOrder inOrder, String error, int nativeRequestId) { + inOrder.verify(mManager).onRouteRequestError(error, nativeRequestId); + inOrder.verify(mManager, never()) + .onRouteCreated(anyString(), anyString(), anyInt(), + any(CafBaseMediaRouteProvider.class), anyBoolean()); + } + + private void verifyClientRecord(ClientRecord record, String routeId, String clientId, + String appId, String origin, int tabId, boolean isConnected) { + assertEquals(record.routeId, routeId); + assertEquals(record.clientId, clientId); + assertEquals(record.appId, appId); + assertEquals(record.origin, origin); + assertEquals(record.tabId, tabId); + assertEquals(record.isConnected, isConnected); + } +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/CafMessageHandlerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/CafMessageHandlerTest.java new file mode 100644 index 0000000..e76e1ea --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/CafMessageHandlerTest.java
@@ -0,0 +1,1229 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.media.router.caf; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyDouble; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import com.google.android.gms.cast.ApplicationMetadata; +import com.google.android.gms.cast.CastDevice; +import com.google.android.gms.cast.framework.CastSession; +import com.google.android.gms.common.api.Status; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.media.router.CastSessionUtil; +import org.chromium.chrome.browser.media.router.ClientRecord; +import org.chromium.chrome.browser.media.router.JSONTestUtils.JSONObjectLike; +import org.chromium.chrome.browser.media.router.JSONTestUtils.JSONStringLike; +import org.chromium.chrome.browser.media.router.MediaSink; +import org.chromium.chrome.browser.media.router.caf.CafMessageHandler.RequestRecord; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Robolectric tests for CastSession. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class CafMessageHandlerTest { + private static final String TAG = "MediaRouter"; + + private static final String SESSION_ID = "SESSION_ID"; + private static final String INVALID_SESSION_ID = "INVALID_SESSION_ID"; + private static final String CLIENT_ID1 = "client-id-1"; + private static final String CLIENT_ID2 = "client-id-2"; + private static final String INVALID_CLIENT_ID = "xxxxxxxxxxxxxxxxx"; + private static final String NAMESPACE1 = "namespace1"; + private static final String NAMESPACE2 = "namespace2"; + private static final String MEDIA_NAMESPACE = CastSessionUtil.MEDIA_NAMESPACE; + private static final int SEQUENCE_NUMBER1 = 1; + private static final int SEQUENCE_NUMBER2 = 2; + private static final int REQUEST_ID1 = 1; + private static final int REQUEST_ID2 = 2; + private static final int VOID_SEQUENCE_NUMBER = CafMessageHandler.VOID_SEQUENCE_NUMBER; + private CafMediaRouteProvider mRouteProvider; + @Mock + private CastSession mSession; + @Mock + private CastSessionController mSessionController; + private ClientRecord mClientRecord1; + private ClientRecord mClientRecord2; + private Map<String, ClientRecord> mClientRecordMap; + private CafMessageHandler mMessageHandler; + private int mNumStopApplicationCalled; + + private interface CheckedRunnable { void run() throws Exception; } + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mRouteProvider = mock(CafMediaRouteProvider.class); + mClientRecord1 = + new ClientRecord("route-id-1", CLIENT_ID1, "app-id", "auto-join", "origin", 1); + mClientRecord2 = + new ClientRecord("route-id-2", CLIENT_ID2, "app-id", "auto-join", "origin2", 1); + + mMessageHandler = spy(new CafMessageHandler(mRouteProvider, mSessionController)); + + doReturn(SESSION_ID).when(mSessionController).getSessionId(); + doReturn(true) + .when(mMessageHandler) + .sendStringCastMessage(anyString(), anyString(), anyString(), anyInt()); + doReturn(mSession).when(mSessionController).getSession(); + doReturn(true).when(mSessionController).isConnected(); + doReturn(SESSION_ID).when(mSessionController).getSessionId(); + + mClientRecordMap = new HashMap<>(); + + mClientRecordMap.put(CLIENT_ID1, mClientRecord1); + mClientRecordMap.put(CLIENT_ID2, mClientRecord2); + doReturn(mClientRecordMap).when(mRouteProvider).getClientIdToRecords(); + doNothing().when(mRouteProvider).sendMessageToClient(anyString(), anyString()); + } + + void setUpForAppMessageTest() throws JSONException { + List<String> namespaces = new ArrayList<String>(); + namespaces.add(NAMESPACE1); + doReturn(namespaces).when(mSessionController).getNamespaces(); + doReturn(true) + .when(mMessageHandler) + .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt()); + } + + @Test + public void testOnSessionStarted() { + doReturn("session_message").when(mMessageHandler).buildSessionMessage(); + // The call in setUp() actually only sets the session. This call will notify the clients + // that have sent "client_connect" + mClientRecord1.isConnected = true; + + mMessageHandler.onSessionStarted(); + + verify(mMessageHandler) + .sendEnclosedMessageToClient( + CLIENT_ID1, "new_session", "session_message", VOID_SEQUENCE_NUMBER); + verify(mMessageHandler, never()) + .sendEnclosedMessageToClient(eq(CLIENT_ID2), anyString(), anyString(), anyInt()); + } + + @Test + public void testHandleClientConnectMessage_sessionConnected() throws JSONException { + doReturn("session_message").when(mMessageHandler).buildSessionMessage(); + mClientRecord1.isConnected = false; + JSONObject message = new JSONObject(); + message.put("type", "client_connect"); + message.put("clientId", mClientRecord1.clientId); + + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + + assertTrue(mClientRecord1.isConnected); + verify(mMessageHandler) + .sendEnclosedMessageToClient(mClientRecord1.clientId, "new_session", + "session_message", VOID_SEQUENCE_NUMBER); + verify(mRouteProvider).flushPendingMessagesToClient(mClientRecord1); + } + + @Test + public void testHandleClientConnectMessage_sessionNotConnected() throws JSONException { + doReturn("session_message").when(mMessageHandler).buildSessionMessage(); + doReturn(false).when(mSessionController).isConnected(); + mClientRecord1.isConnected = false; + JSONObject message = new JSONObject(); + message.put("type", "client_connect"); + message.put("clientId", mClientRecord1.clientId); + + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + + assertTrue(mClientRecord1.isConnected); + verify(mMessageHandler, never()) + .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt()); + verify(mRouteProvider).flushPendingMessagesToClient(mClientRecord1); + } + + @Test + public void testHandleClientConnectMessage_noClientRecord() throws JSONException { + doReturn("session_message").when(mMessageHandler).buildSessionMessage(); + JSONObject message = new JSONObject(); + message.put("type", "client_connect"); + message.put("clientId", "other-client-id"); + + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + + verify(mMessageHandler, never()) + .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt()); + verify(mRouteProvider, never()).flushPendingMessagesToClient(any(ClientRecord.class)); + } + + @Test + public void testHandleClientConnectMessage_noClientId() throws JSONException { + doReturn("session_message").when(mMessageHandler).buildSessionMessage(); + JSONObject message = new JSONObject(); + message.put("type", "client_connect"); + + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + + verify(mMessageHandler, never()) + .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt()); + verify(mRouteProvider, never()).flushPendingMessagesToClient(any(ClientRecord.class)); + } + + @Test + public void testHandleClientDisconnectMessage() throws JSONException { + JSONObject message = new JSONObject(); + message.put("type", "client_disconnect"); + message.put("clientId", mClientRecord1.clientId); + + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + + verify(mRouteProvider).removeRoute("route-id-1", null); + } + + @Test + public void testHandleClientDisconnectMessage_noClientRecord() throws JSONException { + JSONObject message = new JSONObject(); + message.put("type", "client_disconnect"); + message.put("clientId", "other-client-id"); + + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + + verify(mRouteProvider, never()).removeRoute(anyString(), anyString()); + } + + @Test + public void testHandleClientDisconnectMessage_noClientId() throws JSONException { + JSONObject message = new JSONObject(); + message.put("type", "client_disconnect"); + + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + + verify(mRouteProvider, never()).removeRoute(anyString(), anyString()); + } + + @Test + public void testHandleClientLeaveSessionMessage() throws JSONException { + JSONObject message = buildLeaveSessionMessage(mClientRecord1.clientId, SESSION_ID, 12345); + ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class); + + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + + verify(mRouteProvider) + .sendMessageToClient(eq(mClientRecord1.clientId), messageCaptor.capture()); + JSONObject capturedMessage = new JSONObject(messageCaptor.getValue()); + verifySimpleSessionMessage( + capturedMessage, "leave_session", 12345, mClientRecord1.clientId); + } + + @Test + public void testHandleClientLeaveSessionMessage_noSequenceNumber() throws JSONException { + JSONObject message = buildLeaveSessionMessage(mClientRecord1.clientId, SESSION_ID, 12345); + message.remove("sequenceNumber"); + ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class); + + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + + verify(mRouteProvider) + .sendMessageToClient(eq(mClientRecord1.clientId), messageCaptor.capture()); + JSONObject capturedMessage = new JSONObject(messageCaptor.getValue()); + verifySimpleSessionMessage( + capturedMessage, "leave_session", VOID_SEQUENCE_NUMBER, mClientRecord1.clientId); + } + + @Test + public void testHandleClientLeaveSessionMessage_noClientRecord() throws JSONException { + JSONObject message = buildLeaveSessionMessage("other-client-id", SESSION_ID, 12345); + + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + + verify(mRouteProvider, never()).sendMessageToClient(anyString(), anyString()); + } + + @Test + public void testHandleClientLeaveSessionMessage_wrongSessionId() throws JSONException { + JSONObject message = + buildLeaveSessionMessage(mClientRecord1.clientId, "other-session-id", 12345); + + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + + verify(mRouteProvider, never()).sendMessageToClient(anyString(), anyString()); + } + + @Test + public void testHandleClientLeaveSessionMessage_sessionNotConnected() throws JSONException { + doReturn(false).when(mSessionController).isConnected(); + JSONObject message = buildLeaveSessionMessage(mClientRecord1.clientId, SESSION_ID, 12345); + + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + + verify(mRouteProvider, never()).sendMessageToClient(anyString(), anyString()); + } + + @Test + public void testHandleClientLeaveSessionMessage_noClientId() throws JSONException { + JSONObject message = buildLeaveSessionMessage(mClientRecord1.clientId, SESSION_ID, 12345); + message.remove("clientId"); + + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + + verify(mRouteProvider, never()).sendMessageToClient(anyString(), anyString()); + } + + @Test + public void testHandleClientLeaveSessionMessage_removeRoutes_tabAndOriginScoped() + throws JSONException { + mClientRecordMap.clear(); + + prepareClientRecord( + "route-id-1", "client-id-1", "app-id", "tab_and_origin_scoped", "origin", 1); + prepareClientRecord("route-id-2", "client-id-2", "app-id", "auto-join", "origin", 1); + prepareClientRecord("route-id-3", "client-id-3", "app-id", "auto-join", "origin2", 1); + prepareClientRecord("route-id-4", "client-id-4", "app-id", "auto-join", "origin", 2); + + JSONObject message = buildLeaveSessionMessage("client-id-1", SESSION_ID, 12345); + + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + + // Only routes with same origin and tab ID will be removed. + verify(mRouteProvider).removeRoute("route-id-1", null); + verify(mRouteProvider).removeRoute("route-id-2", null); + verify(mRouteProvider, never()).removeRoute("route-id-3", null); + verify(mRouteProvider, never()).removeRoute("route-id-4", null); + } + + @Test + public void testHandleClientLeaveSessionMessage_removeRoutes_originScoped() + throws JSONException { + prepareClientRecord("route-id-1", "client-id-1", "app-id", "origin_scoped", "origin", 1); + prepareClientRecord("route-id-2", "client-id-2", "app-id", "auto-join", "origin", 1); + prepareClientRecord("route-id-3", "client-id-3", "app-id", "auto-join", "origin2", 1); + prepareClientRecord("route-id-4", "client-id-4", "app-id", "auto-join", "origin", 2); + + JSONObject message = buildLeaveSessionMessage("client-id-1", SESSION_ID, 12345); + + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + + // Only routes with same origin will be removed. + verify(mRouteProvider).removeRoute("route-id-1", null); + verify(mRouteProvider).removeRoute("route-id-2", null); + verify(mRouteProvider, never()).removeRoute("route-id-3", null); + verify(mRouteProvider).removeRoute("route-id-4", null); + } + + @Test + public void testHandleClientLeaveSessionMessage_removeRoutes_otherScoped() + throws JSONException { + prepareClientRecord("route-id-1", "client-id-1", "app-id", "other_scoped", "origin", 1); + prepareClientRecord("route-id-2", "client-id-2", "app-id", "auto-join", "origin", 1); + prepareClientRecord("route-id-3", "client-id-3", "app-id", "auto-join", "origin2", 1); + prepareClientRecord("route-id-4", "client-id-4", "app-id", "auto-join", "origin", 2); + + JSONObject message = buildLeaveSessionMessage("client-id-1", SESSION_ID, 12345); + + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + + // No route should be removed. + verify(mRouteProvider, never()).removeRoute(anyString(), anyString()); + } + + @Test + public void testHandleSessionMessageOfV2MessageType() throws JSONException { + doReturn(true).when(mMessageHandler).handleCastV2MessageFromClient(any(JSONObject.class)); + + JSONObject message = new JSONObject(); + message.put("type", "v2_message"); + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler).handleCastV2MessageFromClient(argThat(new JSONObjectLike(message))); + } + + @Test + public void testHandleSessionMessageOfAppMessageType() throws JSONException { + doReturn(true).when(mMessageHandler).handleAppMessageFromClient(any(JSONObject.class)); + + JSONObject message = new JSONObject(); + message.put("type", "app_message"); + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler).handleAppMessageFromClient(argThat(new JSONObjectLike(message))); + } + + @Test + public void testHandleSessionMessageOfUnsupportedType() throws JSONException { + doReturn(true).when(mMessageHandler).handleCastV2MessageFromClient(any(JSONObject.class)); + + JSONObject message = new JSONObject(); + message.put("type", "unsupported"); + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler, never()).handleCastV2MessageFromClient(any(JSONObject.class)); + verify(mMessageHandler, never()).handleAppMessageFromClient(any(JSONObject.class)); + } + + @Test + public void testCastV2MessageWithWrongTypeInnerMessage() throws JSONException { + org.robolectric.shadows.ShadowLog.stream = System.out; + JSONObject innerMessage = new JSONObject().put("type", "STOP"); + final JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage); + // Replace the inner JSON message with string. + message.put("message", "wrong type inner message"); + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler, never()).handleStopMessage(anyString(), anyInt()); + verify(mMessageHandler, never()) + .handleVolumeMessage(any(JSONObject.class), anyString(), anyInt()); + verify(mMessageHandler, never()) + .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt()); + } + + @Test + public void testCastV2MessageOfStopType() throws JSONException { + JSONObject innerMessage = new JSONObject().put("type", "STOP"); + JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage); + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler).handleStopMessage(eq(CLIENT_ID1), eq(SEQUENCE_NUMBER1)); + } + + @Test + public void testCastV2MessageofSetVolumeTypeShouldWait() throws Exception { + doReturn(true).when(mSession).isMute(); + JSONObject innerMessage = + new JSONObject() + .put("type", "SET_VOLUME") + .put("volume", + new JSONObject().put("level", (double) 1).put("muted", false)); + JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage); + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + JSONObject volumeMessage = innerMessage.getJSONObject("volume"); + verify(mSession).setMute(false); + verify(mSession).setVolume(1.0); + verify(mMessageHandler) + .handleVolumeMessage( + argThat(new JSONObjectLike(innerMessage.getJSONObject("volume"))), + eq(CLIENT_ID1), eq(SEQUENCE_NUMBER1)); + assertEquals(mMessageHandler.getVolumeRequestsForTest().size(), 1); + } + + @Test + public void testCastV2MessageofSetVolumeTypeShouldNotWait() throws Exception { + doReturn(false).when(mSession).isMute(); + doReturn(1.0).when(mSession).getVolume(); + JSONObject innerMessage = + new JSONObject() + .put("type", "SET_VOLUME") + .put("volume", + new JSONObject().put("level", (double) 1).put("muted", false)); + JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage); + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + JSONObject volumeMessage = innerMessage.getJSONObject("volume"); + verify(mSession, never()).setMute(anyBoolean()); + verify(mSession, never()).setVolume(anyDouble()); + verify(mMessageHandler) + .handleVolumeMessage( + argThat(new JSONObjectLike(innerMessage.getJSONObject("volume"))), + eq(CLIENT_ID1), eq(SEQUENCE_NUMBER1)); + assertEquals(mMessageHandler.getVolumeRequestsForTest().size(), 0); + } + + @Test + public void testCastV2MessageofSetVolumeTypeWithNullVolumeMessage() throws JSONException { + JSONObject innerMessage = new JSONObject().put("type", "SET_VOLUME"); + final JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage); + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler, never()) + .handleVolumeMessage(any(JSONObject.class), anyString(), anyInt()); + } + + @Test + public void testCastV2MessageofSetVolumeTypeWithWrongTypeVolumeMessage() throws JSONException { + JSONObject innerMessage = new JSONObject() + .put("type", "SET_VOLUME") + .put("volume", "wrong type volume message"); + final JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage); + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler, never()) + .handleVolumeMessage(any(JSONObject.class), anyString(), anyInt()); + } + + @Test + public void testCastV2MessageOfMediaMessageType() throws JSONException { + doReturn(true) + .when(mMessageHandler) + .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt()); + for (String messageType : CafMessageHandler.getMediaMessageTypesForTest()) { + // TODO(zqzhang): SET_VOLUME and STOP should not reach here? + if ("MEDIA_SET_VOLUME".equals(messageType) || "STOP_MEDIA".equals(messageType)) { + continue; + } + JSONObject innerMessage = new JSONObject().put("type", messageType); + JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage); + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + + JSONObject expected = new JSONObject(); + if (CafMessageHandler.getMediaOverloadedMessageTypesForTest().containsKey( + messageType)) { + expected.put("type", + CafMessageHandler.getMediaOverloadedMessageTypesForTest().get(messageType)); + } else { + expected.put("type", messageType); + } + verify(mMessageHandler) + .sendJsonCastMessage(argThat(new JSONObjectLike(expected)), + eq(CastSessionUtil.MEDIA_NAMESPACE), eq(CLIENT_ID1), + eq(SEQUENCE_NUMBER1)); + } + } + + @Test + public void testCastV2MessageWithNullSequenceNumber() throws JSONException { + JSONObject innerMessage = new JSONObject().put("type", "STOP"); + JSONObject message = buildCastV2Message(CLIENT_ID1, innerMessage); + message.remove("sequenceNumber"); + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler).handleStopMessage(eq(CLIENT_ID1), eq(VOID_SEQUENCE_NUMBER)); + } + + @Test + public void testHandleStopMessage() throws JSONException { + InOrder inOrder = inOrder(mSessionController); + assertEquals(0, mMessageHandler.getStopRequestsForTest().size()); + mMessageHandler.handleStopMessage(CLIENT_ID1, SEQUENCE_NUMBER1); + assertEquals(1, mMessageHandler.getStopRequestsForTest().get(CLIENT_ID1).size(), 1); + inOrder.verify(mSessionController).endSession(); + mMessageHandler.handleStopMessage(CLIENT_ID1, SEQUENCE_NUMBER2); + assertEquals(2, mMessageHandler.getStopRequestsForTest().get(CLIENT_ID1).size(), 2); + inOrder.verify(mSessionController).endSession(); + } + + @Test + public void testAppMessageWithExistingNamespace() throws JSONException { + setUpForAppMessageTest(); + + JSONObject actualMessage = buildActualAppMessage(); + JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage); + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler) + .sendJsonCastMessage(argThat(new JSONObjectLike(actualMessage)), eq(NAMESPACE1), + eq(CLIENT_ID1), eq(SEQUENCE_NUMBER1)); + } + + @Test + public void testAppMessageWithNonexistingNamespace() throws JSONException { + setUpForAppMessageTest(); + + JSONObject actualMessage = buildActualAppMessage(); + JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE2, actualMessage); + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler, never()) + .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt()); + } + + @Test + public void testAppMessageWithoutSequenceNumber() throws JSONException { + setUpForAppMessageTest(); + + JSONObject actualMessage = buildActualAppMessage(); + JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage); + message.remove("sequenceNumber"); + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler) + .sendJsonCastMessage(argThat(new JSONObjectLike(actualMessage)), eq(NAMESPACE1), + eq(CLIENT_ID1), eq(VOID_SEQUENCE_NUMBER)); + } + + @Test + public void testAppMessageWithNullSessionId() throws JSONException { + setUpForAppMessageTest(); + + JSONObject actualMessage = buildActualAppMessage(); + final JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage); + message.getJSONObject("message").remove("sessionId"); + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler, never()) + .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt()); + } + + @Test + public void testAppMessageWithWrongSessionId() throws JSONException { + setUpForAppMessageTest(); + + JSONObject actualMessage = buildActualAppMessage(); + JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage); + message.getJSONObject("message").put("sessionId", INVALID_SESSION_ID); + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler, never()) + .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt()); + } + + @Test + public void testAppMessageWithNullActualMessage() throws JSONException { + setUpForAppMessageTest(); + + JSONObject actualMessage = buildActualAppMessage(); + final JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage); + message.getJSONObject("message").remove("message"); + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler, never()) + .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt()); + } + + @Test + public void testAppMessageWithStringMessage() throws JSONException { + setUpForAppMessageTest(); + + JSONObject actualMessage = buildActualAppMessage(); + JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage); + message.getJSONObject("message").put("message", "string message"); + assertTrue(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler, never()) + .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt()); + verify(mMessageHandler) + .sendStringCastMessage( + eq("string message"), eq(NAMESPACE1), eq(CLIENT_ID1), eq(SEQUENCE_NUMBER1)); + } + + @Test + public void testAppMessageWithNullAppMessage() throws JSONException { + setUpForAppMessageTest(); + + JSONObject actualMessage = buildActualAppMessage(); + final JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage); + message.remove("message"); + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler, never()) + .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt()); + } + + @Test + public void testAppMessageWithEmptyAppMessage() throws JSONException { + setUpForAppMessageTest(); + + JSONObject actualMessage = buildActualAppMessage(); + final JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage); + message.put("message", new JSONObject()); + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler, never()) + .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt()); + } + + @Test + public void testAppMessageWithWrongTypeAppMessage() throws JSONException { + setUpForAppMessageTest(); + + JSONObject actualMessage = buildActualAppMessage(); + final JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage); + message.put("message", "wrong type app message"); + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler, never()) + .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt()); + } + + @Test + public void testAppMessageWithNullClient() throws JSONException { + setUpForAppMessageTest(); + + JSONObject actualMessage = buildActualAppMessage(); + final JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage); + message.remove("clientId"); + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler, never()) + .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt()); + } + + @Test + public void testAppMessageWithNonexistingClient() throws JSONException { + setUpForAppMessageTest(); + + JSONObject actualMessage = buildActualAppMessage(); + JSONObject message = buildAppMessage(CLIENT_ID1, NAMESPACE1, actualMessage); + message.put("clientId", INVALID_CLIENT_ID); + assertFalse(mMessageHandler.handleMessageFromClient(message.toString())); + verify(mMessageHandler, never()) + .sendJsonCastMessage(any(JSONObject.class), anyString(), anyString(), anyInt()); + } + + @Test + public void testSendJsonCastMessage() throws JSONException { + assertEquals(mMessageHandler.getRequestsForTest().size(), 0); + JSONObject message = buildJsonCastMessage("message"); + assertTrue(mMessageHandler.sendJsonCastMessage( + message, NAMESPACE1, CLIENT_ID1, SEQUENCE_NUMBER1)); + assertEquals(mMessageHandler.getRequestsForTest().size(), 1); + verify(mMessageHandler) + .sendStringCastMessage( + argThat(new JSONStringLike(message)), anyString(), anyString(), anyInt()); + } + + @Test + public void testSendJsonCastMessageWhileDisconnected() throws JSONException { + doReturn(false).when(mSessionController).isConnected(); + + JSONObject message = buildJsonCastMessage("message"); + assertFalse(mMessageHandler.sendJsonCastMessage( + message, NAMESPACE1, CLIENT_ID1, SEQUENCE_NUMBER1)); + assertEquals(mMessageHandler.getRequestsForTest().size(), 0); + verify(mMessageHandler, never()) + .sendStringCastMessage(anyString(), anyString(), anyString(), anyInt()); + } + + @Test + public void testSendJsonCastMessageWithInvalidSequenceNumber() throws JSONException { + JSONObject message = buildJsonCastMessage("message"); + assertTrue(mMessageHandler.sendJsonCastMessage( + message, NAMESPACE1, CLIENT_ID1, VOID_SEQUENCE_NUMBER)); + assertEquals(mMessageHandler.getRequestsForTest().size(), 0); + verify(mMessageHandler) + .sendStringCastMessage( + argThat(new JSONStringLike(message)), anyString(), anyString(), anyInt()); + } + + @Test + public void testSendJsonCastMessageWithNullRequestId() throws JSONException { + assertEquals(mMessageHandler.getRequestsForTest().size(), 0); + JSONObject message = buildJsonCastMessage("message"); + message.remove("requestId"); + assertTrue(mMessageHandler.sendJsonCastMessage( + message, NAMESPACE1, CLIENT_ID1, SEQUENCE_NUMBER1)); + assertTrue(message.has("requestId")); + assertEquals(mMessageHandler.getRequestsForTest().size(), 1); + verify(mMessageHandler) + .sendStringCastMessage( + argThat(new JSONStringLike(message)), anyString(), anyString(), anyInt()); + } + + @Test + public void testOnMessageReceivedWithExistingRequestId() throws JSONException { + doNothing() + .when(mMessageHandler) + .onAppMessage(anyString(), anyString(), any(RequestRecord.class)); + assertEquals(mMessageHandler.getRequestsForTest().size(), 0); + RequestRecord request = new RequestRecord(CLIENT_ID1, SEQUENCE_NUMBER1); + mMessageHandler.getRequestsForTest().append(REQUEST_ID1, request); + assertEquals(mMessageHandler.getRequestsForTest().size(), 1); + JSONObject message = new JSONObject(); + message.put("requestId", REQUEST_ID1); + mMessageHandler.onMessageReceived(NAMESPACE1, message.toString()); + assertEquals(mMessageHandler.getRequestsForTest().size(), 0); + verify(mMessageHandler).onAppMessage(eq(message.toString()), eq(NAMESPACE1), eq(request)); + } + + @Test + public void testOnMessageReceivedWithNonexistingRequestId() throws JSONException { + doNothing() + .when(mMessageHandler) + .onAppMessage(anyString(), anyString(), any(RequestRecord.class)); + assertEquals(mMessageHandler.getRequestsForTest().size(), 0); + RequestRecord request = new RequestRecord(CLIENT_ID1, SEQUENCE_NUMBER1); + mMessageHandler.getRequestsForTest().append(REQUEST_ID1, request); + assertEquals(mMessageHandler.getRequestsForTest().size(), 1); + JSONObject message = new JSONObject(); + message.put("requestId", REQUEST_ID2); + mMessageHandler.onMessageReceived(NAMESPACE1, message.toString()); + assertEquals(mMessageHandler.getRequestsForTest().size(), 1); + verify(mMessageHandler) + .onAppMessage(eq(message.toString()), eq(NAMESPACE1), (RequestRecord) isNull()); + } + + @Test + public void testOnMessageReceivedWithoutRequestId() throws JSONException { + doNothing() + .when(mMessageHandler) + .onAppMessage(anyString(), anyString(), any(RequestRecord.class)); + assertEquals(mMessageHandler.getRequestsForTest().size(), 0); + RequestRecord request = new RequestRecord(CLIENT_ID1, SEQUENCE_NUMBER1); + mMessageHandler.getRequestsForTest().append(REQUEST_ID1, request); + assertEquals(mMessageHandler.getRequestsForTest().size(), 1); + JSONObject message = new JSONObject(); + mMessageHandler.onMessageReceived(NAMESPACE1, message.toString()); + assertEquals(mMessageHandler.getRequestsForTest().size(), 1); + verify(mMessageHandler) + .onAppMessage(eq(message.toString()), eq(NAMESPACE1), (RequestRecord) isNull()); + } + + @Test + public void testOnMessageReceivedOfMediaNamespace() throws JSONException { + doNothing().when(mMessageHandler).onMediaMessage(anyString(), any(RequestRecord.class)); + mMessageHandler.onMessageReceived(MEDIA_NAMESPACE, "anymessage"); + verify(mMessageHandler).onMediaMessage(eq("anymessage"), (RequestRecord) isNull()); + } + + @Test + public void testOnMediaMessageOfMediaStatusTypeWithRequestRecord() { + doNothing() + .when(mMessageHandler) + .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt()); + doReturn(true).when(mMessageHandler).isMediaStatusMessage(anyString()); + RequestRecord request = new RequestRecord(CLIENT_ID1, SEQUENCE_NUMBER1); + mMessageHandler.onMediaMessage("anymessage", request); + verify(mMessageHandler, never()) + .sendEnclosedMessageToClient(eq(CLIENT_ID1), eq("v2_message"), eq("anymessage"), + eq(VOID_SEQUENCE_NUMBER)); + verify(mMessageHandler) + .sendEnclosedMessageToClient(eq(CLIENT_ID2), eq("v2_message"), eq("anymessage"), + eq(VOID_SEQUENCE_NUMBER)); + verify(mMessageHandler) + .sendEnclosedMessageToClient( + eq(CLIENT_ID1), eq("v2_message"), eq("anymessage"), eq(SEQUENCE_NUMBER1)); + } + + @Test + public void testOnMediaMessageOfMediaStatusTypeWithNullRequestRecord() { + doNothing() + .when(mMessageHandler) + .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt()); + doReturn(true).when(mMessageHandler).isMediaStatusMessage(anyString()); + mMessageHandler.onMediaMessage("anymessage", null); + verify(mMessageHandler) + .sendEnclosedMessageToClient(eq(CLIENT_ID1), eq("v2_message"), eq("anymessage"), + eq(VOID_SEQUENCE_NUMBER)); + verify(mMessageHandler) + .sendEnclosedMessageToClient(eq(CLIENT_ID2), eq("v2_message"), eq("anymessage"), + eq(VOID_SEQUENCE_NUMBER)); + } + + @Test + public void testOnMediaMessageOfNonMediaStatusTypeWithRequestRecord() { + doNothing() + .when(mMessageHandler) + .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt()); + doReturn(false).when(mMessageHandler).isMediaStatusMessage(anyString()); + RequestRecord request = new RequestRecord(CLIENT_ID1, SEQUENCE_NUMBER1); + mMessageHandler.onMediaMessage("anymessage", request); + verify(mMessageHandler, never()) + .sendEnclosedMessageToClient( + anyString(), anyString(), anyString(), eq(VOID_SEQUENCE_NUMBER)); + verify(mMessageHandler) + .sendEnclosedMessageToClient( + eq(CLIENT_ID1), eq("v2_message"), eq("anymessage"), eq(SEQUENCE_NUMBER1)); + } + + @Test + public void testOnMediaMessageOfNonMediaStatusTypeWithNullRequestRecord() { + doNothing() + .when(mMessageHandler) + .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt()); + doReturn(false).when(mMessageHandler).isMediaStatusMessage(anyString()); + mMessageHandler.onMediaMessage("anymessage", null); + verify(mMessageHandler, never()) + .sendEnclosedMessageToClient( + anyString(), anyString(), anyString(), eq(VOID_SEQUENCE_NUMBER)); + verify(mMessageHandler, never()) + .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt()); + } + + @Test + public void testOnAppMessageWithRequestRecord() throws JSONException { + doNothing() + .when(mMessageHandler) + .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt()); + RequestRecord request = new RequestRecord(CLIENT_ID1, SEQUENCE_NUMBER1); + mMessageHandler.onAppMessage("anyMessage", NAMESPACE1, request); + JSONObject expected = new JSONObject(); + expected.put("sessionId", SESSION_ID); + expected.put("namespaceName", NAMESPACE1); + expected.put("message", "anyMessage"); + verify(mMessageHandler) + .sendEnclosedMessageToClient(eq(CLIENT_ID1), eq("app_message"), + argThat(new JSONStringLike(expected)), eq(SEQUENCE_NUMBER1)); + verify(mMessageHandler, never()).broadcastClientMessage(anyString(), anyString()); + } + + @Test + public void testOnAppMessageWithNullRequestRecord() throws JSONException { + doNothing().when(mMessageHandler).broadcastClientMessage(anyString(), anyString()); + mMessageHandler.onAppMessage("anyMessage", NAMESPACE1, null); + JSONObject expected = new JSONObject(); + expected.put("sessionId", SESSION_ID); + expected.put("namespaceName", NAMESPACE1); + expected.put("message", "anyMessage"); + verify(mMessageHandler, never()) + .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt()); + verify(mMessageHandler) + .broadcastClientMessage(eq("app_message"), argThat(new JSONStringLike(expected))); + } + + @Test + public void testOnSessionEnded() { + doNothing() + .when(mMessageHandler) + .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt()); + assertEquals(0, mMessageHandler.getStopRequestsForTest().size()); + mMessageHandler.getStopRequestsForTest().put(CLIENT_ID1, new ArrayDeque<Integer>()); + mMessageHandler.getStopRequestsForTest().get(CLIENT_ID1).add(SEQUENCE_NUMBER1); + mMessageHandler.getStopRequestsForTest().get(CLIENT_ID1).add(SEQUENCE_NUMBER2); + assertEquals(1, mMessageHandler.getStopRequestsForTest().size()); + assertEquals(2, mMessageHandler.getStopRequestsForTest().get(CLIENT_ID1).size()); + + mMessageHandler.onSessionEnded(); + verify(mMessageHandler) + .sendEnclosedMessageToClient( + eq(CLIENT_ID1), eq("remove_session"), eq(SESSION_ID), eq(SEQUENCE_NUMBER1)); + verify(mMessageHandler) + .sendEnclosedMessageToClient( + eq(CLIENT_ID1), eq("remove_session"), eq(SESSION_ID), eq(SEQUENCE_NUMBER2)); + verify(mMessageHandler) + .sendEnclosedMessageToClient(eq(CLIENT_ID2), eq("remove_session"), eq(SESSION_ID), + eq(VOID_SEQUENCE_NUMBER)); + } + + @Test + public void testOnVolumeChanged() { + doNothing().when(mMessageHandler).onVolumeChanged(anyString(), anyInt()); + assertEquals(0, mMessageHandler.getVolumeRequestsForTest().size()); + mMessageHandler.getVolumeRequestsForTest().add( + new RequestRecord(CLIENT_ID1, SEQUENCE_NUMBER1)); + assertEquals(1, mMessageHandler.getVolumeRequestsForTest().size()); + + mMessageHandler.onVolumeChanged(); + verify(mMessageHandler).onVolumeChanged(CLIENT_ID1, SEQUENCE_NUMBER1); + assertEquals(0, mMessageHandler.getVolumeRequestsForTest().size()); + } + + @Test + public void testOnVolumeChangedWithEmptyVolumeRequests() { + mMessageHandler.onVolumeChanged(); + verify(mMessageHandler, never()).onVolumeChanged(eq(CLIENT_ID1), eq(SEQUENCE_NUMBER1)); + } + + @Test + public void testOnVolumeChangedForClient() { + doNothing() + .when(mMessageHandler) + .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt()); + mMessageHandler.onVolumeChanged(CLIENT_ID1, SEQUENCE_NUMBER1); + verify(mMessageHandler) + .sendEnclosedMessageToClient( + eq(CLIENT_ID1), eq("v2_message"), (String) isNull(), eq(SEQUENCE_NUMBER1)); + } + + @Test + public void testOnAppMessageSent() { + Status mockResult = mock(Status.class); + doReturn(true).when(mockResult).isSuccess(); + doNothing() + .when(mMessageHandler) + .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt()); + mMessageHandler.onSendAppMessageResult(mockResult, CLIENT_ID1, SEQUENCE_NUMBER1); + verify(mMessageHandler) + .sendEnclosedMessageToClient( + eq(CLIENT_ID1), eq("app_message"), (String) isNull(), eq(SEQUENCE_NUMBER1)); + } + + @Test + public void testSendEnclosedMessageToClient() throws JSONException { + String message = "dontcare_message1"; + doReturn(message) + .when(mMessageHandler) + .buildEnclosedClientMessage(anyString(), anyString(), anyString(), anyInt()); + mMessageHandler.sendEnclosedMessageToClient( + CLIENT_ID1, "anytype", "dontcare_message2", SEQUENCE_NUMBER1); + + verify(mRouteProvider).sendMessageToClient(eq(CLIENT_ID1), eq(message)); + } + + @Test + public void testBroadcastClientMessage() { + doNothing() + .when(mMessageHandler) + .sendEnclosedMessageToClient(anyString(), anyString(), anyString(), anyInt()); + mMessageHandler.broadcastClientMessage("anytype", "anymessage"); + for (String clientId : mRouteProvider.getClientIdToRecords().keySet()) { + verify(mMessageHandler) + .sendEnclosedMessageToClient(eq(clientId), eq("anytype"), eq("anymessage"), + eq(VOID_SEQUENCE_NUMBER)); + } + } + + @Test + public void testSendReceiverActionToClient() throws JSONException { + MediaSink sink = mock(MediaSink.class); + doReturn("sink-id").when(sink).getId(); + doReturn("sink-name").when(sink).getName(); + doReturn(Arrays.asList("audio_in", "audio_out", "video_in", "video_out")) + .when(mSessionController) + .getCapabilities(); + + mMessageHandler.sendReceiverActionToClient("route-id", sink, "client-id", "action"); + + ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class); + verify(mRouteProvider).sendMessageToClient(eq("client-id"), messageCaptor.capture()); + JSONObject capturedMessage = new JSONObject(messageCaptor.getValue()); + assertEquals(capturedMessage.getString("type"), "receiver_action"); + assertEquals(capturedMessage.getInt("sequenceNumber"), VOID_SEQUENCE_NUMBER); + assertEquals(capturedMessage.getInt("timeoutMillis"), 0); + assertEquals(capturedMessage.getString("clientId"), "client-id"); + + JSONObject receiverAction = capturedMessage.getJSONObject("message"); + assertEquals(receiverAction.getString("action"), "action"); + + JSONObject receiverInfo = receiverAction.getJSONObject("receiver"); + assertEquals(receiverInfo.getString("label"), "sink-id"); + assertEquals(receiverInfo.getString("friendlyName"), "sink-name"); + assertFalse(receiverInfo.has("volume")); + assertFalse(receiverInfo.has("isActiveInput")); + assertFalse(receiverInfo.has("displayStatus")); + assertEquals(receiverInfo.getString("receiverType"), "cast"); + + JSONArray capabilities = receiverInfo.getJSONArray("capabilities"); + assertEquals(capabilities.getString(0), "audio_in"); + assertEquals(capabilities.getString(1), "audio_out"); + assertEquals(capabilities.getString(2), "video_in"); + assertEquals(capabilities.getString(3), "video_out"); + } + + @Test + public void testBuildEnclosedClientMessageWithNullMessage() throws JSONException { + String message = mMessageHandler.buildEnclosedClientMessage( + "anytype", null, CLIENT_ID1, SEQUENCE_NUMBER1); + JSONObject expected = new JSONObject(); + expected.put("type", "anytype"); + expected.put("sequenceNumber", SEQUENCE_NUMBER1); + expected.put("timeoutMillis", 0); + expected.put("clientId", CLIENT_ID1); + expected.put("message", null); + + assertTrue("\nexpected: " + expected.toString() + ",\n actual: " + message.toString(), + new JSONObjectLike(expected).matches(new JSONObject(message))); + } + + @Test + public void testBuildEnclosedClientMessageOfRemoveSessionType() throws JSONException { + String message = mMessageHandler.buildEnclosedClientMessage( + "remove_session", SESSION_ID, CLIENT_ID1, SEQUENCE_NUMBER1); + JSONObject expected = new JSONObject(); + expected.put("type", "remove_session"); + expected.put("sequenceNumber", SEQUENCE_NUMBER1); + expected.put("timeoutMillis", 0); + expected.put("clientId", CLIENT_ID1); + expected.put("message", SESSION_ID); + + assertTrue("\nexpected: " + expected.toString() + ",\n actual: " + message.toString(), + new JSONObjectLike(expected).matches(new JSONObject(message))); + } + + @Test + public void testBuildEnclosedClientMessageOfDisconnectSessionType() throws JSONException { + String message = mMessageHandler.buildEnclosedClientMessage( + "disconnect_session", SESSION_ID, CLIENT_ID1, SEQUENCE_NUMBER1); + JSONObject expected = new JSONObject(); + expected.put("type", "disconnect_session"); + expected.put("sequenceNumber", SEQUENCE_NUMBER1); + expected.put("timeoutMillis", 0); + expected.put("clientId", CLIENT_ID1); + expected.put("message", SESSION_ID); + + assertTrue("\nexpected: " + expected.toString() + ",\n actual: " + message.toString(), + new JSONObjectLike(expected).matches(new JSONObject(message))); + } + + @Test + public void testBuildEnclosedClientMessageWithInnerMessage() throws JSONException { + JSONObject innerMessage = buildSessionMessage(SESSION_ID); + String message = mMessageHandler.buildEnclosedClientMessage( + "anytype", innerMessage.toString(), CLIENT_ID1, SEQUENCE_NUMBER1); + JSONObject expected = new JSONObject(); + expected.put("type", "anytype"); + expected.put("sequenceNumber", SEQUENCE_NUMBER1); + expected.put("timeoutMillis", 0); + expected.put("clientId", CLIENT_ID1); + expected.put("message", innerMessage); + + assertTrue("\nexpected: " + expected.toString() + ",\n actual: " + message.toString(), + new JSONObjectLike(expected).matches(new JSONObject(message))); + } + + @Test + public void testBuildSessionMessage() throws JSONException { + CastDevice castDevice = mock(CastDevice.class); + doReturn("device-id").when(castDevice).getDeviceId(); + doReturn("CastDevice friendly name").when(castDevice).getFriendlyName(); + doReturn(castDevice).when(mSession).getCastDevice(); + ApplicationMetadata appMetadata = mock(ApplicationMetadata.class); + doReturn("app-id").when(appMetadata).getApplicationId(); + doReturn(appMetadata).when(mSession).getApplicationMetadata(); + doReturn(1.0).when(mSession).getVolume(); + doReturn(false).when(mSession).isMute(); + doReturn("status text").when(mSession).getApplicationStatus(); + doReturn(1).when(mSession).getActiveInputState(); + doReturn(Arrays.asList("namespace-1", "namespace-2")) + .when(mSessionController) + .getNamespaces(); + doReturn(Arrays.asList("audio_in", "audio_out", "video_in", "video_out")) + .when(mSessionController) + .getCapabilities(); + + JSONObject message = new JSONObject(mMessageHandler.buildSessionMessage()); + + assertEquals(message.getString("sessionId"), SESSION_ID); + assertEquals(message.getString("statusText"), "status text"); + assertEquals(message.getString("status"), "connected"); + assertEquals(message.getString("transportId"), "web-4"); + assertEquals(message.getString("appId"), "app-id"); + assertEquals(message.getString("displayName"), "CastDevice friendly name"); + + JSONArray mediaArray = message.getJSONArray("media"); + + assertEquals(mediaArray.length(), 0); + + JSONArray namespacesArray = message.getJSONArray("namespaces"); + assertEquals(namespacesArray.length(), 2); + assertEquals(namespacesArray.getJSONObject(0).getString("name"), "namespace-1"); + assertEquals(namespacesArray.getJSONObject(1).getString("name"), "namespace-2"); + + JSONObject receiverInfo = message.getJSONObject("receiver"); + assertEquals(receiverInfo.getString("label"), "device-id"); + assertEquals(receiverInfo.getString("friendlyName"), "CastDevice friendly name"); + assertEquals(receiverInfo.getInt("isActiveInput"), 1); + assertEquals(receiverInfo.getString("receiverType"), "cast"); + assertFalse(receiverInfo.has("displayStatus")); + + JSONArray capabilities = receiverInfo.getJSONArray("capabilities"); + assertEquals(capabilities.getString(0), "audio_in"); + assertEquals(capabilities.getString(1), "audio_out"); + assertEquals(capabilities.getString(2), "video_in"); + assertEquals(capabilities.getString(3), "video_out"); + + JSONObject volume = receiverInfo.getJSONObject("volume"); + assertEquals(volume.getDouble("level"), 1.0, 1e-6); + assertFalse(volume.getBoolean("muted")); + } + + @Test + public void testBuildSessionMessage_sessionDisconnected() { + doReturn(false).when(mSessionController).isConnected(); + + CastDevice castDevice = mock(CastDevice.class); + doReturn("device-id").when(castDevice).getDeviceId(); + doReturn("CastDevice friendly name").when(castDevice).getFriendlyName(); + doReturn(castDevice).when(mSession).getCastDevice(); + ApplicationMetadata appMetadata = mock(ApplicationMetadata.class); + doReturn("app-id").when(appMetadata).getApplicationId(); + doReturn(appMetadata).when(mSession).getApplicationMetadata(); + doReturn(1.0).when(mSession).getVolume(); + doReturn(false).when(mSession).isMute(); + doReturn("status text").when(mSession).getApplicationStatus(); + doReturn(1).when(mSession).getActiveInputState(); + doReturn(Arrays.asList("namespace-1", "namespace-2")) + .when(mSessionController) + .getNamespaces(); + doReturn(Arrays.asList("audio_in", "audio_out", "video_in", "video_out")) + .when(mSessionController) + .getCapabilities(); + + assertEquals(mMessageHandler.buildSessionMessage(), "{}"); + } + + private JSONObject buildCastV2Message(String clientId, JSONObject innerMessage) + throws JSONException { + JSONObject message = new JSONObject(); + message.put("type", "v2_message"); + message.put("message", innerMessage); + message.put("sequenceNumber", SEQUENCE_NUMBER1); + message.put("timeoutMillis", 0); + message.put("clientId", clientId); + + return message; + } + + private JSONObject buildAppMessage(String clientId, String namespace, Object actualMessage) + throws JSONException { + JSONObject innerMessage = new JSONObject(); + innerMessage.put("sessionId", mSessionController.getSessionId()); + innerMessage.put("namespaceName", namespace); + innerMessage.put("message", actualMessage); + + JSONObject message = new JSONObject(); + message.put("type", "app_message"); + message.put("message", innerMessage); + message.put("sequenceNumber", SEQUENCE_NUMBER1); + message.put("timeoutMillis", 0); + message.put("clientId", clientId); + + return message; + } + + private JSONObject buildActualAppMessage() throws JSONException { + JSONObject message = new JSONObject(); + message.put("type", "actual app message type"); + + return message; + } + + private JSONObject buildSessionMessage(String sessionId) throws JSONException { + JSONObject message = new JSONObject(); + message.put("sessionId", sessionId); + + return message; + } + + private void expectException(CheckedRunnable r, Class exceptionClass) { + boolean caughtException = false; + try { + r.run(); + } catch (Exception e) { + if (e.getClass() == exceptionClass) caughtException = true; + } + assertTrue(caughtException); + } + + private JSONObject buildJsonCastMessage(String message) throws JSONException { + JSONObject jsonMessage = new JSONObject(); + jsonMessage.put("requestId", REQUEST_ID1); + jsonMessage.put("message", message); + return jsonMessage; + } + + private void verifySimpleSessionMessage(JSONObject message, String type, int sequenceNumber, + String clientId) throws JSONException { + assertEquals(message.getString("type"), type); + assertEquals(message.getInt("sequenceNumber"), sequenceNumber); + assertEquals(message.getInt("timeoutMillis"), 0); + assertEquals(message.getInt("sequenceNumber"), sequenceNumber); + } + + private void prepareClientRecord(String routeId, String clientId, String appId, + String autoJoinPolicy, String origin, int tabId) { + ClientRecord clientRecord = + new ClientRecord(routeId, clientId, appId, autoJoinPolicy, origin, tabId); + mClientRecordMap.put(clientId, clientRecord); + } + + private JSONObject buildLeaveSessionMessage( + String clientId, String sessionId, int sequenceNumber) throws JSONException { + JSONObject message = new JSONObject(); + message.put("type", "leave_session"); + message.put("clientId", clientId); + message.put("message", sessionId); + message.put("sequenceNumber", sequenceNumber); + return message; + } +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/ShadowCastMediaSource.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/ShadowCastMediaSource.java new file mode 100644 index 0000000..4907a979 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/caf/ShadowCastMediaSource.java
@@ -0,0 +1,32 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.media.router.caf; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +import org.chromium.chrome.browser.media.router.cast.CastMediaSource; + +/** Shadow implementation for {@link MediaRouter}. */ +@Implements(CastMediaSource.class) +public class ShadowCastMediaSource { + private static ShadowImplementation sImpl; + + @Implementation + public static CastMediaSource from(String sourceId) { + return sImpl.from(sourceId); + } + + public static void setImplementation(ShadowImplementation impl) { + sImpl = impl; + } + + /** The implementation skeleton for the implementation backing the shadow. */ + public static class ShadowImplementation { + public CastMediaSource from(String sourceId) { + return null; + } + } +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandlerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandlerTest.java index e4aa918..81467be 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandlerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandlerTest.java
@@ -36,9 +36,9 @@ import org.chromium.base.test.util.Feature; import org.chromium.chrome.browser.media.router.CastSessionUtil; import org.chromium.chrome.browser.media.router.ClientRecord; +import org.chromium.chrome.browser.media.router.JSONTestUtils.JSONObjectLike; +import org.chromium.chrome.browser.media.router.JSONTestUtils.JSONStringLike; import org.chromium.chrome.browser.media.router.cast.CastMessageHandler.RequestRecord; -import org.chromium.chrome.browser.media.router.cast.JSONTestUtils.JSONObjectLike; -import org.chromium.chrome.browser.media.router.cast.JSONTestUtils.JSONStringLike; import java.util.ArrayDeque; import java.util.HashMap;
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 37e04b2..c93e153 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-72.0.3614.0_rc-r1.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-72.0.3616.0_rc-r1.afdo.bz2 \ No newline at end of file
diff --git a/chrome/app/file_manager_strings.grdp b/chrome/app/file_manager_strings.grdp index a908d7f7..7c944d9 100644 --- a/chrome/app/file_manager_strings.grdp +++ b/chrome/app/file_manager_strings.grdp
@@ -1024,9 +1024,6 @@ <message name="IDS_FILE_BROWSER_DRIVE_WELCOME_TITLE_ALTERNATIVE" desc="In the Welcome to Google Drive banner, title of the alternative banner offering 100GB free storage."> Get 100 GB free with Google Drive </message> - <message name="IDS_FILE_BROWSER_DRIVE_WELCOME_TITLE_ALTERNATIVE_1TB" desc="In the Welcome to Google Drive banner, title of the alternative banner offering 1TB free storage."> - Get 1 TB free with Google Drive - </message> <message name="IDS_FILE_BROWSER_DRIVE_WELCOME_TEXT_SHORT" desc="In the Welcome to Google Drive banner, text of the welcome message, short version."> All files saved in this folder are backed up online automatically </message>
diff --git a/chrome/app/resources/generated_resources_am.xtb b/chrome/app/resources/generated_resources_am.xtb index f54b458b..fac3a58 100644 --- a/chrome/app/resources/generated_resources_am.xtb +++ b/chrome/app/resources/generated_resources_am.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">የስምረት ቅንብሮችን አሳይ</translation> <translation id="1124772482545689468">ተጠቃሚ</translation> <translation id="1125550662859510761"><ph name="WIDTH" /> x <ph name="HEIGHT" /> ይመስላል (ቤተኛ)</translation> -<translation id="1127216846847548354">በድምጽ ማግበር</translation> <translation id="1128109161498068552">ማናቸውንም ጣቢያዎች ለሚመለከተው ስርዓት የተወሰኑ መልዕክቶችን MIDI መሳሪያዎችን ለመድረስ እንዲጠቀሙ አይፍቀዱ።</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">የፍለጋ ፕሮግራምን ያርትዑ</translation> @@ -1642,7 +1641,6 @@ <translation id="3495660573538963482">የGoogle ረዳት ቅንብሮች</translation> <translation id="3496213124478423963">አሳንስ</translation> <translation id="3505030558724226696">የመሣሪያ መዳረሻ ሻር</translation> -<translation id="3506093155988721483">የእርስዎን ረዳት ሲያስጀምሩት በቁልፍ ሰሌዳ ምትክ ንግግርን ይጠቀሙ</translation> <translation id="3507421388498836150">ለ«<ph name="EXTENSION_NAME" />» አሁን ያሉት ፈቃዶች</translation> <translation id="3507547268929739059">የLinux መተግበሪያዎችን ለChromebook ያስወግዱ</translation> <translation id="3507888235492474624">የብሉቱዝ መሣሪያዎችን ዳግም ቃኝ</translation> @@ -2058,7 +2056,6 @@ <translation id="4100733287846229632">የመሣሪያው ቦታ እጅግ በጣም ዝቅተኛ ነው</translation> <translation id="4103091233824664032">የማያ ገጽ ቁልፍ እና በመለያ መግባትን ለማዋቀር የይለፍ ቃልዎን ያስገቡ</translation> <translation id="4104163789986725820">ወደ &ውጪ ላክ...</translation> -<translation id="4105563239298244027">ከGoogle Drive ጋር 1 ቴባ ነጻ ያግኙ</translation> <translation id="4107048419833779140">የማከማቻ መሣሪያዎችን ለይተው ይወቁ እና ያስወጡ</translation> <translation id="4109135793348361820">መስኮት ወደ <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />) ውሰድ</translation> <translation id="4110895898888439383">ድሩን በከፍተኛ ንጽጽር ሁነታ ያስሱ</translation> @@ -5336,7 +5333,6 @@ <translation id="9214520840402538427">ውይ! የጭነት ጊዜ መገለጫ ባህሪያት ጊዜ አልፎባቸዋል። እባክዎ የድጋፍ ተወካይዎን ያግኙ።</translation> <translation id="9214695392875603905">ዘቢብ ኬክ</translation> <translation id="9215293857209265904">«<ph name="EXTENSION_NAME" />» ታክሏል</translation> -<translation id="9215934040295798075">ልጣፍ ያዘጋጁ</translation> <translation id="9218430445555521422">እንደወረደ አዘጋጀው</translation> <translation id="9219103736887031265">ምስሎች</translation> <translation id="9220525904950070496">መለያ ያስወግዱ</translation>
diff --git a/chrome/app/resources/generated_resources_ar.xtb b/chrome/app/resources/generated_resources_ar.xtb index cd44a73..d3cb2c5 100644 --- a/chrome/app/resources/generated_resources_ar.xtb +++ b/chrome/app/resources/generated_resources_ar.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">عرض إعدادات المزامنة</translation> <translation id="1124772482545689468">المستخدم</translation> <translation id="1125550662859510761">تبدو كـ <ph name="WIDTH" /> x <ph name="HEIGHT" /> (أصلية)</translation> -<translation id="1127216846847548354">تفعيل الصوت</translation> <translation id="1128109161498068552">عدم السماح لأي موقع باستخدام الرسائل الحصرية في النظام للدخول إلى أجهزة MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">تعديل محرّك البحث</translation> @@ -1305,7 +1304,7 @@ <translation id="2961090598421146107"><ph name="CERTIFICATE_NAME" /> (الإضافة متوفرة)</translation> <translation id="2961695502793809356">انقر للانتقال إلى الأمام واضغط لمشاهدة السجل</translation> <translation id="2963151496262057773">المكوّن الإضافي التالي غير مستجيب: <ph name="PLUGIN_NAME" />، هل تريد إيقافه؟</translation> -<translation id="2966937470348689686">إدارة التفضيلات في Android</translation> +<translation id="2966937470348689686">إدارة إعدادات Android المفضّلة</translation> <translation id="2972557485845626008">البرامج الثابتة</translation> <translation id="2972581237482394796">إعا&دة</translation> <translation id="2972642118232180842">تشغيل المحتوى المهم فقط (موصى به)</translation> @@ -1641,7 +1640,6 @@ <translation id="3495660573538963482">إعدادات مساعد Google</translation> <translation id="3496213124478423963">تصغير</translation> <translation id="3505030558724226696">إبطال الوصول إلى الجهاز</translation> -<translation id="3506093155988721483">استخدام الكلام بدلاً من لوحة المفاتيح عند بدء "مساعد Google"</translation> <translation id="3507421388498836150">الأذونات الحالية لـ "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">إزالة تطبيقات Linux لـ Chromebook</translation> <translation id="3507888235492474624">إعادة فحص أجهزة البلوتوث</translation> @@ -2056,7 +2054,6 @@ <translation id="4100733287846229632">المساحة على الجهاز منخفضة للغاية</translation> <translation id="4103091233824664032">يُرجى إدخال كلمة مرورك لتهيئة قفل الشاشة وتسجيل الدخول</translation> <translation id="4104163789986725820">ت&صدير...</translation> -<translation id="4105563239298244027">احصل على 1 تيرابايت مجانًا مع Google Drive</translation> <translation id="4107048419833779140">تحديد أجهزة التخزين وإخراجها</translation> <translation id="4109135793348361820">نقل النافذة إلى <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">تصفُّح الويب في وضع التباين العالي</translation> @@ -5332,7 +5329,6 @@ <translation id="9214520840402538427">عفوًا! لقد انتهت مهلة بدء تشغيل سمات وقت التثبيت. يُرجى الاتصال بممثل الدعم.</translation> <translation id="9214695392875603905">كب كيك</translation> <translation id="9215293857209265904">تمت إضافة "<ph name="EXTENSION_NAME" />"</translation> -<translation id="9215934040295798075">تعيين خلفية</translation> <translation id="9218430445555521422">تعيين كافتراضي</translation> <translation id="9219103736887031265">صور</translation> <translation id="9220525904950070496">إزالة الحساب</translation>
diff --git a/chrome/app/resources/generated_resources_bg.xtb b/chrome/app/resources/generated_resources_bg.xtb index 20ba4aa..3d8e41d 100644 --- a/chrome/app/resources/generated_resources_bg.xtb +++ b/chrome/app/resources/generated_resources_bg.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Показване на настройките за синхронизиране</translation> <translation id="1124772482545689468">Потребител</translation> <translation id="1125550662859510761">Разделителната способност е <ph name="WIDTH" /> x <ph name="HEIGHT" /> (стандартна)</translation> -<translation id="1127216846847548354">Гласово активиране</translation> <translation id="1128109161498068552">Да не се разрешава на сайтовете да използват специални системни съобщения за достъп до MIDI устройствата</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Редактиране на търсещата машина</translation> @@ -1640,7 +1639,6 @@ <translation id="3495660573538963482">Настройки на Google Асистент</translation> <translation id="3496213124478423963">Намаляване</translation> <translation id="3505030558724226696">Отмяна на достъпа до устройството</translation> -<translation id="3506093155988721483">Използване на говор вместо клавиатурата, когато стартирате Асистент</translation> <translation id="3507421388498836150">Текущи разрешения за <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Премахване на приложенията за Linux за Chromebook</translation> <translation id="3507888235492474624">Повторно сканиране за устройства с Bluetooth</translation> @@ -2060,7 +2058,6 @@ <translation id="4100733287846229632">Мястото на устройството е критично малко</translation> <translation id="4103091233824664032">Въведете паролата си, за да конфигурирате заключването на екрана и влизането в профила</translation> <translation id="4104163789986725820">Екс&портиране...</translation> -<translation id="4105563239298244027">Получете 1 ТБ безплатно с Google Диск</translation> <translation id="4107048419833779140">Идентифициране и изваждане на устройства за съхранение</translation> <translation id="4109135793348361820">Преместване на прозореца към <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Сърфирайте в мрежата в режим на повишена четливост</translation> @@ -5336,7 +5333,6 @@ <translation id="9214520840402538427">Ами сега! Времето за изчакване на инициализирането на атрибутите за времето за инсталиране изтече. Моля, свържете се с представител на екипа си за поддръжка.</translation> <translation id="9214695392875603905">Кексче</translation> <translation id="9215293857209265904"><ph name="EXTENSION_NAME" /> се добави</translation> -<translation id="9215934040295798075">Задаване на тапета</translation> <translation id="9218430445555521422">Задаване по подразбиране</translation> <translation id="9219103736887031265">Изображения</translation> <translation id="9220525904950070496">Премахване на профила</translation>
diff --git a/chrome/app/resources/generated_resources_bn.xtb b/chrome/app/resources/generated_resources_bn.xtb index 5e5eed4..4d18ed0 100644 --- a/chrome/app/resources/generated_resources_bn.xtb +++ b/chrome/app/resources/generated_resources_bn.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">সিঙ্ক সেটিংস দেখুন</translation> <translation id="1124772482545689468">ব্যবহারকারী</translation> <translation id="1125550662859510761">মনে হচ্ছে <ph name="WIDTH" /> x <ph name="HEIGHT" /> (স্থানীয়)</translation> -<translation id="1127216846847548354">ভয়েসের মাধ্যমে চালু করা</translation> <translation id="1128109161498068552">কোনো সাইটকে MIDI ডিভাইসগুলি অ্যাক্সেস করার জন্য সিস্টেমের বিশিষ্ট বার্তাগুলি ব্যবহার করার মঞ্জুরি দেবেন না</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">সার্চ ইঞ্জিন সম্পাদনা করুন</translation> @@ -615,7 +614,7 @@ <translation id="1880905663253319515">শংসাপত্র মুছবেন "<ph name="CERTIFICATE_NAME" />"?</translation> <translation id="1886996562706621347">সাইটগুলিকে প্রোটোকলের জন্য ডিফল্ট পরিচালক হতে জিজ্ঞাসা করার অনুমতি দেয় (প্রস্তাবিত)</translation> <translation id="1887442540531652736">সাইন-ইন করার সময় সমস্যা হয়েছে</translation> -<translation id="1887597546629269384">আবার "Hey Google" বলুন</translation> +<translation id="1887597546629269384">আবার "হ্যালো Google" বলুন</translation> <translation id="1887850431809612466">হার্ডওয়্যার পুনর্বিবেচনাগুলি</translation> <translation id="1889984860246851556">প্রক্সি সেটিংস খুলুন</translation> <translation id="1890674179660343635"><span>আইডি: </span><ph name="EXTENSION_ID" /></translation> @@ -1640,7 +1639,6 @@ <translation id="3495660573538963482">Google সহায়ক সেটিংস</translation> <translation id="3496213124478423963">জুম কমান</translation> <translation id="3505030558724226696">ডিভাইসের অ্যাক্সেস প্রত্যাহার করুন</translation> -<translation id="3506093155988721483">আপনার অ্যাসিস্ট্যান্ট চালু করার সময় কীবোর্ডের পরিবর্তে স্পিচ ব্যবহার করুন</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" এর জন্য বর্তমান অনুমতিগুলি</translation> <translation id="3507547268929739059">Chromebook থেকে Linux অ্যাপ সরিয়ে দিন</translation> <translation id="3507888235492474624">ব্লুটুথ ডিভাইস আবার স্ক্যান করুন</translation> @@ -2057,7 +2055,6 @@ <translation id="4100733287846229632">ডিভাইসের স্থান আশংকাজনকভাবে কম</translation> <translation id="4103091233824664032">স্ক্রিন লক এবং সাইন-ইন কনফিগার করার জন্য আপনার পাসওয়ার্ড লিখুন</translation> <translation id="4104163789986725820">র&প্তানি...</translation> -<translation id="4105563239298244027">Google ড্রাইভের সাথে বিনামূল্যে ১ TB পান</translation> <translation id="4107048419833779140">স্টোরেজ ডিভাইসগুলি শনাক্ত করে সরিয়ে দিন</translation> <translation id="4109135793348361820"><ph name="USER_NAME" /> (<ph name="USER_EMAIL" />) এ উইন্ডো সরান</translation> <translation id="4110895898888439383">উচ্চ কনট্রাস্ট মোডে ওয়েব ব্রাউজ করুন</translation> @@ -2285,7 +2282,7 @@ <translation id="4524832533047962394">অপারেটিং সিস্টেমের এই ভার্সনটি প্রদত্ত নথিভুক্তকরণের মোড সমর্থন করে না। আপনি সর্বাধুনিক ভার্সনটি চালাচ্ছেন কিনা দেখুন।</translation> <translation id="4525382759303819021">Play স্টোর অ্যাপ সম্পর্কে লেটেস্ট আপডেট ও প্রস্তাবনা পান</translation> <translation id="4530494379350999373">উৎস</translation> -<translation id="4533846798469727141">এখন "Hey Google" বলুন</translation> +<translation id="4533846798469727141">এখন "হ্যালো Google" বলুন</translation> <translation id="4533985347672295764">CPU সময়</translation> <translation id="4534661889221639075">আবার চেষ্টা করুন।</translation> <translation id="4535127706710932914">ডিফল্ট প্রোফাইল</translation> @@ -3810,7 +3807,7 @@ <translation id="6840184929775541289">একটি শংসাপত্র কর্তৃপক্ষ নয়</translation> <translation id="6840313690797192085">$১ PB</translation> <translation id="6841186874966388268">ত্রুটিগুলি</translation> -<translation id="6843423766595476978">Ok Google সেট হয়ে গেছে</translation> +<translation id="6843423766595476978">হ্যালো Google ব্যবহারের জন্য প্রস্তুত</translation> <translation id="6845038076637626672">সর্বাধিক খুলুন</translation> <translation id="685040365210406336">কোনও পরিবর্তন করবেন না</translation> <translation id="6851497530878285708">অ্যাপ সক্ষম করা হয়েছে</translation> @@ -4735,7 +4732,7 @@ <translation id="8249296373107784235">বাতিল</translation> <translation id="8249672078237421304">আপনি যে ভাষাতে পড়েন সেই ভাষাতে না থাকা পৃষ্ঠাগুলি অনুবাদ করার প্রস্তাব দিন</translation> <translation id="8251578425305135684">থাম্বনেল সরানো হয়েছে৷</translation> -<translation id="8252569384384439529">আপলোড হচ্ছে...</translation> +<translation id="8252569384384439529">আপলোড হচ্ছে…</translation> <translation id="8253198102038551905">নেটওয়ার্কের প্রোপাটিজ পেতে '+'-এ ক্লিক করুন</translation> <translation id="825483282309623688">আপনার ডেটা পুনরুদ্ধার করতে, আপনার একটি ইন্টারনেট সংযোগ প্রয়োজন।</translation> <translation id="8256319818471787266">স্পার্কি</translation> @@ -5332,7 +5329,6 @@ <translation id="9214520840402538427">ওহো! প্রারম্ভিক ইনস্টলেশন-সময়ের বৈশিষ্ট্যাবলীর সময় ফুরিয়েছে৷ দয়া করে আপনার সহায়ক প্রতিনিধির সঙ্গে যোগাযোগ করুন৷</translation> <translation id="9214695392875603905">কাপ কেক</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" জোড়া হয়েছে</translation> -<translation id="9215934040295798075">ওয়ালপেপার সেট করুন</translation> <translation id="9218430445555521422">ডিফল্ট হিসেবে সেট করুন</translation> <translation id="9219103736887031265">ছবিগুলি</translation> <translation id="9220525904950070496">অ্যাকাউন্ট সরান</translation>
diff --git a/chrome/app/resources/generated_resources_ca.xtb b/chrome/app/resources/generated_resources_ca.xtb index 175dfec..cf05087 100644 --- a/chrome/app/resources/generated_resources_ca.xtb +++ b/chrome/app/resources/generated_resources_ca.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Mostra la configuració de sincronització</translation> <translation id="1124772482545689468">Usuari</translation> <translation id="1125550662859510761">Resolució: <ph name="WIDTH" /> x <ph name="HEIGHT" /> (nativa)</translation> -<translation id="1127216846847548354">Activació de la veu</translation> <translation id="1128109161498068552">No permetis que cap lloc utilitzi els missatges exclusius del sistema per accedir als dispositius MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Edita el motor de cerca</translation> @@ -1640,7 +1639,6 @@ <translation id="3495660573538963482">Configuració de l'Assistent de Google</translation> <translation id="3496213124478423963">Redueix</translation> <translation id="3505030558724226696">Revoca l'accés als dispositius</translation> -<translation id="3506093155988721483">Utilitza la veu en lloc del teclat quan iniciïs l'Assistent</translation> <translation id="3507421388498836150">Permisos actuals de l'extensió <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Suprimeix les aplicacions per a Linux de Chromebook</translation> <translation id="3507888235492474624">Torna a cercar dispositius Bluetooth</translation> @@ -2057,7 +2055,6 @@ <translation id="4100733287846229632">Queda molt poc espai al dispositiu</translation> <translation id="4103091233824664032">Introdueix la contrasenya per configurar el bloqueig de pantalla i l'inici de sessió</translation> <translation id="4104163789986725820">E&xporta...</translation> -<translation id="4105563239298244027">Obteniu 1 TB gratis amb Google Drive</translation> <translation id="4107048419833779140">Identifica i expulsa els dispositius d'emmagatzematge</translation> <translation id="4109135793348361820">Mou la finestra a <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Navega per Internet en mode d'alt contrast</translation> @@ -5332,7 +5329,6 @@ <translation id="9214520840402538427">La inicialització dels atributs en temps d'instal·lació ha esgotat el temps d'espera. Contacteu amb el representant d'assistència.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">S'ha afegit "<ph name="EXTENSION_NAME" />"</translation> -<translation id="9215934040295798075">Estableix fons de pantalla</translation> <translation id="9218430445555521422">Estableix com a predeterminat</translation> <translation id="9219103736887031265">Imatges</translation> <translation id="9220525904950070496">Suprimir el compte</translation>
diff --git a/chrome/app/resources/generated_resources_cs.xtb b/chrome/app/resources/generated_resources_cs.xtb index 80ededa..a6e77ebe 100644 --- a/chrome/app/resources/generated_resources_cs.xtb +++ b/chrome/app/resources/generated_resources_cs.xtb
@@ -32,6 +32,7 @@ <translation id="1039337018183941703">Neplatný nebo poškozený soubor</translation> <translation id="1042174272890264476">Počítač je dodáván s integrovanou knihovnou RLZ prohlížeče <ph name="SHORT_PRODUCT_NAME" />. RLZ přiřadí značku, která slouží k vyhodnocení vyhledávání a využití prohlížečů <ph name="SHORT_PRODUCT_NAME" />, které pocházejí z konkrétní propagační kampaně. Tato značka není jedinečná a neumožňuje osobní identifikaci. Tyto značky jsou někdy v prohlížeči <ph name="PRODUCT_NAME" /> uváděny v dotazech ve Vyhledávání Google.</translation> <translation id="1046059554679513793">Toto jméno se již používá.</translation> +<translation id="1046635659603195359">Funkci rozpoznání hlasu Voice Match jste u Asistenta Google už zřejmě nastavili v jiném zařízení. Dřívější nahrávky lze použít k vytvoření hlasového modelu v tomto zařízení. Mělo by to trvat méně než minutu.</translation> <translation id="1047431265488717055">Kopírovat te&xt odkazu</translation> <translation id="1047726139967079566">Přidat stránku do záložek...</translation> <translation id="1047956942837015229">Mazání <ph name="COUNT" /> položek...</translation> @@ -91,7 +92,6 @@ <translation id="1123187597739372905">Zobrazit nastavení synchronizace</translation> <translation id="1124772482545689468">Uživatel</translation> <translation id="1125550662859510761">Vypadá jako <ph name="WIDTH" /> × <ph name="HEIGHT" /> (nativní)</translation> -<translation id="1127216846847548354">Hlasová aktivace</translation> <translation id="1128109161498068552">Nepovolovat žádným webům využívání exkluzivních zpráv systému pro přístup k zařízením MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Úprava vyhledávače</translation> @@ -166,6 +166,8 @@ Na následující obrazovce prosím zadejte zpětnou vazbu, která nám problém pomůže vyřešit.</translation> <translation id="1217668622537098248">Po akci vrátit na kliknutí levým tlačítkem</translation> <translation id="121783623783282548">Hesla se neshodují.</translation> +<translation id="1218839827383191197"><ph name="BEGIN_PARAGRAPH1" />Služby určování polohy Google používají zdroje, jako jsou sítě Wi-Fi, mobilní sítě a senzory, pomocí kterých se snaží odhadnout polohu tohoto zařízení.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Určování polohy můžete vypnout tím, že v zařízení deaktivujete hlavní nastavení polohy. V nastavení polohy můžete také vypnout používání sítí Wi-Fi, mobilních sítí a senzorů k určování polohy.<ph name="END_PARAGRAPH2" /></translation> <translation id="122082903575839559">Algoritmus podpisu certifikátu</translation> <translation id="1221024147024329929">Šifrování PKCS #1 MD2 s RSA</translation> <translation id="1221825588892235038">Pouze výběr</translation> @@ -241,6 +243,7 @@ <translation id="1340527397989195812">Zálohujte média ze zařízení pomocí aplikace Soubory.</translation> <translation id="1341988552785875222">Aktuální tapetu nastavila aplikace <ph name="APP_NAME" />. Je možné, že před výběrem jiné tapety bude nutné aplikaci <ph name="APP_NAME" /> odinstalovat.</translation> <translation id="1346748346194534595">Doprava</translation> +<translation id="1347256498747320987">Instalace aktualizací a aplikací. Pokračováním vyjadřujete souhlas s tím, že toto zařízení může také automaticky stahovat a instalovat aktualizace a aplikace od společnosti Google, operátora a výrobce zařízení, a v případě potřeby k tomu smí používat mobilní datové připojení. Některé z těchto aplikací mohou nabízet nákupy v aplikaci. <ph name="BEGIN_LINK1" />Další informace<ph name="END_LINK1" /></translation> <translation id="1347975661240122359">Aktualizace bude zahájena, až baterie dosáhne <ph name="BATTERY_LEVEL" /> %.</translation> <translation id="1351692861129622852">Importování <ph name="FILE_COUNT" /> souborů...</translation> <translation id="1353686479385938207"><ph name="PROVIDER_NAME" />: <ph name="NETWORK_NAME" /></translation> @@ -372,6 +375,7 @@ <translation id="1529899284660134226">Spravovat sdílené soubory a složky</translation> <translation id="1530838837447122178">Otevřít nastavení myši a touchpadu</translation> <translation id="1531004739673299060">Okno aplikace</translation> +<translation id="1536754031901697553">Odpojování...</translation> <translation id="15373452373711364">Velký kurzor myši</translation> <translation id="1538729222189715449">Otevírání souborů systému Linux...</translation> <translation id="1540605929960647700">Zapnout ukázkový režim</translation> @@ -1300,6 +1304,7 @@ <translation id="2946119680249604491">Přidat připojení</translation> <translation id="2948300991547862301">Přejít na stránku <ph name="PAGE_TITLE" /></translation> <translation id="29488703364906173">Rychlý, jednoduchý a bezpečný webový prohlížeč vytvořený pro moderní web</translation> +<translation id="2949289451367477459">Používat polohu. Povolte aplikacím a službám s oprávněním pro přístup k poloze využívat polohu tohoto zařízení. Google může pravidelně shromažďovat údaje o poloze a anonymně je používat ke zlepšování přesnosti polohy a služeb založených na poloze. <ph name="BEGIN_LINK1" />Další informace<ph name="END_LINK1" /></translation> <translation id="2958721676848865875">Upozornění na zabalení rozšíření</translation> <translation id="296026337010986570">Hotovo! Škodlivý software byl odstraněn. Budete-li chtít rozšíření znovu zapnout, přejděte na stránku <a href="chrome://extensions">Rozšíření</a>.</translation> <translation id="2961090598421146107"><ph name="CERTIFICATE_NAME" /> (poskytnuto rozšířením)</translation> @@ -1640,7 +1645,6 @@ <translation id="3495660573538963482">Nastavení Asistenta Google</translation> <translation id="3496213124478423963">Oddálit</translation> <translation id="3505030558724226696">Zrušit přístup k zařízení</translation> -<translation id="3506093155988721483">Místo klávesnice při spuštění Asistenta používat hlas</translation> <translation id="3507421388498836150">Aktuální oprávnění pro aplikaci <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Odstranit linuxové aplikace pro Chromebook</translation> <translation id="3507888235492474624">Znovu vyhledat zařízení Bluetooth</translation> @@ -1761,6 +1765,7 @@ <translation id="3677657024345889897">Nejtišší</translation> <translation id="3678156199662914018">Rozšíření: <ph name="EXTENSION_NAME" /></translation> <translation id="3681311097828166361">Děkujeme vám za zpětnou vazbu. Nyní jste offline, zpráva bude odeslána později.</translation> +<translation id="3682824389861648626">Limit pohybu</translation> <translation id="3683023058278427253">U vaší domény jsme zjistili několik typů licencí. Chcete-li pokračovat, vyberte jeden typ.</translation> <translation id="3683524264665795342">Požadavek na sdílení obrazovky s aplikací <ph name="APP_NAME" /></translation> <translation id="3685122418104378273">Když používáte mobilní datové připojení, synchronizace s Diskem Google je ve výchozím nastavení vypnutá.</translation> @@ -1810,6 +1815,7 @@ <translation id="3742055079367172538">Byl vytvořen snímek obrazovky</translation> <translation id="3742666961763734085">Organizační jednotku s daným názvem nelze najít. Zkuste to prosím znovu.</translation> <translation id="3744111561329211289">Synchronizace na pozadí</translation> +<translation id="3747077776423672805">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 (možná bude třeba aplikacemi listovat doprava či doleva). Následně klepněte na Odinstalovat nebo Deaktivovat.</translation> <translation id="3748026146096797577">Nepřipojeno</translation> <translation id="3749289110408117711">Název souboru</translation> <translation id="3751427701788899101">Připojení bylo ztraceno</translation> @@ -1967,6 +1973,7 @@ <translation id="3954953195017194676">Nemáte žádné nedávno zaznamenané protokoly událostí WebRTC.</translation> <translation id="3955193568934677022">Povolit webům přehrávat chráněný obsah (doporučeno)</translation> <translation id="3956702100721821638">Ke službě Google Play se nepodařilo připojit</translation> +<translation id="3957844511978444971">Klepnutím na Přijmout potvrdíte výběr těchto nastavení služeb Google.</translation> <translation id="3958088479270651626">Importovat záložky a nastavení</translation> <translation id="3960566196862329469">ONC</translation> <translation id="3965965397408324205">Zavřít profil <ph name="PROFILE_NAME" /></translation> @@ -2057,7 +2064,6 @@ <translation id="4100733287846229632">V zařízení je kriticky málo místa</translation> <translation id="4103091233824664032">Chcete-li nakonfigurovat zámek obrazovky a přihlášení, zadejte heslo</translation> <translation id="4104163789986725820">E&xport...</translation> -<translation id="4105563239298244027">Získejte 1 TB volného úložiště na Disku Google zdarma</translation> <translation id="4107048419833779140">Identifikovat a vysouvat úložná zařízení</translation> <translation id="4109135793348361820">Přesunout okno k uživateli <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Prohlížejte internet v režimu vysokého kontrastu</translation> @@ -2791,6 +2797,7 @@ <translation id="5301954838959518834">Dobře, rozumím</translation> <translation id="5302048478445481009">Jazyk</translation> <translation id="5305688511332277257">Není nainstalován žádný certifikát</translation> +<translation id="5307030433605830021">Zdroj není podporován</translation> <translation id="5308380583665731573">Připojení</translation> <translation id="5311304534597152726">Přihlašujete se jako</translation> <translation id="5315873049536339193">Identita</translation> @@ -2928,6 +2935,7 @@ <translation id="5507756662695126555">Neodvolatelnost</translation> <translation id="5509693895992845810">Uložit &jako...</translation> <translation id="5509914365760201064">Vydal: <ph name="CERTIFICATE_AUTHORITY" /></translation> +<translation id="5511379779384092781">Velmi malý</translation> <translation id="5511823366942919280">Opravdu toto zařízení chcete nastavit jako zařízení Shark?</translation> <translation id="5512653252560939721">Certifikát uživatele musí být hardwarový.</translation> <translation id="5516183516694518900">Přihlaste se do prohlížeče Chrome pomocí účtu Google a získejte záložky, historii, hesla a další nastavení do všech svých zařízení.</translation> @@ -2987,6 +2995,10 @@ <translation id="5582839680698949063">Hlavní nabídka</translation> <translation id="5583640892426849032">Backspace</translation> <translation id="5584088138253955452">Uložit uživatelské jméno?</translation> +<translation id="5584915726528712820"><ph name="BEGIN_PARAGRAPH1" />Toto jsou obecné informace o vašem zařízení a způsobu jeho používání (např. stav baterie, aktivita systému a aplikací nebo chyby). Data budou využívána k vylepšení systému Android. Některé souhrnné informace pomohou s vylepšováním aplikací a služeb také našim partnerům, například vývojářům Androidu.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Vypnutí této funkce nemá vliv na schopnost zařízení odesílat informace, které jsou potřeba pro základní služby, jako jsou aktualizace systému a zabezpečení.<ph name="END_PARAGRAPH2" /> + <ph name="BEGIN_PARAGRAPH3" />Vlastník tuto funkci může ovládat pomocí možnosti Nastavení > Rozšířená nastavení > Automaticky do Googlu odesílat diagnostické údaje a údaje o využití.<ph name="END_PARAGRAPH3" /> + <ph name="BEGIN_PARAGRAPH4" />Pokud je zapnuto dodatečné nastavení Aktivita na webu a v aplikacích, mohou se tato data ukládat do vašeho účtu Google. Svá data můžete zobrazit a smazat na stránce account.google.com, kde také můžete změnit nastavení svého účtu.<ph name="END_PARAGRAPH4" /></translation> <translation id="5585118885427931890">Složku záložek nelze vytvořit.</translation> <translation id="558563010977877295">Otevřít konkrétní stránku nebo skupinu stránek</translation> <translation id="5585912436068747822">Formátování se nezdařilo</translation> @@ -3019,6 +3031,7 @@ <translation id="5623842676595125836">Protokol</translation> <translation id="5624120631404540903">Spravovat hesla</translation> <translation id="5626134646977739690">Jméno:</translation> +<translation id="5626283214046138476">Platnost vašeho dozorovaného uživatelského účtu brzy vyprší.</translation> <translation id="5627086634964711283">Také řídí, která stránka se zobrazí po kliknutí na tlačítko Domovská stránka.</translation> <translation id="5627676517703583263">Pohybujte se na internetu chytře pomocí prohlížeče Google Chrome</translation> <translation id="562935524653278697">Váš administrátor synchronizaci záložek, historie, hesel a dalších nastavení zakázal.</translation> @@ -3291,6 +3304,8 @@ <translation id="604001903249547235">Zálohování do cloudu</translation> <translation id="6040143037577758943">Zavřít</translation> <translation id="6040852767465482106">Anonymní identita</translation> +<translation id="6041046205544295907"><ph name="BEGIN_PARAGRAPH1" />Služby určování polohy Google používají zdroje, jako jsou sítě Wi-Fi, mobilní sítě a senzory, pomocí kterých se snaží odhadnout polohu vašeho zařízení.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Určování polohy můžete vypnout tím, že v zařízení deaktivujete hlavní nastavení polohy. V nastavení polohy můžete také vypnout používání sítí Wi-Fi, mobilních sítí a senzorů k určování polohy.<ph name="END_PARAGRAPH2" /></translation> <translation id="6041155700700864984">Ukončit režim celé obrazovky</translation> <translation id="604124094241169006">Automaticky</translation> <translation id="6042169520002885235">Vyberte výrobce a model tiskárny</translation> @@ -3319,6 +3334,7 @@ <translation id="6074825444536523002">Formulář Google</translation> <translation id="6075731018162044558">Jejda! Systému se pro toto zařízení nepodařilo získat token dlouhodobého přístupu k rozhraní API.</translation> <translation id="6075907793831890935">Výměna dat se zařízením <ph name="HOSTNAME" /></translation> +<translation id="6076175485108489240">Používat polohu. Povolte aplikacím a službám s oprávněním pro přístup k poloze využívat polohu tohoto zařízení. Google může pravidelně shromažďovat údaje o poloze a anonymně je používat ke zlepšování přesnosti polohy a služeb založených na poloze. <ph name="BEGIN_LINK1" />Další informace<ph name="END_LINK1" /></translation> <translation id="6076448957780543068">Přiložit tento snímek obrazovky</translation> <translation id="6077131872140550515">Odebrat z preferovaných</translation> <translation id="6077189836672154517">Tipy a aktuality k zařízení <ph name="DEVICE_TYPE" /></translation> @@ -3969,6 +3985,7 @@ <translation id="7088674813905715446">Zařízení bylo vyřazeno administrátorem. Chcete-li zařízení zaregistrovat, požádejte administrátora, aby jeho registraci umožnil.</translation> <translation id="7093434536568905704">GTK+</translation> <translation id="7093866338626856921">Výměna dat s následujícími zařízeními: <ph name="HOSTNAMES" /></translation> +<translation id="7094583680070770403">Uložte své místní soubory a nastavte nový účet.</translation> <translation id="7096857570999173890">Když budete odhlášeni, můžete zařízení odemknout pomocí kódu PIN.</translation> <translation id="7098389117866926363">Zařízení USB Type-C (levý zadní port)</translation> <translation id="7098447629416471489">Zde se zobrazí ostatní uložené vyhledávače</translation> @@ -4035,6 +4052,7 @@ <translation id="7191454237977785534">Uložit soubor jako</translation> <translation id="7193374945610105795">Pro web <ph name="ORIGIN" /> nejsou uložena žádná hesla</translation> <translation id="7196835305346730603">Vyhledávání zařízení Chromebox v okolí...</translation> +<translation id="7196913789568937443">Zálohování na Disk Google. Snadno obnovte svá data nebo kdykoliv přejděte na jiné zařízení. Záloha zahrnuje data aplikací. Zálohy se nahrávají do Googlu a šifrují pomocí hesla účtu Google. <ph name="BEGIN_LINK1" />Další informace<ph name="END_LINK1" /></translation> <translation id="7197190419934240522">Mějte při procházení internetu vždy k dispozici Vyhledávání Google a chytré funkce Google</translation> <translation id="7197632491113152433">Ve vašem účtu jsme našli aplikace, které lze použít na tomto zařízení, celkem <ph name="NUMBER_OF_APPS" />.</translation> <translation id="7199158086730159431">Zobrazit nápovědu</translation> @@ -4121,6 +4139,7 @@ <translation id="7324297612904500502">Fórum beta</translation> <translation id="7325437708553334317">Rozšíření Vysoký kontrast</translation> <translation id="7328162502911382168">(<ph name="COUNT" />)</translation> +<translation id="7328699668338161242">Asistent již dokáže rozpoznat váš hlas</translation> <translation id="7328867076235380839">Neplatná kombinace</translation> <translation id="7329154610228416156">Přihlášení se nezdařilo, protože bylo nakonfigurováno k použití nezabezpečené adresy URL (<ph name="BLOCKED_URL" />). Obraťte se na svého administrátora.</translation> <translation id="7334190995941642545">Smart Lock aktuálně není k dispozici. Zkuste to znovu později.</translation> @@ -4169,6 +4188,7 @@ <translation id="7400839060291901923">Nastavte připojení na zařízení <ph name="PHONE_NAME" /></translation> <translation id="740624631517654988">Zablokováno vyskakovací okno</translation> <translation id="7407430846095439694">Importovat a svázat</translation> +<translation id="7409549334477097887">Velmi velký</translation> <translation id="7409836189476010449">Spustit Flash</translation> <translation id="7410344089573941623">Zobrazit dotaz, pokud bude chtít web <ph name="HOST" /> používat webovou kameru a mikrofon</translation> <translation id="741204030948306876">Ano</translation> @@ -4475,6 +4495,7 @@ <translation id="7853747251428735">&Další nástroje</translation> <translation id="7857117644404132472">Přidat výjimku</translation> <translation id="7857949311770343000">Je toto stránka nové karty, kterou jste očekávali?</translation> +<translation id="7859183520363892678">Naučte Asistenta rozpoznávat váš hlas</translation> <translation id="786073089922909430">Služba: <ph name="ARC_PROCESS_NAME" /></translation> <translation id="7861215335140947162">&Stažené soubory</translation> <translation id="7864662577698025113">Přidat novou službu</translation> @@ -4628,6 +4649,9 @@ <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> <translation id="8074127646604999664">Povolit nedávno zavřeným webům dokončit odeslání a příjem dat</translation> <translation id="8076492880354921740">Karty</translation> <translation id="8076835018653442223">Správce přístup k místním souborům v tomto zařízení zakázal</translation> @@ -4638,6 +4662,11 @@ <translation id="8086015605808120405">Probíhá konfigurace tiskárny <ph name="PRINTER_NAME" />...</translation> <translation id="8090234456044969073">Může číst seznam nejčastěji navštěvovaných webů</translation> <translation id="8093359998839330381">Plugin <ph name="PLUGIN_NAME" /> neodpovídá</translation> +<translation id="8095105960962832018"><ph name="BEGIN_PARAGRAPH1" />Zálohování na Disk Google. Snadno obnovte svá data nebo kdykoliv přejděte na jiné zařízení. Záloha zahrnuje data aplikací.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Zálohy se nahrávají do Googlu a šifrují pomocí hesla účtu Google.<ph name="END_PARAGRAPH2" /> + <ph name="BEGIN_PARAGRAPH3" />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_PARAGRAPH3" /> + <ph name="BEGIN_PARAGRAPH4" />Zálohovaná data se nezapočítávají do kvóty úložiště na Disku.<ph name="END_PARAGRAPH4" /> + <ph name="BEGIN_PARAGRAPH5" />Tuto službu můžete vypnout v Nastavení.<ph name="END_PARAGRAPH5" /></translation> <translation id="80974698889265265">Kódy PIN se neshodují</translation> <translation id="8101987792947961127">Je vyžadováno použití funkce Powerwash při dalším restartu</translation> <translation id="8102159139658438129">Možnosti připojeného telefonu najdete v sekci <ph name="LINK_BEGIN" />Nastavení<ph name="LINK_END" /></translation> @@ -4680,6 +4709,7 @@ <translation id="8162857629993139764">Vytvořit novou poznámku</translation> <translation id="8168435359814927499">Obsah</translation> <translation id="8174047975335711832">Informace o zařízení</translation> +<translation id="8174876712881364124">Zálohování na Disk Google. Snadno obnovte data nebo přejděte na jiné zařízení. Tato záloha zahrnuje data aplikací. Zálohy se nahrávají do Googlu a šifrují pomocí hesla účtu Google dítěte. <ph name="BEGIN_LINK1" />Další informace<ph name="END_LINK1" /></translation> <translation id="8177196903785554304">Podrobnosti o síti</translation> <translation id="8179976553408161302">Enter</translation> <translation id="8180239481735238521">stránka</translation> @@ -4745,6 +4775,10 @@ <translation id="8261506727792406068">Smazat</translation> <translation id="8263744495942430914">Stránka <ph name="FULLSCREEN_ORIGIN" /> deaktivovala váš ukazatel myši.</translation> <translation id="8264718194193514834">Rozšíření <ph name="EXTENSION_NAME" /> spustilo režim celé obrazovky.</translation> +<translation id="8267961145111171918"><ph name="BEGIN_PARAGRAPH1" />Toto jsou obecné informace o tomto zařízení a způsobu jeho používání (např. stav baterie, aktivita systému a aplikací a chyby). Data budou využívána k vylepšování systému Android a některé souhrnné informace pomohou s vylepšením aplikací a služeb také našim partnerům, například vývojářům aplikací pro Android.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Vypnutí této funkce nemá vliv na schopnost zařízení odesílat informace, které jsou potřeba pro základní služby, jako jsou aktualizace systému a zabezpečení.<ph name="END_PARAGRAPH2" /> + <ph name="BEGIN_PARAGRAPH3" />Vlastník tuto funkci může ovládat pomocí možnosti Nastavení > Rozšířená nastavení > Automaticky do Googlu odesílat diagnostické údaje a údaje o využití.<ph name="END_PARAGRAPH3" /> + <ph name="BEGIN_PARAGRAPH4" />Pokud je pro dítě zapnuté dodatečné nastavení Aktivita na webu a v aplikacích, mohou se tato data ukládat do jeho účtu Google. Další informace o těchto nastaveních a o tom, jak je upravit, najdete na stránce families.google.com.<ph name="END_PARAGRAPH4" /></translation> <translation id="8270242299912238708">Dokumenty PDF</translation> <translation id="827097179112817503">Zobrazit tlačítko Domovská stránka</translation> <translation id="8271246892936492311">{COUNT,plural, =1{Byla smazána 1 záložka}few{Byly smazány # záložky}many{Bylo smazáno # záložky}other{Bylo smazáno # záložek}}</translation> @@ -5328,7 +5362,6 @@ <translation id="9214520840402538427">Jejda! Vypršel časový limit inicializace atributů doby instalace. Kontaktujte zástupce podpory.</translation> <translation id="9214695392875603905">Sladký košíček</translation> <translation id="9215293857209265904">Bylo přidáno rozšíření <ph name="EXTENSION_NAME" /></translation> -<translation id="9215934040295798075">Nastavit tapetu</translation> <translation id="9218430445555521422">Nastavit jako výchozí</translation> <translation id="9219103736887031265">Obrázky</translation> <translation id="9220525904950070496">Odebrat účet</translation>
diff --git a/chrome/app/resources/generated_resources_da.xtb b/chrome/app/resources/generated_resources_da.xtb index f49dfdc..45dd0f3 100644 --- a/chrome/app/resources/generated_resources_da.xtb +++ b/chrome/app/resources/generated_resources_da.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Vis indstillinger for synkronisering</translation> <translation id="1124772482545689468">Bruger</translation> <translation id="1125550662859510761">Ligner <ph name="WIDTH" /> x <ph name="HEIGHT" /> (oprindelig)</translation> -<translation id="1127216846847548354">Stemmeaktivering</translation> <translation id="1128109161498068552">Tillad ikke, at websites bruger interne systemmeddelelser til at få adgang til MIDI-enheder</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Rediger søgemaskine</translation> @@ -1641,7 +1640,6 @@ <translation id="3495660573538963482">Indstillinger for Google Assistent</translation> <translation id="3496213124478423963">Zoom ud</translation> <translation id="3505030558724226696">Tilbagekald adgang til enhed</translation> -<translation id="3506093155988721483">Brug tale i stedet for tastatur, når du starter Google-assistenten</translation> <translation id="3507421388498836150">Nuværende tilladelser for "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Fjern Linux-apps til Chromebook</translation> <translation id="3507888235492474624">Søg efter Bluetooth-enheder igen</translation> @@ -2059,7 +2057,6 @@ <translation id="4100733287846229632">Der er næsten ikke mere plads på enheden</translation> <translation id="4103091233824664032">Angiv din adgangskode for at konfigurere skærmlås og login</translation> <translation id="4104163789986725820">E&ksporter...</translation> -<translation id="4105563239298244027">Få 1 TB gratis plads med Google Drev</translation> <translation id="4107048419833779140">Identificer og fjern lagerenheder</translation> <translation id="4109135793348361820">Flyt vindue til <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Brug internettet i tilstanden Stor kontrast</translation> @@ -5335,7 +5332,6 @@ <translation id="9214520840402538427">Ups! Initialiseringen af installationstidens attributter har fået timeout. Kontakt en supportmedarbejder.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" er tilføjet</translation> -<translation id="9215934040295798075">Vælg baggrund</translation> <translation id="9218430445555521422">Indstil som standard</translation> <translation id="9219103736887031265">Billeder</translation> <translation id="9220525904950070496">Fjern konto</translation>
diff --git a/chrome/app/resources/generated_resources_de.xtb b/chrome/app/resources/generated_resources_de.xtb index eee97d2..5e1ff53 100644 --- a/chrome/app/resources/generated_resources_de.xtb +++ b/chrome/app/resources/generated_resources_de.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Synchronisierungseinstellungen anzeigen</translation> <translation id="1124772482545689468">Nutzer</translation> <translation id="1125550662859510761">Auflösung <ph name="WIDTH" /> x <ph name="HEIGHT" /> (nativ)</translation> -<translation id="1127216846847548354">Sprachaktivierung</translation> <translation id="1128109161498068552">Websites nicht gestatten, mittels systemexklusiver Meldungen auf MIDI-Geräte zuzugreifen</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Suchmaschine bearbeiten</translation> @@ -1638,7 +1637,6 @@ <translation id="3495660573538963482">Google Assistant-Einstellungen</translation> <translation id="3496213124478423963">Verkleinern</translation> <translation id="3505030558724226696">Gerätezugriff aufheben</translation> -<translation id="3506093155988721483">Spracheingabe anstelle der Tastatur verwenden, wenn Assistant gestartet wird</translation> <translation id="3507421388498836150">Aktuelle Berechtigungen für "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Linux-Apps für Chromebook entfernen</translation> <translation id="3507888235492474624">Noch einmal nach Bluetooth-Geräten suchen</translation> @@ -2056,7 +2054,6 @@ <translation id="4100733287846229632">Speicherplatz auf Gerät äußerst niedrig</translation> <translation id="4103091233824664032">Passwort eingeben, um Displaysperre und Log-in zu konfigurieren</translation> <translation id="4104163789986725820">E&xportieren...</translation> -<translation id="4105563239298244027">Nutzen Sie 1 TB kostenlosen Speicher bei Google Drive.</translation> <translation id="4107048419833779140">Speichergeräte ermitteln und auswerfen</translation> <translation id="4109135793348361820">Fenster zu <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />) verschieben</translation> <translation id="4110895898888439383">Das Web in Modus mit hohem Kontrast durchsuchen</translation> @@ -5332,7 +5329,6 @@ <translation id="9214520840402538427">Hoppla! Bei der Initialisierung der Installationszeit-Attribute ist eine Zeitüberschreitung aufgetreten. Bitte wenden Sie sich an Ihren Support-Mitarbeiter.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" hinzugefügt</translation> -<translation id="9215934040295798075">Hintergrund festlegen</translation> <translation id="9218430445555521422">Als Standardbrowser festlegen</translation> <translation id="9219103736887031265">Bilder</translation> <translation id="9220525904950070496">Konto entfernen</translation>
diff --git a/chrome/app/resources/generated_resources_el.xtb b/chrome/app/resources/generated_resources_el.xtb index 99c1659..188dd49b 100644 --- a/chrome/app/resources/generated_resources_el.xtb +++ b/chrome/app/resources/generated_resources_el.xtb
@@ -32,6 +32,7 @@ <translation id="1039337018183941703">Μη έγκυρο ή κατεστραμμένο αρχείο</translation> <translation id="1042174272890264476">Ο υπολογιστής σας κυκλοφορεί και με ενσωματωμένη τη βιβλιοθήκη RLZ του <ph name="SHORT_PRODUCT_NAME" />. Το RLZ εκχωρεί μια μη μοναδική ετικέτα μη προσωπικής ταυτοποίησης για τη μέτρηση των αναζητήσεων και της χρήσης του <ph name="SHORT_PRODUCT_NAME" /> που προκύπτει από μια συγκεκριμένη καμπάνια προώθησης. Αυτές οι ετικέτες εμφανίζονται μερικές φορές σε ερωτήματα στην Αναζήτηση Google στο <ph name="PRODUCT_NAME" />.</translation> <translation id="1046059554679513793">Ωχ, αυτό το όνομα χρησιμοποιείται ήδη!</translation> +<translation id="1046635659603195359">Φαίνεται πως έχετε ήδη ρυθμίσει το Voice Match με τον Βοηθό σας Google σε κάποια άλλη συσκευή. Αυτές οι προηγούμενες ηχογραφήσεις μπορούν να χρησιμοποιηθούν για τη δημιουργία ενός φωνητικού μοντέλου σε αυτήν τη συσκευή. Η διαδικασία αναμένεται να διαρκέσει λιγότερο από ένα λεπτό.</translation> <translation id="1047431265488717055">Αντιγραφή κε&ιμένου συνδέσμου</translation> <translation id="1047726139967079566">Τοποθέτηση Σελιδοδείκτη σε Αυτήν τη Σελίδα...</translation> <translation id="1047956942837015229">Διαγραφή <ph name="COUNT" /> στοιχείων…</translation> @@ -91,7 +92,6 @@ <translation id="1123187597739372905">Εμφάνιση ρυθμίσεων συγχρονισμού</translation> <translation id="1124772482545689468">Χρήστης</translation> <translation id="1125550662859510761">Θα εμφανίζεται ως <ph name="WIDTH" /> x <ph name="HEIGHT" /> (Εγγενής)</translation> -<translation id="1127216846847548354">Ενεργοποίηση φωνής</translation> <translation id="1128109161498068552">Να μην επιτρέπεται σε κανέναν ιστότοπο να χρησιμοποιεί αποκλειστικά μηνύματα συστήματος για την πρόσβαση σε συσκευές MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Επεξεργασία μηχανής αναζήτησης</translation> @@ -166,6 +166,8 @@ Στην επόμενη οθόνη, σας προτείνουμε να μας στείλετε περισσότερες πληροφορίες για να μπορέσουμε να διορθώσουμε το πρόβλημα.</translation> <translation id="1217668622537098248">Επαναφορά σε αριστερό κλικ μετά από κάποια ενέργεια</translation> <translation id="121783623783282548">Δεν ταιριάζουν οι κωδικοί πρόσβασης.</translation> +<translation id="1218839827383191197"><ph name="BEGIN_PARAGRAPH1" />Η υπηρεσία τοποθεσίας της Google χρησιμοποιεί πηγές όπως δίκτυα Wi‑Fi και κινητής τηλεφωνίας καθώς και αισθητήρες, για τον υπολογισμό της τοποθεσίας αυτής της συσκευής.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Μπορείτε να απενεργοποιήσετε την Τοποθεσία απενεργοποιώντας τη βασική ρύθμιση "Τοποθεσία" σε αυτήν τη συσκευή. Μπορείτε επίσης να απενεργοποιήσετε τη χρήση δικτύων Wi-Fi και κινητής τηλεφωνίας και των αισθητήρων για την τοποθεσία στις ρυθμίσεις τοποθεσίας.<ph name="END_PARAGRAPH2" /></translation> <translation id="122082903575839559">Αλγόριθμος υπογραφής πιστοποιητικού</translation> <translation id="1221024147024329929">PKCS #1 MD2 με κρυπτογράφηση RSA</translation> <translation id="1221825588892235038">Μόνο επιλογή</translation> @@ -241,6 +243,7 @@ <translation id="1340527397989195812">Δημιουργία αντιγράφων ασφαλείας μέσων από τη συσκευή με χρήση της εφαρμογής "Αρχεία".</translation> <translation id="1341988552785875222">Η τρέχουσα ταπετσαρία έχει οριστεί από το '<ph name="APP_NAME" />'. Ενδεχομένως να χρειαστεί να απεγκαταστήσετε το '<ph name="APP_NAME" />' πριν επιλέξετε μια διαφορετική ταπετσαρία.</translation> <translation id="1346748346194534595">Δεξιά</translation> +<translation id="1347256498747320987">Εγκατάσταση ενημερώσεων και εφαρμογών. Εάν συνεχίσετε, αποδέχεστε ότι αυτή η συσκευή ενδέχεται επίσης να κατεβάζει και να εγκαθιστά αυτόματα ενημερώσεις και εφαρμογές από την Google, την εταιρεία κινητής τηλεφωνίας και τον κατασκευαστή της συσκευής, πιθανόν με τη χρήση δεδομένων κινητής τηλεφωνίας. Ορισμένες από αυτές τις εφαρμογές μπορεί να προσφέρουν αγορές εντός εφαρμογής. <ph name="BEGIN_LINK1" />Μάθετε περισσότερα<ph name="END_LINK1" /></translation> <translation id="1347975661240122359">Η ενημέρωση θα ξεκινήσει μόλις το επίπεδο της μπαταρίας φτάσει στο <ph name="BATTERY_LEVEL" />%.</translation> <translation id="1351692861129622852">Εισαγωγή <ph name="FILE_COUNT" /> αρχείων…</translation> <translation id="1353686479385938207"><ph name="PROVIDER_NAME" />: <ph name="NETWORK_NAME" /></translation> @@ -372,6 +375,7 @@ <translation id="1529899284660134226">Διαχείριση κοινόχρηστων αρχείων και φακέλων</translation> <translation id="1530838837447122178">Άνοιγμα των ρυθμίσεων ποντικιού και επιφάνειας αφής της συσκευής</translation> <translation id="1531004739673299060">Παράθυρο εφαρμογής</translation> +<translation id="1536754031901697553">Γίνεται αποσύνδεση…</translation> <translation id="15373452373711364">Μεγάλος δείκτης ποντικιού</translation> <translation id="1538729222189715449">Άνοιγμα αρχείων Linux…</translation> <translation id="1540605929960647700">Ενεργοποίηση λειτουργίας επίδειξης</translation> @@ -1301,6 +1305,7 @@ <translation id="2946119680249604491">Προσθήκη σύνδεσης</translation> <translation id="2948300991547862301">Μετάβαση στη σελίδα <ph name="PAGE_TITLE" /></translation> <translation id="29488703364906173">Ένα γρήγορο, απλό και ασφαλές πρόγραμμα περιήγησης ιστού, το οποίο δημιουργήθηκε για τον σύγχρονο ιστό.</translation> +<translation id="2949289451367477459">Χρήση της τοποθεσίας. Επιτρέψτε στις εφαρμογές και στις υπηρεσίες που έχουν άδεια χρήσης τοποθεσίας να χρησιμοποιούν την τοποθεσία αυτής της συσκευής. Η Google μπορεί να συλλέγει περιοδικά δεδομένα τοποθεσίας και να τα χρησιμοποιεί ανώνυμα, προκειμένου να βελτιώσει την ακρίβεια της τοποθεσίας και των υπηρεσιών που βασίζονται στην τοποθεσία. <ph name="BEGIN_LINK1" />Μάθετε περισσότερα<ph name="END_LINK1" /></translation> <translation id="2958721676848865875">Προειδοποίηση στοίβαξης επέκτασης</translation> <translation id="296026337010986570">Η διαδικασία ολοκληρώθηκε! Το επιβλαβές λογισμικό καταργήθηκε. Για να ενεργοποιήσετε ξανά τις επεκτάσεις, μεταβείτε στην ενότητα <a href="chrome://extensions">Επεκτάσεις</a>.</translation> <translation id="2961090598421146107"><ph name="CERTIFICATE_NAME" /> (παρέχεται επέκταση)</translation> @@ -1643,7 +1648,6 @@ <translation id="3495660573538963482">Ρυθμίσεις του Βοηθού Google</translation> <translation id="3496213124478423963">Σμίκρυνση</translation> <translation id="3505030558724226696">Ανάκληση πρόσβασης στη συσκευή</translation> -<translation id="3506093155988721483">Χρησιμοποιήστε φωνητικές εντολές αντί για πληκτρολόγιο, όταν κάνετε εκκίνηση του Βοηθού</translation> <translation id="3507421388498836150">Τρέχοντα δικαιώματα για "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Κατάργηση εφαρμογών Linux για Chromebook</translation> <translation id="3507888235492474624">Επανάληψη σάρωσης συσκευών Bluetooth</translation> @@ -1764,6 +1768,7 @@ <translation id="3677657024345889897">Χαμηλότερη ένταση</translation> <translation id="3678156199662914018">Επέκταση: <ph name="EXTENSION_NAME" /></translation> <translation id="3681311097828166361">Σας ευχαριστούμε για τα σχόλιά σας. Βρίσκεστε εκτός σύνδεσης αυτήν τη στιγμή. Η αναφορά σας θα σταλεί αργότερα.</translation> +<translation id="3682824389861648626">Ελάχιστο όριο κίνησης</translation> <translation id="3683023058278427253">Εντοπίσαμε πολλούς τύπους αδειών για τον τομέα σας. Επιλέξτε έναν, για να συνεχίσετε.</translation> <translation id="3683524264665795342">Αίτημα κοινής χρήσης οθόνης από την εφαρμογή <ph name="APP_NAME" /></translation> <translation id="3685122418104378273">Ο συγχρονισμός του Google Drive είναι απενεργοποιημένος από προεπιλογή όταν χρησιμοποιούνται δεδομένα κινητής τηλεφωνίας.</translation> @@ -1813,6 +1818,7 @@ <translation id="3742055079367172538">Το στιγμιότυπο οθόνης έχει ληφθεί</translation> <translation id="3742666961763734085">Δεν είναι δυνατή η εύρεση μιας μονάδας οργάνωσης με αυτό το όνομα. Προσπαθήστε ξανά.</translation> <translation id="3744111561329211289">Συγχρονισμός παρασκηνίου</translation> +<translation id="3747077776423672805">Για να καταργήσετε εφαρμογές, μεταβείτε στις Ρυθμίσεις > Google Play Store > Διαχείριση προτιμήσεων Android > Εφαρμογές ή Διαχείριση εφαρμογών. Έπειτα, πατήστε την εφαρμογή που θέλετε να απεγκαταστήσετε (μπορεί να χρειαστεί να σύρετε προς τα δεξιά ή προς τα αριστερά για να βρείτε την εφαρμογή). Στη συνέχεια, πατήστε Απεγκατάσταση ή Απενεργοποίηση.</translation> <translation id="3748026146096797577">Εκτός σύνδεσης</translation> <translation id="3749289110408117711">Όνομα αρχείου</translation> <translation id="3751427701788899101">Η σύνδεση χάθηκε</translation> @@ -1971,6 +1977,7 @@ <translation id="3954953195017194676">Δεν υπάρχουν αρχεία καταγραφής WebRTC που λήφθηκαν πρόσφατα.</translation> <translation id="3955193568934677022">Να επιτρέπεται στους ιστοτόπους να αναπαράγουν προστατευμένο περιεχόμενο (συνιστάται)</translation> <translation id="3956702100721821638">Δεν ήταν δυνατή η επικοινωνία με το Google Play</translation> +<translation id="3957844511978444971">Πατήστε "Αποδοχή" για να επιβεβαιώσετε την επιλογή αυτών των ρυθμίσεων υπηρεσιών Google.</translation> <translation id="3958088479270651626">Εισαγωγή σελιδοδεικτών και ρυθμίσεων</translation> <translation id="3960566196862329469">ONC</translation> <translation id="3965965397408324205">Έξοδος από <ph name="PROFILE_NAME" /></translation> @@ -2061,7 +2068,6 @@ <translation id="4100733287846229632">Ο ελεύθερος χώρος της συσκευής είναι οριακός</translation> <translation id="4103091233824664032">Εισαγάγετε τον κωδικό πρόσβασής σας για να διαμορφώσετε το κλείδωμα της οθόνης και τη σύνδεση</translation> <translation id="4104163789986725820">Ε&ξαγωγή...</translation> -<translation id="4105563239298244027">Αποκτήστε δωρεάν 1 TB με το Google Drive</translation> <translation id="4107048419833779140">Ταυτοποίηση και κατάργηση συσκευών αποθηκευτικού χώρου</translation> <translation id="4109135793348361820">Μετακίνηση παραθύρου στο χρήστη <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Περιήγηση στον ιστό με τη λειτουργία υψηλής αντίθεσης</translation> @@ -2796,6 +2802,7 @@ <translation id="5301954838959518834">OK, το κατάλαβα</translation> <translation id="5302048478445481009">Γλώσσα</translation> <translation id="5305688511332277257">Δεν υπάρχει εγκατεστημένο</translation> +<translation id="5307030433605830021">Η πηγή δεν υποστηρίζεται</translation> <translation id="5308380583665731573">Σύνδεση</translation> <translation id="5311304534597152726">Σύνδεση ως</translation> <translation id="5315873049536339193">Ταυτότητα</translation> @@ -2933,6 +2940,7 @@ <translation id="5507756662695126555">Χωρίς δυνατότητα υπαναχώρησης</translation> <translation id="5509693895992845810">Αποθήκευση &Ως...</translation> <translation id="5509914365760201064">Εκδότης: <ph name="CERTIFICATE_AUTHORITY" /></translation> +<translation id="5511379779384092781">Πολύ μικρό</translation> <translation id="5511823366942919280">Είστε βέβαιοι ότι θέλετε να ορίσετε αυτήν τη συσκευή ως "Shark";</translation> <translation id="5512653252560939721">Θα πρέπει να έχει δημιουργηθεί κάποιο φυσικό αντίγραφο του πιστοποιητικού χρήστη.</translation> <translation id="5516183516694518900">Συνδεθείτε στο Chrome με τον Λογαριασμό σας Google, για να μεταφέρετε τους σελιδοδείκτες, το ιστορικό και τις ρυθμίσεις σας σε όλες τις συσκευές σας.</translation> @@ -2992,6 +3000,10 @@ <translation id="5582839680698949063">Κύριο μενού</translation> <translation id="5583640892426849032">Πλήκτρο Backspace</translation> <translation id="5584088138253955452">Αποθήκευση ονόματος χρήστη;</translation> +<translation id="5584915726528712820"><ph name="BEGIN_PARAGRAPH1" />Αυτές είναι γενικές πληροφορίες σχετικά με τη συσκευή σας και τον τρόπο με τον οποίο τη χρησιμοποιείτε (όπως είναι το επίπεδο της μπαταρίας, η δραστηριότητα συστήματος και εφαρμογών και τα σφάλματα). Τα δεδομένα θα χρησιμοποιηθούν για τη βελτίωση του Android και ορισμένες συγκεντρωτικές πληροφορίες θα βοηθήσουν τις εφαρμογές και τους συνεργάτες της Google, όπως οι προγραμματιστές Android, να βελτιώσουν τις εφαρμογές και τα προϊόντα τους.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Η απενεργοποίηση αυτής της λειτουργίας δεν επηρεάζει τη δυνατότητα της συσκευής να στέλνει τις απαραίτητες πληροφορίες για σημαντικές υπηρεσίες, όπως είναι οι ενημερώσεις συστήματος και η ασφάλεια.<ph name="END_PARAGRAPH2" /> + <ph name="BEGIN_PARAGRAPH3" />Ο κάτοχος μπορεί να ελέγχει αυτήν τη λειτουργία από τις Ρυθμίσεις > Σύνθετες > Αυτόματη αποστολή δεδομένων διαγνωστικών στοιχείων και χρήσης στην Google.<ph name="END_PARAGRAPH3" /> + <ph name="BEGIN_PARAGRAPH4" />Εάν είναι ενεργή η ρύθμιση της πρόσθετης Δραστηριότητας ιστού και εφαρμογών, αυτά τα δεδομένα μπορεί να αποθηκευτούν στον Λογαριασμό σας Google. Μπορείτε να δείτε τα δεδομένα σας, να τα διαγράψετε και να αλλάξετε τις ρυθμίσεις του λογαριασμού σας στη διεύθυνση account.google.com.<ph name="END_PARAGRAPH4" /></translation> <translation id="5585118885427931890">Δεν ήταν δυνατή η δημιουργία φακέλου σελιδοδεικτών.</translation> <translation id="558563010977877295">Ανοίξτε μια συγκεκριμένη σελίδα ή ένα σύνολο σελίδων</translation> <translation id="5585912436068747822">Αποτυχία μορφοποίησης</translation> @@ -3025,6 +3037,7 @@ <translation id="5623842676595125836">Αρχείο καταγραφής</translation> <translation id="5624120631404540903">Διαχείριση κωδικών πρόσβασης</translation> <translation id="5626134646977739690">Όνομα:</translation> +<translation id="5626283214046138476">Ο λογαριασμός εποπτευόμενου χρήστη σας θα λήξει σύντομα.</translation> <translation id="5627086634964711283">Επίσης, ελέγχει τη σελίδα που εμφανίζεται όταν κάνετε κλικ στο κουμπί αρχικής σελίδας.</translation> <translation id="5627676517703583263">Περιηγηθείτε έξυπνα στο Chrome</translation> <translation id="562935524653278697">Ο διαχειριστής σας έχει απενεργοποιήσει τον συγχρονισμό των σελιδοδεικτών, του ιστορικού, των κωδικών πρόσβασης και άλλων ρυθμίσεων.</translation> @@ -3297,6 +3310,8 @@ <translation id="604001903249547235">Αντίγραφο ασφαλείας στο cloud</translation> <translation id="6040143037577758943">Κλείσιμο</translation> <translation id="6040852767465482106">Ανώνυμη ταυτότητα</translation> +<translation id="6041046205544295907"><ph name="BEGIN_PARAGRAPH1" />Η υπηρεσία τοποθεσίας της Google χρησιμοποιεί πηγές όπως δίκτυα Wi‑Fi και κινητής τηλεφωνίας καθώς και αισθητήρες, για τον υπολογισμό της τοποθεσίας της συσκευής σας.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Μπορείτε να απενεργοποιήσετε την Τοποθεσία απενεργοποιώντας τη βασική ρύθμιση "Τοποθεσία" στη συσκευή σας. Μπορείτε επίσης να απενεργοποιήσετε τη χρήση δικτύων Wi-Fi και κινητής τηλεφωνίας και των αισθητήρων για την τοποθεσία στις ρυθμίσεις τοποθεσίας.<ph name="END_PARAGRAPH2" /></translation> <translation id="6041155700700864984">Έξοδος από πλήρη οθόνη</translation> <translation id="604124094241169006">Αυτόματη</translation> <translation id="6042169520002885235">Επιλέξτε έναν κατασκευαστή και ένα μοντέλο εκτυπωτή</translation> @@ -3325,6 +3340,7 @@ <translation id="6074825444536523002">Φόρμα Google</translation> <translation id="6075731018162044558">Ωχ! Το σύστημα δεν κατάφερε να αποκτήσει βραχυπρόθεσμη πρόσβαση API για την παρούσα συσκευή.</translation> <translation id="6075907793831890935">Ανταλλαγή δεδομένων με τη συσκευή με την ονομασία <ph name="HOSTNAME" /></translation> +<translation id="6076175485108489240">Χρήση της τοποθεσίας. Επιτρέψτε στις εφαρμογές και στις υπηρεσίες που έχουν άδεια χρήσης τοποθεσίας να χρησιμοποιούν την τοποθεσία της συσκευής σας. Η Google μπορεί να συλλέγει περιοδικά δεδομένα τοποθεσίας και να τα χρησιμοποιεί ανώνυμα, προκειμένου να βελτιώσει την ακρίβεια της τοποθεσίας και των υπηρεσιών που βασίζονται στην τοποθεσία. <ph name="BEGIN_LINK1" />Μάθετε περισσότερα<ph name="END_LINK1" /></translation> <translation id="6076448957780543068">Συμπερίληψη αυτού του στιγμιότυπου οθόνης</translation> <translation id="6077131872140550515">Κατάργηση από τα προτιμώμενα</translation> <translation id="6077189836672154517">Συμβουλές και ενημερώσεις για <ph name="DEVICE_TYPE" /></translation> @@ -3975,6 +3991,7 @@ <translation id="7088674813905715446">Αυτή η συσκευή έχει τεθεί σε ανενεργή κατάσταση από το διαχειριστή. Για να την ενεργοποιήσετε για εγγραφή, ζητήστε από το διαχειριστή σας να τη θέσει σε κατάσταση εκκρεμότητας.</translation> <translation id="7093434536568905704">GTK+</translation> <translation id="7093866338626856921">Ανταλλαγή δεδομένων με συσκευές με την ονομασία: <ph name="HOSTNAMES" /></translation> +<translation id="7094583680070770403">Αποθηκεύστε τα τοπικά αρχεία σας και ρυθμίστε έναν νέο λογαριασμό.</translation> <translation id="7096857570999173890">Μπορείτε να χρησιμοποιείτε το PIN για να ξεκλειδώνετε τη συσκευή σας όταν είστε αποσυνδεδεμένοι.</translation> <translation id="7098389117866926363">Συσκευή USB-C (πίσω αριστερή θύρα)</translation> <translation id="7098447629416471489">Οι άλλες αποθηκευμένες μηχανές αναζήτησης θα εμφανίζονται εδώ.</translation> @@ -4041,6 +4058,7 @@ <translation id="7191454237977785534">Αποθήκευση αρχείου ως</translation> <translation id="7193374945610105795">Δεν έχουν αποθηκευτεί κωδικοί πρόσβασης για το <ph name="ORIGIN" /></translation> <translation id="7196835305346730603">Γίνεται αναζήτηση για κοντινά Chromebox…</translation> +<translation id="7196913789568937443">Δημιουργία αντιγράφων ασφαλείας στο Google Drive. Επαναφέρετε με ευκολία τα δεδομένα σας ή αλλάξτε συσκευή ανά πάσα στιγμή. Το αντίγραφο ασφαλείας σας περιλαμβάνει δεδομένα εφαρμογών. Τα αντίγραφα ασφαλείας σας μεταφορτώνονται στην Google και κρυπτογραφούνται χρησιμοποιώντας τον κωδικό πρόσβασης του Λογαριασμού σας Google. <ph name="BEGIN_LINK1" />Μάθετε περισσότερα<ph name="END_LINK1" /></translation> <translation id="7197190419934240522">Λήψη Αναζήτησης Google και έξυπνων λειτουργιών Google κάθε φορά που περιηγείστε</translation> <translation id="7197632491113152433">Εντοπίσαμε <ph name="NUMBER_OF_APPS" /> εφαρμογές από τον λογαριασμό σας, η χρήση των οποίων δεν είναι δυνατή σε αυτήν τη συσκευή.</translation> <translation id="7199158086730159431">Λάβετε β&οήθεια</translation> @@ -4127,6 +4145,7 @@ <translation id="7324297612904500502">Φόρουμ για την έκδοση beta</translation> <translation id="7325437708553334317">Επέκταση για τις "Αντιθέσεις"</translation> <translation id="7328162502911382168">(<ph name="COUNT" />)</translation> +<translation id="7328699668338161242">Ο Βοηθός σας μπορεί ήδη να αναγνωρίσει τη φωνή σας</translation> <translation id="7328867076235380839">Μη έγκυρος συνδυασμός</translation> <translation id="7329154610228416156">Η διαδικασία σύνδεσης απέτυχε γιατί είχε ρυθμιστεί να χρησιμοποιεί μια μη ασφαλή διεύθυνση URL (<ph name="BLOCKED_URL" />). Επικοινωνήστε με το διαχειριστή σας.</translation> <translation id="7334190995941642545">Η λειτουργία Smart Lock δεν είναι διαθέσιμη προς το παρόν. Δοκιμάστε ξανά αργότερα.</translation> @@ -4175,6 +4194,7 @@ <translation id="7400839060291901923">Ρυθμίστε τη σύνδεση στο τηλέφωνό σας <ph name="PHONE_NAME" /></translation> <translation id="740624631517654988">Αποκλείστηκε αναδυόμενο παράθυρο</translation> <translation id="7407430846095439694">Εισαγωγή και δέσμευση</translation> +<translation id="7409549334477097887">Πολύ μεγάλο</translation> <translation id="7409836189476010449">Εκτέλεση Flash</translation> <translation id="7410344089573941623">Ερώτηση εάν το <ph name="HOST" /> θέλει να αποκτήσει πρόσβαση στην κάμερα και στο μικρόφωνό σας</translation> <translation id="741204030948306876">Ναι, συμφωνώ</translation> @@ -4483,6 +4503,7 @@ <translation id="7853747251428735">Περισσότερα Ε&ργαλεία</translation> <translation id="7857117644404132472">Προσθήκη εξαίρεσης</translation> <translation id="7857949311770343000">Είναι αυτή η σελίδα νέας καρτέλας που περιμένατε να δείτε;</translation> +<translation id="7859183520363892678">Εκπαιδεύστε τον Βοηθό ώστε να αναγνωρίζει τη φωνή σας</translation> <translation id="786073089922909430">Υπηρεσία: <ph name="ARC_PROCESS_NAME" /></translation> <translation id="7861215335140947162">&Λήψεις</translation> <translation id="7864662577698025113">Προσθήκη νέας υπηρεσίας</translation> @@ -4636,6 +4657,9 @@ <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> <translation id="8074127646604999664">Να επιτρέπεται στους ιστότοπους που έκλεισαν πρόσφατα να ολοκληρώνουν την αποστολή και τη λήψη δεδομένων</translation> <translation id="8076492880354921740">Καρτέλες</translation> <translation id="8076835018653442223">Η πρόσβαση στα τοπικά αρχεία στη συσκευή σας έχει απενεργοποιηθεί από τον διαχειριστή σας</translation> @@ -4646,6 +4670,11 @@ <translation id="8086015605808120405">Διαμόρφωση <ph name="PRINTER_NAME" /> …</translation> <translation id="8090234456044969073">Ανάγνωση λίστας με τους ιστότοπους που επισκέπτεστε πιο συχνά</translation> <translation id="8093359998839330381">Η προσθήκη <ph name="PLUGIN_NAME" /> δεν ανταποκρίνεται</translation> +<translation id="8095105960962832018"><ph name="BEGIN_PARAGRAPH1" />Δημιουργία αντιγράφων ασφαλείας στο Google Drive. Επαναφέρετε με ευκολία τα δεδομένα σας ή αλλάξτε συσκευή ανά πάσα στιγμή. Το αντίγραφο ασφαλείας σας περιλαμβάνει δεδομένα εφαρμογών.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Τα αντίγραφα ασφαλείας σας μεταφορτώνονται στην Google και κρυπτογραφούνται χρησιμοποιώντας τον κωδικό πρόσβασης του Λογαριασμού σας Google.<ph name="END_PARAGRAPH2" /> + <ph name="BEGIN_PARAGRAPH3" />Τα δεδομένα εφαρμογής μπορεί να είναι οποιουδήποτε είδους δεδομένα έχουν αποθηκευτεί από μια εφαρμογή (βάσει των ρυθμίσεων προγραμματιστή σας), συμπεριλαμβανομένων δεδομένων όπως επαφών, μηνυμάτων και φωτογραφιών.<ph name="END_PARAGRAPH3" /> + <ph name="BEGIN_PARAGRAPH4" />Τα δεδομένα αντιγράφων ασφαλείας δεν υπολογίζονται στο όριο του αποθηκευτικού σας χώρου στο Drive.<ph name="END_PARAGRAPH4" /> + <ph name="BEGIN_PARAGRAPH5" />Μπορείτε να απενεργοποιήσετε αυτήν την υπηρεσία στις Ρυθμίσεις.<ph name="END_PARAGRAPH5" /></translation> <translation id="80974698889265265">Τα PIN δεν ταιριάζουν</translation> <translation id="8101987792947961127">Απαιτείται Powerwash στην επόμενη επανεκκίνηση</translation> <translation id="8102159139658438129">Μεταβείτε στις <ph name="LINK_BEGIN" />Ρυθμίσεις<ph name="LINK_END" />, για να δείτε τις επιλογές που έχετε για το συνδεδεμένο τηλέφωνο</translation> @@ -4689,6 +4718,7 @@ <translation id="8162857629993139764">Δημιουργία νέας σημείωσης</translation> <translation id="8168435359814927499">Περιεχόμενο</translation> <translation id="8174047975335711832">Στοιχεία συσκευής</translation> +<translation id="8174876712881364124">Δημιουργία αντιγράφων ασφαλείας στο Google Drive. Επαναφέρετε με ευκολία δεδομένα ή αλλάξτε συσκευή ανά πάσα στιγμή. Αυτό το αντίγραφο ασφαλείας περιλαμβάνει δεδομένα εφαρμογών. Τα δεδομένα μεταφορτώνονται στην Google και κρυπτογραφούνται χρησιμοποιώντας τον κωδικό πρόσβασης του Λογαριασμού Google του παιδιού σας. <ph name="BEGIN_LINK1" />Μάθετε περισσότερα<ph name="END_LINK1" /></translation> <translation id="8177196903785554304">Λεπτομέρειες δικτύου</translation> <translation id="8179976553408161302">Enter</translation> <translation id="8180239481735238521">σελίδα</translation> @@ -4754,6 +4784,10 @@ <translation id="8261506727792406068">Διαγραφή</translation> <translation id="8263744495942430914">Το <ph name="FULLSCREEN_ORIGIN" /> έχει απενεργοποιήσει τον δείκτη του ποντικιού σας.</translation> <translation id="8264718194193514834">Η επέκταση "<ph name="EXTENSION_NAME" />" ενεργοποίησε τη λειτουργία πλήρους οθόνης.</translation> +<translation id="8267961145111171918"><ph name="BEGIN_PARAGRAPH1" />Αυτές είναι γενικές πληροφορίες σχετικά με αυτήν τη συσκευή και τον τρόπο με τον οποίο χρησιμοποιείται (όπως είναι το επίπεδο της μπαταρίας, η δραστηριότητα συστήματος και εφαρμογών και τα σφάλματα). Τα δεδομένα θα χρησιμοποιηθούν για τη βελτίωση του Android και ορισμένες συγκεντρωτικές πληροφορίες θα βοηθήσουν τις εφαρμογές και τους συνεργάτες της Google, όπως οι προγραμματιστές Android, να βελτιώσουν τις εφαρμογές και τα προϊόντα τους.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Η απενεργοποίηση αυτής της λειτουργίας δεν επηρεάζει τη δυνατότητα αυτής της συσκευής να στέλνει τις απαραίτητες πληροφορίες για σημαντικές υπηρεσίες, όπως είναι οι ενημερώσεις συστήματος και η ασφάλεια.<ph name="END_PARAGRAPH2" /> + <ph name="BEGIN_PARAGRAPH3" />Ο κάτοχος μπορεί να ελέγχει αυτήν τη λειτουργία από τις Ρυθμίσεις > Σύνθετες > Αυτόματη αποστολή δεδομένων διαγνωστικών στοιχείων και χρήσης στην Google.<ph name="END_PARAGRAPH3" /> + <ph name="BEGIN_PARAGRAPH4" />Εάν είναι ενεργή η ρύθμιση της πρόσθετης Δραστηριότητας ιστού και εφαρμογών για το παιδί σας, αυτά τα δεδομένα μπορεί να αποθηκευτούν στον Λογαριασμό του Google. Μάθετε περισσότερα σχετικά με αυτές τις ρυθμίσεις και τον τρόπο προσαρμογής τους στη διεύθυνση families.google.com.<ph name="END_PARAGRAPH4" /></translation> <translation id="8270242299912238708">Έγγραφα PDF</translation> <translation id="827097179112817503">Εμφάνιση κουμπιού Αρχικής σελίδας</translation> <translation id="8271246892936492311">{COUNT,plural, =1{1 σελιδοδείκτης διαγράφηκε}other{# σελιδοδείκτες διαγράφηκαν}}</translation> @@ -5335,7 +5369,6 @@ <translation id="9214520840402538427">Ωχ! Η περίοδος προετοιμασίας των ιδιοτήτων χρόνου εγκατάστασης έχει λήξει. Επικοινωνήστε με τον αντιπρόσωπό σας υποστήριξης.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">Προστέθηκε η επέκταση "<ph name="EXTENSION_NAME" />"</translation> -<translation id="9215934040295798075">Ορισμός ταπετσαρίας</translation> <translation id="9218430445555521422">Ορισμός ως προεπιλογή</translation> <translation id="9219103736887031265">Εικόνες</translation> <translation id="9220525904950070496">Κατάργηση λογαριασμού</translation>
diff --git a/chrome/app/resources/generated_resources_en-GB.xtb b/chrome/app/resources/generated_resources_en-GB.xtb index 1472534..0841481 100644 --- a/chrome/app/resources/generated_resources_en-GB.xtb +++ b/chrome/app/resources/generated_resources_en-GB.xtb
@@ -32,6 +32,7 @@ <translation id="1039337018183941703">Invalid or corrupt file</translation> <translation id="1042174272890264476">Your computer also comes with <ph name="SHORT_PRODUCT_NAME" />'s RLZ library built in. RLZ assigns a non-unique, non-personally identifiable tag to measure the searches and <ph name="SHORT_PRODUCT_NAME" /> usage driven by a particular promotional campaign. These labels sometimes appear in Google Search queries in <ph name="PRODUCT_NAME" />.</translation> <translation id="1046059554679513793">Whoops, this name is already in use!</translation> +<translation id="1046635659603195359">It looks like you've already set up Voice Match with your Google Assistant on another device.These previous recordings can be used to make a voice model on this device. This should take less than a minute.</translation> <translation id="1047431265488717055">Copy Link Te&xt</translation> <translation id="1047726139967079566">Bookmark This Page...</translation> <translation id="1047956942837015229">Deleting <ph name="COUNT" /> items...</translation> @@ -91,7 +92,6 @@ <translation id="1123187597739372905">Show sync settings</translation> <translation id="1124772482545689468">User</translation> <translation id="1125550662859510761">Looks like <ph name="WIDTH" /> x <ph name="HEIGHT" /> (Native)</translation> -<translation id="1127216846847548354">Voice activation</translation> <translation id="1128109161498068552">Do not allow any sites to use system exclusive messages to access MIDI devices</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Edit search engine</translation> @@ -166,6 +166,8 @@ On the next screen, please send feedback to help us fix the issue.</translation> <translation id="1217668622537098248">Revert to left click after action</translation> <translation id="121783623783282548">Passwords do not match.</translation> +<translation id="1218839827383191197"><ph name="BEGIN_PARAGRAPH1" />Google's location service uses sources such as Wi-Fi, mobile networks and sensors to help estimate this device’s location.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />You can turn off location by turning off the main location setting on this device. You can also turn off the use of Wi-Fi, mobile networks and sensors for location in location settings.<ph name="END_PARAGRAPH2" /></translation> <translation id="122082903575839559">Certificate Signature Algorithm</translation> <translation id="1221024147024329929">PKCS #1 MD2 With RSA Encryption</translation> <translation id="1221825588892235038">Selection only</translation> @@ -241,6 +243,7 @@ <translation id="1340527397989195812">Back up media from the device using the Files app.</translation> <translation id="1341988552785875222">The current wallpaper is set by '<ph name="APP_NAME" />'. You may need to uninstall '<ph name="APP_NAME" />' before selecting a different wallpaper.</translation> <translation id="1346748346194534595">Right</translation> +<translation id="1347256498747320987">Install updates & apps. By continuing, you agree that this device may also automatically download and install updates and apps from Google, your operator and your device's manufacturer, possibly using mobile data. Some of these apps may offer in-app purchases. <ph name="BEGIN_LINK1" />Learn More<ph name="END_LINK1" /></translation> <translation id="1347975661240122359">Update will begin when battery reaches <ph name="BATTERY_LEVEL" />%.</translation> <translation id="1351692861129622852">Importing <ph name="FILE_COUNT" /> files...</translation> <translation id="1353686479385938207"><ph name="PROVIDER_NAME" />: <ph name="NETWORK_NAME" /></translation> @@ -372,6 +375,7 @@ <translation id="1529899284660134226">Manage shared files and folders</translation> <translation id="1530838837447122178">Open mouse and touchpad device settings</translation> <translation id="1531004739673299060">Application Window</translation> +<translation id="1536754031901697553">Disconnecting...</translation> <translation id="15373452373711364">Large mouse cursor</translation> <translation id="1538729222189715449">Opening Linux files...</translation> <translation id="1540605929960647700">Enable demo mode</translation> @@ -1300,6 +1304,7 @@ <translation id="2946119680249604491">Add connection</translation> <translation id="2948300991547862301">Go to <ph name="PAGE_TITLE" /></translation> <translation id="29488703364906173">A fast, simple and secure web browser, built for the modern web.</translation> +<translation id="2949289451367477459">Use location. Allow apps and services with location permission to use this device’s location. Google may collect location data periodically and use this data in an anonymous way to improve location accuracy and location-based services. <ph name="BEGIN_LINK1" />Learn More<ph name="END_LINK1" /></translation> <translation id="2958721676848865875">Pack extension warning</translation> <translation id="296026337010986570">Finished! Harmful software removed. To turn extensions back on, visit <a href="chrome://extensions">Extensions</a>.</translation> <translation id="2961090598421146107"><ph name="CERTIFICATE_NAME" /> (extension provided)</translation> @@ -1642,7 +1647,6 @@ <translation id="3495660573538963482">Google Assistant settings</translation> <translation id="3496213124478423963">Zoom Out</translation> <translation id="3505030558724226696">Revoke device access</translation> -<translation id="3506093155988721483">Use speech instead of keyboard when you start your Assistant</translation> <translation id="3507421388498836150">Current Permissions for "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Remove Linux Apps for Chromebook</translation> <translation id="3507888235492474624">Re-scan Bluetooth devices</translation> @@ -1763,6 +1767,7 @@ <translation id="3677657024345889897">Quietest</translation> <translation id="3678156199662914018">Extension: <ph name="EXTENSION_NAME" /></translation> <translation id="3681311097828166361">Thank you for your feedback. You are offline now, and your report will be sent later.</translation> +<translation id="3682824389861648626">Movement threshold</translation> <translation id="3683023058278427253">We have detected multiple license types for your domain. Please chose one to continue.</translation> <translation id="3683524264665795342"><ph name="APP_NAME" /> Screen Sharing Request</translation> <translation id="3685122418104378273">Google Drive sync is disabled by default, when using mobile data.</translation> @@ -1812,6 +1817,7 @@ <translation id="3742055079367172538">Screenshot taken</translation> <translation id="3742666961763734085">Can’t find an organisational unit with that name. Please try again.</translation> <translation id="3744111561329211289">Background sync</translation> +<translation id="3747077776423672805">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.</translation> <translation id="3748026146096797577">Not Connected</translation> <translation id="3749289110408117711">File name</translation> <translation id="3751427701788899101">Connection was lost</translation> @@ -1970,6 +1976,7 @@ <translation id="3954953195017194676">You have no recently captured WebRTC event logs.</translation> <translation id="3955193568934677022">Allow sites to play protected content (recommended)</translation> <translation id="3956702100721821638">Couldn't reach Google Play</translation> +<translation id="3957844511978444971">Tap 'Accept' to confirm your selection of these Google services settings.</translation> <translation id="3958088479270651626">Import bookmarks and settings</translation> <translation id="3960566196862329469">ONC</translation> <translation id="3965965397408324205">Exit <ph name="PROFILE_NAME" /></translation> @@ -2060,7 +2067,6 @@ <translation id="4100733287846229632">Device space critically low</translation> <translation id="4103091233824664032">Enter your password to configure screen lock and sign-in</translation> <translation id="4104163789986725820">E&xport...</translation> -<translation id="4105563239298244027">Get 1 TB free with Google Drive</translation> <translation id="4107048419833779140">Identify and eject storage devices</translation> <translation id="4109135793348361820">Move window to <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Browse the web in high contrast mode</translation> @@ -2795,6 +2801,7 @@ <translation id="5301954838959518834">OK, got it</translation> <translation id="5302048478445481009">Language</translation> <translation id="5305688511332277257">None installed</translation> +<translation id="5307030433605830021">Source not supported</translation> <translation id="5308380583665731573">Connect</translation> <translation id="5311304534597152726">Signing in as</translation> <translation id="5315873049536339193">Identity</translation> @@ -2932,6 +2939,7 @@ <translation id="5507756662695126555">Non-repudiation</translation> <translation id="5509693895992845810">Save &As...</translation> <translation id="5509914365760201064">Issuer: <ph name="CERTIFICATE_AUTHORITY" /></translation> +<translation id="5511379779384092781">Extra small</translation> <translation id="5511823366942919280">Are you sure that you want to set up this device as a "Shark"?</translation> <translation id="5512653252560939721">User certificate must be hardware-backed.</translation> <translation id="5516183516694518900">Sign in to Chrome with your Google Account to get your bookmarks, history, passwords and other settings on all your devices.</translation> @@ -2991,6 +2999,10 @@ <translation id="5582839680698949063">Main menu</translation> <translation id="5583640892426849032">Backspace</translation> <translation id="5584088138253955452">Save username?</translation> +<translation id="5584915726528712820"><ph name="BEGIN_PARAGRAPH1" />This is general information about your device and how you use it (such as battery level, system and app activity and errors). The data will be used to improve Android, and some aggregated information will also help Google apps and partners, such as Android developers, make their apps and products better.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Turning off this feature doesn't affect your device's ability to send the information needed for essential services such as system updates and security.<ph name="END_PARAGRAPH2" /> + <ph name="BEGIN_PARAGRAPH3" />The owner can control this feature from Settings > Advanced > Automatically send diagnostic and usage data to Google.<ph name="END_PARAGRAPH3" /> + <ph name="BEGIN_PARAGRAPH4" />If your additional Web & app activity setting is turned on, this data may be saved to your Google Account. You can see your data, delete it and change your account settings at account.google.com.<ph name="END_PARAGRAPH4" /></translation> <translation id="5585118885427931890">Could not create bookmark folder.</translation> <translation id="558563010977877295">Open a specific page or set of pages</translation> <translation id="5585912436068747822">Formatting failed</translation> @@ -3023,6 +3035,7 @@ <translation id="5623842676595125836">Log</translation> <translation id="5624120631404540903">Manage passwords</translation> <translation id="5626134646977739690">Name:</translation> +<translation id="5626283214046138476">Your supervised user account is expiring soon.</translation> <translation id="5627086634964711283">It also controls what page is shown when you click the Home button.</translation> <translation id="5627676517703583263">Browse smart with Chrome</translation> <translation id="562935524653278697">Your administrator has disabled syncing of your bookmarks, history, passwords and other settings.</translation> @@ -3295,6 +3308,8 @@ <translation id="604001903249547235">Cloud backup</translation> <translation id="6040143037577758943">Close</translation> <translation id="6040852767465482106">Anonymous Identity</translation> +<translation id="6041046205544295907"><ph name="BEGIN_PARAGRAPH1" />Google's location service uses sources such as Wi-Fi, mobile networks and sensors to help estimate your device’s location.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />You can turn off location by turning off the main location setting on your device. You can also turn off the use of Wi-Fi, mobile networks and sensors for location in location settings.<ph name="END_PARAGRAPH2" /></translation> <translation id="6041155700700864984">Exit Full Screen</translation> <translation id="604124094241169006">Automatic</translation> <translation id="6042169520002885235">Select a printer manufacturer and model</translation> @@ -3323,6 +3338,7 @@ <translation id="6074825444536523002">Google form</translation> <translation id="6075731018162044558">Oops! The system failed to attain a long-term API access token for this device.</translation> <translation id="6075907793831890935">Exchange data with the device named <ph name="HOSTNAME" /></translation> +<translation id="6076175485108489240">Use location. Allow apps and services with location permission to use your device’s location. Google may collect location data periodically and use this data in an anonymous way to improve location accuracy and location-based services. <ph name="BEGIN_LINK1" />Learn More<ph name="END_LINK1" /></translation> <translation id="6076448957780543068">Include this screenshot</translation> <translation id="6077131872140550515">Remove from preferred</translation> <translation id="6077189836672154517">Tips and updates on <ph name="DEVICE_TYPE" /></translation> @@ -3973,6 +3989,7 @@ <translation id="7088674813905715446">This device has been placed into a deprovisioned state by the administrator. To enable it for enrolment, please have your administrator place the device into a pending state.</translation> <translation id="7093434536568905704">GTK+</translation> <translation id="7093866338626856921">Exchange data with the devices named: <ph name="HOSTNAMES" /></translation> +<translation id="7094583680070770403">Please save your local files and set up a new account.</translation> <translation id="7096857570999173890">You can use your PIN to unlock your device when you are signed out.</translation> <translation id="7098389117866926363">USB-C device (left port in the back)</translation> <translation id="7098447629416471489">Other saved search engines will appear here</translation> @@ -4039,6 +4056,7 @@ <translation id="7191454237977785534">Save file as</translation> <translation id="7193374945610105795">No passwords saved for <ph name="ORIGIN" /></translation> <translation id="7196835305346730603">Searching for nearby Chromeboxes...</translation> +<translation id="7196913789568937443">Back up to Google Drive. Easily restore your data or switch device at any time. Your backup includes app data. Your backups are uploaded to Google and encrypted using your Google Account password. <ph name="BEGIN_LINK1" />Learn More<ph name="END_LINK1" /></translation> <translation id="7197190419934240522">Get Google Search and Google smarts every time that you browse</translation> <translation id="7197632491113152433">We found <ph name="NUMBER_OF_APPS" /> apps from your account that can be used on this device.</translation> <translation id="7199158086730159431">Get H&elp</translation> @@ -4125,6 +4143,7 @@ <translation id="7324297612904500502">Beta forum</translation> <translation id="7325437708553334317">High Contrast Extension</translation> <translation id="7328162502911382168">(<ph name="COUNT" />)</translation> +<translation id="7328699668338161242">Your Assistant can already recognise your voice</translation> <translation id="7328867076235380839">Invalid combination</translation> <translation id="7329154610228416156">Sign-in failed because it was configured to use a non-secure URL (<ph name="BLOCKED_URL" />). Please contact your administrator.</translation> <translation id="7334190995941642545">Smart Lock is currently unavailable. Please try again later.</translation> @@ -4173,6 +4192,7 @@ <translation id="7400839060291901923">Set up connection on your <ph name="PHONE_NAME" /></translation> <translation id="740624631517654988">Pop-up blocked</translation> <translation id="7407430846095439694">Import and Bind</translation> +<translation id="7409549334477097887">Extra large</translation> <translation id="7409836189476010449">Run Flash</translation> <translation id="7410344089573941623">Ask if <ph name="HOST" /> wants to access your camera and microphone</translation> <translation id="741204030948306876">Yes, I'm in</translation> @@ -4481,6 +4501,7 @@ <translation id="7853747251428735">More Too&ls</translation> <translation id="7857117644404132472">Add exception</translation> <translation id="7857949311770343000">Is this the new tab page that you were expecting?</translation> +<translation id="7859183520363892678">Teach the Assistant to recognise your voice</translation> <translation id="786073089922909430">Service: <ph name="ARC_PROCESS_NAME" /></translation> <translation id="7861215335140947162">&Downloads</translation> <translation id="7864662577698025113">Add new service</translation> @@ -4634,6 +4655,9 @@ <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> <translation id="8074127646604999664">Allow recently closed sites to finish sending and receiving data</translation> <translation id="8076492880354921740">Tabs</translation> <translation id="8076835018653442223">Access to local files on your device is disabled by your administrator</translation> @@ -4644,6 +4668,11 @@ <translation id="8086015605808120405">Configuring <ph name="PRINTER_NAME" /> ...</translation> <translation id="8090234456044969073">Read a list of your most frequently visited websites</translation> <translation id="8093359998839330381"><ph name="PLUGIN_NAME" /> isn't responding</translation> +<translation id="8095105960962832018"><ph name="BEGIN_PARAGRAPH1" />Back up to Google Drive. Easily restore your data or switch device at any time. Your backup includes app data.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Your backups are uploaded to Google and encrypted using your Google Account password.<ph name="END_PARAGRAPH2" /> + <ph name="BEGIN_PARAGRAPH3" />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_PARAGRAPH3" /> + <ph name="BEGIN_PARAGRAPH4" />Backup data will not count toward your Drive storage quota.<ph name="END_PARAGRAPH4" /> + <ph name="BEGIN_PARAGRAPH5" />You can turn this service off in Settings.<ph name="END_PARAGRAPH5" /></translation> <translation id="80974698889265265">PINs do not match</translation> <translation id="8101987792947961127">Powerwash required on next reboot</translation> <translation id="8102159139658438129">Go to <ph name="LINK_BEGIN" />Settings<ph name="LINK_END" /> to see options for your connected phone</translation> @@ -4687,6 +4716,7 @@ <translation id="8162857629993139764">Create new note</translation> <translation id="8168435359814927499">Content</translation> <translation id="8174047975335711832">Device information</translation> +<translation id="8174876712881364124">Back up to Google Drive. Easily restore data or switch device at any time. This backup includes app data. Backups are uploaded to Google and encrypted using your child's Google Account password. <ph name="BEGIN_LINK1" />Learn More<ph name="END_LINK1" /></translation> <translation id="8177196903785554304">Network Details</translation> <translation id="8179976553408161302">Enter</translation> <translation id="8180239481735238521">page</translation> @@ -4752,6 +4782,10 @@ <translation id="8261506727792406068">Delete</translation> <translation id="8263744495942430914"><ph name="FULLSCREEN_ORIGIN" /> has disabled your mouse cursor.</translation> <translation id="8264718194193514834">"<ph name="EXTENSION_NAME" />" triggered full screen.</translation> +<translation id="8267961145111171918"><ph name="BEGIN_PARAGRAPH1" />This is general information about this device and how it's used (such as battery level, system and app activity and errors). The data will be used to improve Android, and some aggregated information will also help Google apps and partners, such as Android developers, make their apps and products better.<ph name="END_PARAGRAPH1" /> + <ph name="BEGIN_PARAGRAPH2" />Turning off this feature doesn't affect this device's ability to send the information needed for essential services such as system updates and security.<ph name="END_PARAGRAPH2" /> + <ph name="BEGIN_PARAGRAPH3" />The owner can control this feature from Settings > Advanced > Automatically send diagnostic and usage data to Google.<ph name="END_PARAGRAPH3" /> + <ph name="BEGIN_PARAGRAPH4" />If additional Web & app activity setting is turned on for your child, this data may be saved to their Google Account. Learn more about these settings and how to adjust them at families.google.com.<ph name="END_PARAGRAPH4" /></translation> <translation id="8270242299912238708">PDF documents</translation> <translation id="827097179112817503">Show Home button</translation> <translation id="8271246892936492311">{COUNT,plural, =1{1 bookmark deleted}other{# bookmarks deleted}}</translation> @@ -5335,7 +5369,6 @@ <translation id="9214520840402538427">Oops! The initialisation of the installation-time attributes has timed out. Please contact your support representative.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" added</translation> -<translation id="9215934040295798075">Set wallpaper</translation> <translation id="9218430445555521422">Set as default</translation> <translation id="9219103736887031265">Images</translation> <translation id="9220525904950070496">Remove account</translation>
diff --git a/chrome/app/resources/generated_resources_es-419.xtb b/chrome/app/resources/generated_resources_es-419.xtb index 81c4262f..df76d2e7 100644 --- a/chrome/app/resources/generated_resources_es-419.xtb +++ b/chrome/app/resources/generated_resources_es-419.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Mostrar la configuración de sincronización</translation> <translation id="1124772482545689468">Usuario</translation> <translation id="1125550662859510761">Resolución: <ph name="WIDTH" /> × <ph name="HEIGHT" /> (nativa)</translation> -<translation id="1127216846847548354">Activación por voz</translation> <translation id="1128109161498068552">No permitir que los sitios usen mensajes exclusivos del sistema para acceder a dispositivos MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Editar el motor de búsqueda</translation> @@ -1640,7 +1639,6 @@ <translation id="3495660573538963482">Configuración del Asistente de Google</translation> <translation id="3496213124478423963">Alejar</translation> <translation id="3505030558724226696">Revocar el acceso al dispositivo</translation> -<translation id="3506093155988721483">Usa la voz en lugar del teclado cuando inicias tu Asistente</translation> <translation id="3507421388498836150">Permisos actuales para "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Quitar las apps de Linux para la Chromebook</translation> <translation id="3507888235492474624">Vuelve a buscar dispositivos Bluetooth</translation> @@ -2058,7 +2056,6 @@ <translation id="4100733287846229632">Hay muy poco espacio en el dispositivo</translation> <translation id="4103091233824664032">Ingresa tu contraseña para configurar el bloqueo de pantalla y acceder</translation> <translation id="4104163789986725820">E&xportar...</translation> -<translation id="4105563239298244027">Obtén 1 TB gratuito con Google Drive</translation> <translation id="4107048419833779140">Identificar y expulsar los dispositivos de almacenamiento</translation> <translation id="4109135793348361820">Mover ventana a <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Navegar en la Web en el modo de contraste alto</translation> @@ -5334,7 +5331,6 @@ <translation id="9214520840402538427">¡Vaya! Se ha agotado el tiempo de la inicialización de los atributos de tiempo de instalación. Comunícate con el representante de asistencia.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" agregada</translation> -<translation id="9215934040295798075">Establecer fondo de pantalla</translation> <translation id="9218430445555521422">Establecer como predeterminado</translation> <translation id="9219103736887031265">Imágenes</translation> <translation id="9220525904950070496">Eliminar cuenta</translation>
diff --git a/chrome/app/resources/generated_resources_es.xtb b/chrome/app/resources/generated_resources_es.xtb index 2284d59..4c9e81c 100644 --- a/chrome/app/resources/generated_resources_es.xtb +++ b/chrome/app/resources/generated_resources_es.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Mostrar ajustes de sincronización</translation> <translation id="1124772482545689468">Usuario</translation> <translation id="1125550662859510761">Resolución de <ph name="WIDTH" />x<ph name="HEIGHT" /> (nativa)</translation> -<translation id="1127216846847548354">Activación por voz</translation> <translation id="1128109161498068552">No permitir que ningún sitio utilice mensajes exclusivos del sistema para acceder a los dispositivos MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Editar motor de búsqueda</translation> @@ -1641,7 +1640,6 @@ <translation id="3495660573538963482">Configuración del Asistente de Google</translation> <translation id="3496213124478423963">Alejar</translation> <translation id="3505030558724226696">Revocar acceso al dispositivo</translation> -<translation id="3506093155988721483">Usar la voz en lugar del teclado al iniciar el Asistente</translation> <translation id="3507421388498836150">Permisos actuales para <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Eliminar aplicaciones de Linux del Chromebook</translation> <translation id="3507888235492474624">Volver a buscar dispositivos Bluetooth</translation> @@ -2058,7 +2056,6 @@ <translation id="4100733287846229632">Queda muy poco espacio en el dispositivo</translation> <translation id="4103091233824664032">Introduce tu contraseña para configurar el bloqueo de pantalla y el inicio de sesión</translation> <translation id="4104163789986725820">E&xportar...</translation> -<translation id="4105563239298244027">Consigue 1 TB gratis con Google Drive</translation> <translation id="4107048419833779140">Identificar y expulsar dispositivos de almacenamiento</translation> <translation id="4109135793348361820">Mover ventana a <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Navega por la Web con el modo de contraste alto</translation> @@ -5333,7 +5330,6 @@ <translation id="9214520840402538427">¡Vaya! Se ha agotado el tiempo de la inicialización de los atributos de tiempo de instalación. Ponte en contacto con el representante del servicio de asistencia.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" añadida</translation> -<translation id="9215934040295798075">Establecer fondo de pantalla</translation> <translation id="9218430445555521422">Establecer como predeterminado</translation> <translation id="9219103736887031265">Imágenes</translation> <translation id="9220525904950070496">Quitar cuenta</translation>
diff --git a/chrome/app/resources/generated_resources_et.xtb b/chrome/app/resources/generated_resources_et.xtb index 02110efa9..03aff17 100644 --- a/chrome/app/resources/generated_resources_et.xtb +++ b/chrome/app/resources/generated_resources_et.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Kuva sünkroonimisseaded</translation> <translation id="1124772482545689468">Kasutaja</translation> <translation id="1125550662859510761">Näib kui <ph name="WIDTH" /> × <ph name="HEIGHT" /> (loomulik eraldusvõime)</translation> -<translation id="1127216846847548354">Häälega aktiveerimine</translation> <translation id="1128109161498068552">Ära luba ühelgi saidil kasutada süsteemi eksklusiivseid sõnumeid MIDI-seadmetele juurdepääsu saamiseks</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Otsingumootori muutmine</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Google'i assistendi seaded</translation> <translation id="3496213124478423963">Vähenda</translation> <translation id="3505030558724226696">Tühista juurdepääs seadmele</translation> -<translation id="3506093155988721483">Kasuta assistendi käivitamisel klaviatuuri asemel häält</translation> <translation id="3507421388498836150">Laiendi „<ph name="EXTENSION_NAME" />” praegused õigused</translation> <translation id="3507547268929739059">Linuxi rakenduste eemaldamine Chromebookist</translation> <translation id="3507888235492474624">Otsi Bluetoothi seadmeid uuesti</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Seadmes on kriitiliselt vähe kettaruumi</translation> <translation id="4103091233824664032">Ekraaniluku seadistamiseks ja sisselogimiseks sisestage parool</translation> <translation id="4104163789986725820">&Ekspordi...</translation> -<translation id="4105563239298244027">Saate Google Drive'is tasuta 1 TB vaba ruumi</translation> <translation id="4107048419833779140">Salvestusseadmete tuvastamine ja väljutamine</translation> <translation id="4109135793348361820">Teisalda aken kasutaja <ph name="USER_NAME" /> töölauale (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Sirvige veebi suure kontrastsusega režiimis</translation> @@ -5337,7 +5334,6 @@ <translation id="9214520840402538427">Installimisaja atribuutide lähtestamisel ilmnes ajalõpp. Võtke ühendust tugiteenuse esindajaga.</translation> <translation id="9214695392875603905">Keeks</translation> <translation id="9215293857209265904">Lisati „<ph name="EXTENSION_NAME" />”</translation> -<translation id="9215934040295798075">Taustapildi määramine</translation> <translation id="9218430445555521422">Seadista vaikebrauseriks</translation> <translation id="9219103736887031265">Pildid</translation> <translation id="9220525904950070496">Konto eemaldamine</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb index 0614683..20cec6b2 100644 --- a/chrome/app/resources/generated_resources_fa.xtb +++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">نمایش تنظیمات همگامسازی</translation> <translation id="1124772482545689468">کاربر</translation> <translation id="1125550662859510761"><ph name="WIDTH" /> × <ph name="HEIGHT" /> بهنظر میرسد (داخلی)</translation> -<translation id="1127216846847548354">فعالسازی صدا</translation> <translation id="1128109161498068552">به هیچ سایتی اجازه داده نشود برای دسترسی به دستگاههای MIDI از پیامهای انحصاری سیستم استفاده کند</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">ویرایش موتور جستجو</translation> @@ -1639,7 +1638,6 @@ <translation id="3495660573538963482">تنظیمات «دستیار Google»</translation> <translation id="3496213124478423963">Zoom Out (دورنمایی)</translation> <translation id="3505030558724226696">لغو دسترسی دستگاه</translation> -<translation id="3506093155988721483">استفاده از گفتار بهجای صفحهکلید هنگام راهاندازی «دستیار»</translation> <translation id="3507421388498836150">اجازههای فعلی برای «<ph name="EXTENSION_NAME" />»</translation> <translation id="3507547268929739059">حذف برنامههای Linux برای Chromebook</translation> <translation id="3507888235492474624">اسکن مجدد دستگاههای بلوتوث</translation> @@ -2057,7 +2055,6 @@ <translation id="4100733287846229632">فضای دستگاه خیلی کم است</translation> <translation id="4103091233824664032">برای پیکربندی قفل صفحه و ورود به سیستم، گذرواژهتان را وارد کنید</translation> <translation id="4104163789986725820">&صادر کردن...</translation> -<translation id="4105563239298244027">با Google Drive یک ترابایت فضای رایگان دریافت کنید</translation> <translation id="4107048419833779140">شناسایی و خارج کردن دستگاههای ذخیرهسازی</translation> <translation id="4109135793348361820">انتقال پنجره به <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">مرور وب در حالت کنتراست بالا</translation> @@ -5332,7 +5329,6 @@ <translation id="9214520840402538427">متأسفیم! مهلت مقداردهی اولیه از ویژگیهای زمان نصب به پایان رسیده است. لطفاً با نماینده پشتیبانی خود تماس بگیرید.</translation> <translation id="9214695392875603905">کیک فنجانی</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" اضافه شد</translation> -<translation id="9215934040295798075">تنظیم کاغذدیواری</translation> <translation id="9218430445555521422">تنظیم بهعنوان پیشفرض</translation> <translation id="9219103736887031265">تصاویر</translation> <translation id="9220525904950070496">حذف حساب</translation>
diff --git a/chrome/app/resources/generated_resources_fi.xtb b/chrome/app/resources/generated_resources_fi.xtb index d872444..1acd962 100644 --- a/chrome/app/resources/generated_resources_fi.xtb +++ b/chrome/app/resources/generated_resources_fi.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Näytä synkronointiasetukset</translation> <translation id="1124772482545689468">Käyttäjä</translation> <translation id="1125550662859510761">Näyttää olevan <ph name="WIDTH" /> x <ph name="HEIGHT" /> (natiivi)</translation> -<translation id="1127216846847548354">Aktivointi puhumalla</translation> <translation id="1128109161498068552">Älä anna sivustojen käyttää MIDI-laitteita järjestelmän omien viestien avulla</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Muokkaa hakukonetta</translation> @@ -1644,7 +1643,6 @@ <translation id="3495660573538963482">Google Assistantin asetukset</translation> <translation id="3496213124478423963">Loitonna</translation> <translation id="3505030558724226696">Peruuta laitteen käyttöoikeus</translation> -<translation id="3506093155988721483">Käynnistä Assistant näppäimistön sijaan puhumalla</translation> <translation id="3507421388498836150">Laajennuksen <ph name="EXTENSION_NAME" /> nykyiset käyttöoikeudet</translation> <translation id="3507547268929739059">Poista Linux-sovellukset Chromebookista</translation> <translation id="3507888235492474624">Hae Bluetooth-laitteet uudelleen</translation> @@ -2059,7 +2057,6 @@ <translation id="4100733287846229632">Laitteen tallennustila on erittäin vähissä</translation> <translation id="4103091233824664032">Syötä salasanasi määrittääksesi näytön lukituksen ja sisäänkirjautumisen.</translation> <translation id="4104163789986725820">V&ie...</translation> -<translation id="4105563239298244027">1 Tt ilmaista tallennustilaa Google Drivessa</translation> <translation id="4107048419833779140">Tunnistaa ja poistaa tallennuslaitteet</translation> <translation id="4109135793348361820">Siirrä ikkuna käyttäjälle <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Selaa internetiä Suuri kontrasti ‑tilassa</translation> @@ -5335,7 +5332,6 @@ <translation id="9214520840402538427">Hups! Asennus-aika-attribuuttien alustaminen on aikakatkaistu. Ota yhteyttä tukipalveluun.</translation> <translation id="9214695392875603905">Kuppikakku</translation> <translation id="9215293857209265904"><ph name="EXTENSION_NAME" /> lisätty</translation> -<translation id="9215934040295798075">Aseta taustakuva</translation> <translation id="9218430445555521422">Aseta oletusselaimeksi</translation> <translation id="9219103736887031265">Kuvat</translation> <translation id="9220525904950070496">Poista tili</translation>
diff --git a/chrome/app/resources/generated_resources_fil.xtb b/chrome/app/resources/generated_resources_fil.xtb index ec05af39..26f4bc6 100644 --- a/chrome/app/resources/generated_resources_fil.xtb +++ b/chrome/app/resources/generated_resources_fil.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Ipakita ang mga setting ng pag-sync</translation> <translation id="1124772482545689468">User</translation> <translation id="1125550662859510761">Mukhang <ph name="WIDTH" /> x <ph name="HEIGHT" /> (Native)</translation> -<translation id="1127216846847548354">Pag-activate gamit ang boses</translation> <translation id="1128109161498068552">Huwag payagan ang anumang mga site na gamitin ang mga eksklusibong mensahe ng system upang i-access ang mga MIDI device</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">I-edit ang search engine</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Mga setting ng Google Assistant</translation> <translation id="3496213124478423963">Zoom Out</translation> <translation id="3505030558724226696">Bawiin ang access sa device</translation> -<translation id="3506093155988721483">Gumamit ng boses sa halip na keyboard kapag sisimulan mo ang iyong Assistant</translation> <translation id="3507421388498836150">Mga Kasalukuyang Pahintulot para sa "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Alisin ang mga App ng Linux sa Chromebook</translation> <translation id="3507888235492474624">Muling mag-scan ng mga Bluetooth device</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Sobrang kaunti na lang ang espasyo ng device</translation> <translation id="4103091233824664032">Ilagay ang iyong password para i-configure ang lock ng screen at pag-sign in</translation> <translation id="4104163789986725820">I-e&xport...</translation> -<translation id="4105563239298244027">Makakuha ng libreng 1 TB sa Google Drive</translation> <translation id="4107048419833779140">Kumilala at mag-eject ng mga storage device</translation> <translation id="4109135793348361820">Ilipat ang window sa <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">I-browse ang web sa high contrast mode</translation> @@ -5338,7 +5335,6 @@ <translation id="9214520840402538427">Oops! Nag-time out ang pagpapasimula sa mga katangian ng pag-install at panahon. Mangyaring makipag-ugnay sa iyong kinatawan ng suporta.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">Idinagdag ang "<ph name="EXTENSION_NAME" />"</translation> -<translation id="9215934040295798075">Magtakda ng wallpaper</translation> <translation id="9218430445555521422">Itakda bilang default</translation> <translation id="9219103736887031265">Mga Larawan</translation> <translation id="9220525904950070496">Alisin ang account</translation>
diff --git a/chrome/app/resources/generated_resources_fr.xtb b/chrome/app/resources/generated_resources_fr.xtb index de5b681..ca498d8 100644 --- a/chrome/app/resources/generated_resources_fr.xtb +++ b/chrome/app/resources/generated_resources_fr.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Afficher les paramètres de synchronisation</translation> <translation id="1124772482545689468">Utilisateur</translation> <translation id="1125550662859510761">La résolution est de <ph name="WIDTH" /> x <ph name="HEIGHT" /> (native)</translation> -<translation id="1127216846847548354">Activation des commandes vocales</translation> <translation id="1128109161498068552">N'autoriser aucun site à utiliser des messages spécifiques au système pour accéder aux appareils MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Modifier le moteur de recherche</translation> @@ -616,7 +615,7 @@ <translation id="1880905663253319515">Supprimer le certificat "<ph name="CERTIFICATE_NAME" />" ?</translation> <translation id="1886996562706621347">Permettre aux sites de demander l'autorisation de devenir gestionnaires par défaut des protocoles (recommandé)</translation> <translation id="1887442540531652736">Erreur de connexion</translation> -<translation id="1887597546629269384">Dites à nouveau "Dis Google"</translation> +<translation id="1887597546629269384">Dites à nouveau "Ok Google"</translation> <translation id="1887850431809612466">Version du matériel</translation> <translation id="1889984860246851556">Ouvrir les paramètres de proxy</translation> <translation id="1890674179660343635"><span>Identifiant</span> : <ph name="EXTENSION_ID" /></translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Paramètres de l'Assistant Google</translation> <translation id="3496213124478423963">Zoom arrière</translation> <translation id="3505030558724226696">Retirer les droits d'accès aux appareils</translation> -<translation id="3506093155988721483">Utiliser la saisie vocale au lieu du clavier pour démarrer l'Assistant</translation> <translation id="3507421388498836150">Autorisations actuelles pour <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Supprimer les applications Linux pour Chromebook</translation> <translation id="3507888235492474624">Relancer la recherche d'appareils Bluetooth</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Très peu d'espace disponible sur l'appareil</translation> <translation id="4103091233824664032">Saisissez votre mot de passe pour configurer le verrouillage de l'écran et la connexion</translation> <translation id="4104163789986725820">E&xporter...</translation> -<translation id="4105563239298244027">Profitez d'un téraoctet d'espace de stockage gratuit grâce à Google Drive</translation> <translation id="4107048419833779140">Identifier et exclure des périphériques de stockage</translation> <translation id="4109135793348361820">Déplacer la fenêtre vers <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Parcourir le Web en mode Contraste élevé</translation> @@ -2289,7 +2286,7 @@ <translation id="4524832533047962394">Le mode d'enregistrement proposé n'est pas compatible avec cette version du système d'exploitation. Vérifiez que vous utilisez bien la version la plus récente.</translation> <translation id="4525382759303819021">Obtenir les dernières actualités et recommandations concernant les applications Play Store</translation> <translation id="4530494379350999373">Origine</translation> -<translation id="4533846798469727141">Maintenant, dites "Dis Google"</translation> +<translation id="4533846798469727141">Maintenant, dites "OK Google"</translation> <translation id="4533985347672295764">Temps CPU</translation> <translation id="4534661889221639075">Réessayez.</translation> <translation id="4535127706710932914">Profil par défaut</translation> @@ -5337,7 +5334,6 @@ <translation id="9214520840402538427">Petit problème… Le délai alloué à l'initialisation des attributs de temps d'installation a expiré. Veuillez contacter le service d'assistance.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" ajoutée</translation> -<translation id="9215934040295798075">Définir le fond d'écran</translation> <translation id="9218430445555521422">Définir comme navigateur par défaut</translation> <translation id="9219103736887031265">Images</translation> <translation id="9220525904950070496">Supprimer le compte</translation>
diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb index ff44b83..f2d3a63 100644 --- a/chrome/app/resources/generated_resources_gu.xtb +++ b/chrome/app/resources/generated_resources_gu.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">સિંક સેટિંગ બતાવો</translation> <translation id="1124772482545689468">વપરાશકર્તા</translation> <translation id="1125550662859510761"><ph name="WIDTH" /> x <ph name="HEIGHT" /> જેવું લાગે છે (મૂળ)</translation> -<translation id="1127216846847548354">વૉઇસ સક્રિય કરવો</translation> <translation id="1128109161498068552">MIDI ઉપકરણોને ઍક્સેસ કરવા માટે સિસ્ટમના એકમાત્ર સંદેશાઓનો ઉપયોગ કરવાની કોઇપણ સાઇટ્સને મંજૂરી આપશો નહીં</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">શોધ એંજિનમાં ફેરફાર કરો</translation> @@ -1639,7 +1638,6 @@ <translation id="3495660573538963482">Google સહાયકની સેટિંગ્સ</translation> <translation id="3496213124478423963">ઝૂમ ઘટાડો</translation> <translation id="3505030558724226696">ઉપકરણ ઍક્સેસ રદબાતલ કરો</translation> -<translation id="3506093155988721483">તમારા આસિસ્ટંટને શરૂ કરો ત્યારે, કીબોર્ડને બદલે વાણીનો ઉપયોગ કરો</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" માટે વર્તમાન પરવાનગીઓ</translation> <translation id="3507547268929739059">Chromebook માટે Linux ઍપને કાઢી નાખો</translation> <translation id="3507888235492474624">બ્લૂટૂથ ડિવાઇસને ફરીથી સ્કૅન કરો</translation> @@ -2057,7 +2055,6 @@ <translation id="4100733287846229632">ઉપકરણ સ્થાન અત્યંત ઓછું છે</translation> <translation id="4103091233824664032">સ્ક્રીન લૉક ગોઠવવા અને સાઇન ઇન કરવા માટે, તમારો પાસવર્ડ દાખલ કરો</translation> <translation id="4104163789986725820">નિ&કાસ કરો...</translation> -<translation id="4105563239298244027">Google ડ્રાઇવ સાથે 1 TB મફત મેળવો</translation> <translation id="4107048419833779140">સ્ટોરેજ ઉપકરણોને ઓળખો અને તેને બહાર કાઢો</translation> <translation id="4109135793348361820"><ph name="USER_NAME" /> (<ph name="USER_EMAIL" />) પર વિંડો ખસેડો</translation> <translation id="4110895898888439383">ઉચ્ચ કોન્ટ્રાસ્ટ મોડમાં વેબ બ્રાઉઝ કરો</translation> @@ -5325,7 +5322,6 @@ <translation id="9214520840402538427">અરે! ઇન્સ્ટૉલેશન-સમયનો ચાલુ એટ્રિબ્યૂટનો સમય સમાપ્ત થયો. કૃપા કરીને તમારા સપોર્ટ પ્રતિનિધિનો સંપર્ક કરો.</translation> <translation id="9214695392875603905">કપકૅક</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" ઉમેરાયું</translation> -<translation id="9215934040295798075">વૉલપેપર સેટ કરો</translation> <translation id="9218430445555521422">ડિફોલ્ટ તરીકે સેટ કરો</translation> <translation id="9219103736887031265">છબીઓ</translation> <translation id="9220525904950070496">એકાઉન્ટ દૂર કરો</translation>
diff --git a/chrome/app/resources/generated_resources_hi.xtb b/chrome/app/resources/generated_resources_hi.xtb index 010d5819..b8d25743 100644 --- a/chrome/app/resources/generated_resources_hi.xtb +++ b/chrome/app/resources/generated_resources_hi.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">सिंक सेटिंग दिखाएं</translation> <translation id="1124772482545689468">उपयोगकर्ता</translation> <translation id="1125550662859510761"><ph name="WIDTH" /> x <ph name="HEIGHT" /> जैसा लगता है (मूल)</translation> -<translation id="1127216846847548354">बोलकर चालू करना</translation> <translation id="1128109161498068552">किसी भी साइट को MIDI डिवाइस को एक्सेस करने के लिए सिस्टम अनन्य संदेशों का उपयोग न करने दें.</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">खोज इंजन संपादित करें</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Google Assistant सेटिंग</translation> <translation id="3496213124478423963">ज़ूम आउट</translation> <translation id="3505030558724226696">डिवाइस एक्सेस निरस्त करें</translation> -<translation id="3506093155988721483">अपनी Assistant सेवा चालू करते समय कीबोर्ड के बजाय आवाज़ का इस्तेमाल करें</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" के लिए वर्तमान अनुमतियां</translation> <translation id="3507547268929739059">Chromebook के लिए Linux ऐप्लिकेशन हटाएं</translation> <translation id="3507888235492474624">ब्लूटूथ डिवाइस के लिए दोबारा स्कैन करें</translation> @@ -2060,7 +2058,6 @@ <translation id="4100733287846229632">डिवाइस में बहुत ही कम स्थान बचा है</translation> <translation id="4103091233824664032">स्क्रीन लॉक कॉन्फ़िगर करने के लिए अपना पासवर्ड डालें और साइन इन करें</translation> <translation id="4104163789986725820">नि&र्यात करें...</translation> -<translation id="4105563239298244027">Google डिस्क के साथ 1 TB मुफ़्त पाएं</translation> <translation id="4107048419833779140">मेमोरी डिवाइसों की पहचान करें और उन्हें निकालें</translation> <translation id="4109135793348361820">विंडो को <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />) पर ले जाएं</translation> <translation id="4110895898888439383">उच्च कंट्रास्ट मोड में वेब ब्राउज़ करें</translation> @@ -5335,7 +5332,6 @@ <translation id="9214520840402538427">ओह! इंस्टॉलेशन-समय विशेषताएं आरंभ करने की समय सीमा समाप्त हो गई है. कृपया अपने सहायता प्रतिनिधि से संपर्क करें.</translation> <translation id="9214695392875603905">कपकेक</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" जोड़ा गया</translation> -<translation id="9215934040295798075">वॉलपेपर सेट करें</translation> <translation id="9218430445555521422">डिफ़ॉल्ट के रूप में सेट करें</translation> <translation id="9219103736887031265">चित्र</translation> <translation id="9220525904950070496">खाता हटाएं</translation>
diff --git a/chrome/app/resources/generated_resources_hr.xtb b/chrome/app/resources/generated_resources_hr.xtb index 4d4aa22..c301ae97 100644 --- a/chrome/app/resources/generated_resources_hr.xtb +++ b/chrome/app/resources/generated_resources_hr.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Prikaži postavke sinkronizacije</translation> <translation id="1124772482545689468">Korisnik</translation> <translation id="1125550662859510761">Izgleda kao <ph name="WIDTH" /> x <ph name="HEIGHT" /> (izvorno)</translation> -<translation id="1127216846847548354">Glasovna aktivacija</translation> <translation id="1128109161498068552">Ne dozvoli nijednoj web-lokaciji upotrebu posebnih sistemskih poruka za pristup MIDI uređajima</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Uređivanje tražilice</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Postavke Google asistenta</translation> <translation id="3496213124478423963">Smanji</translation> <translation id="3505030558724226696">Opoziv pristupa uređaju</translation> -<translation id="3506093155988721483">Upotrebljavajte govor umjesto tipkovnice prilikom pokretanja Asistenta</translation> <translation id="3507421388498836150">Trenutačna dopuštenja za "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Ukloni Linux aplikacije za Chromebook</translation> <translation id="3507888235492474624">Ponovo skenirajte Bluetooth uređaje</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Količina prostora na uređaju kritično je mala</translation> <translation id="4103091233824664032">Unesite zaporku da biste konfigurirali zaključavanje zaslona i prijavljivanje</translation> <translation id="4104163789986725820">I&zvoz...</translation> -<translation id="4105563239298244027">Dobijte 1 TB besplatne pohrane na Google disku</translation> <translation id="4107048419833779140">Prepoznaj i izbaci uređaje za pohranu</translation> <translation id="4109135793348361820">Premjesti prozor korisniku <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Pregledavajte web u načinu rada s visokim kontrastom</translation> @@ -5337,7 +5334,6 @@ <translation id="9214520840402538427">Ups! Inicijalizacija atributa vremena instalacije istekla je. Obratite se predstavniku podrške.</translation> <translation id="9214695392875603905">Kolač</translation> <translation id="9215293857209265904">Dodano je proširenje "<ph name="EXTENSION_NAME" />"</translation> -<translation id="9215934040295798075">Postavi pozadinu</translation> <translation id="9218430445555521422">Postavi kao zadano</translation> <translation id="9219103736887031265">Slike</translation> <translation id="9220525904950070496">Uklanjanje računa</translation>
diff --git a/chrome/app/resources/generated_resources_hu.xtb b/chrome/app/resources/generated_resources_hu.xtb index f7cd082..99eac13d 100644 --- a/chrome/app/resources/generated_resources_hu.xtb +++ b/chrome/app/resources/generated_resources_hu.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Szinkronizálási beállítások megjelenítése</translation> <translation id="1124772482545689468">Felhasználó</translation> <translation id="1125550662859510761">Megjelenés: <ph name="WIDTH" /> × <ph name="HEIGHT" /> (natív)</translation> -<translation id="1127216846847548354">Hangalapú hozzáférés aktiválása</translation> <translation id="1128109161498068552">Ne engedélyezze a webhelyeknek, hogy exkluzív rendszerüzenetekkel elérhessék a MIDI-eszközöket</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Keresőmotor beállítása</translation> @@ -1644,7 +1643,6 @@ <translation id="3495660573538963482">Google Segéd-beállítások</translation> <translation id="3496213124478423963">Kicsinyítés</translation> <translation id="3505030558724226696">Eszközhozzáférés visszavonása</translation> -<translation id="3506093155988721483">Beszéd használata billentyűzet helyett a Segéd indításakor</translation> <translation id="3507421388498836150">Aktuális engedélyek a következőhöz: „<ph name="EXTENSION_NAME" />”</translation> <translation id="3507547268929739059">A Chromebookra telepített linuxos alkalmazások eltávolítása</translation> <translation id="3507888235492474624">Bluetooth-eszközök újrakeresése</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Az eszköz nagyon kevés szabad tárhellyel rendelkezik</translation> <translation id="4103091233824664032">Adja meg jelszavát a képernyőzár és bejelentkezés beállításához</translation> <translation id="4104163789986725820">E&xportálás...</translation> -<translation id="4105563239298244027">1 TB ingyenes tárhelyet kaphat a Google Drive-val</translation> <translation id="4107048419833779140">Tárolóeszközök azonosítása és kiadása</translation> <translation id="4109135793348361820">Az ablak áthelyezése <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />) asztalára</translation> <translation id="4110895898888439383">Böngészhet az interneten kontrasztos megjelenítési módban</translation> @@ -5338,7 +5335,6 @@ <translation id="9214520840402538427">Hoppá! A telepítés alatti attribútumok inicializálásakor időtúllépés történt. Kérjük, lépjen kapcsolatba az ügyfélszolgálattal.</translation> <translation id="9214695392875603905">Muffin</translation> <translation id="9215293857209265904">„<ph name="EXTENSION_NAME" />” hozzáadva</translation> -<translation id="9215934040295798075">Háttérkép beállítása</translation> <translation id="9218430445555521422">Beállítás alapértelmezettként</translation> <translation id="9219103736887031265">Képek</translation> <translation id="9220525904950070496">Fiók eltávolítása</translation>
diff --git a/chrome/app/resources/generated_resources_id.xtb b/chrome/app/resources/generated_resources_id.xtb index bcadb50..0cd1bc2 100644 --- a/chrome/app/resources/generated_resources_id.xtb +++ b/chrome/app/resources/generated_resources_id.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Tampilkan setelan sinkronisasi</translation> <translation id="1124772482545689468">Pengguna</translation> <translation id="1125550662859510761">Sepertinya <ph name="WIDTH" /> x <ph name="HEIGHT" /> (Asli)</translation> -<translation id="1127216846847548354">Aktivasi suara</translation> <translation id="1128109161498068552">Jangan izinkan situs apa pun untuk menggunakan pesan eksklusif sistem untuk mengakses perangkat MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Edit mesin telusur</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Setelan Asisten Google</translation> <translation id="3496213124478423963">Perkecil</translation> <translation id="3505030558724226696">Mencabut akses perangkat</translation> -<translation id="3506093155988721483">Gunakan ucapan, bukan keyboard, untuk memulai Asisten</translation> <translation id="3507421388498836150">Izin Saat Ini untuk "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Hapus Aplikasi Linux untuk Chromebook</translation> <translation id="3507888235492474624">Memindai ulang perangkat Bluetooth</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Ruang perangkat hampir habis</translation> <translation id="4103091233824664032">Masukkan sandi Anda untuk mengonfigurasi kunci layar dan login</translation> <translation id="4104163789986725820">E&kspor...</translation> -<translation id="4105563239298244027">Dapatkan gratis 1 TB dengan Google Drive</translation> <translation id="4107048419833779140">Identifikasi dan keluarkan perangkat penyimpanan</translation> <translation id="4109135793348361820">Pindahkan jendela ke <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Akses web dalam mode kontras tinggi</translation> @@ -5336,7 +5333,6 @@ <translation id="9214520840402538427">Uups! Waktu pemulaian atribut waktu pemasangan telah habis. Hubungi perwakilan dukungan Anda.</translation> <translation id="9214695392875603905">Kue mangkok</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" ditambahkan</translation> -<translation id="9215934040295798075">Setel wallpaper</translation> <translation id="9218430445555521422">Setel sebagai default</translation> <translation id="9219103736887031265">Gambar</translation> <translation id="9220525904950070496">Hapus akun</translation>
diff --git a/chrome/app/resources/generated_resources_it.xtb b/chrome/app/resources/generated_resources_it.xtb index 9fe4a8f..83d81bb 100644 --- a/chrome/app/resources/generated_resources_it.xtb +++ b/chrome/app/resources/generated_resources_it.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Mostra impostazioni di sincronizzazione</translation> <translation id="1124772482545689468">Utente</translation> <translation id="1125550662859510761">Risoluzione di <ph name="WIDTH" /> x <ph name="HEIGHT" /> (nativa)</translation> -<translation id="1127216846847548354">Attivazione vocale</translation> <translation id="1128109161498068552">Non consentire ai siti di utilizzare messaggi esclusivi di sistema per accedere a dispositivi MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Modifica motore di ricerca</translation> @@ -1639,7 +1638,6 @@ <translation id="3495660573538963482">Impostazioni dell'Assistente Google</translation> <translation id="3496213124478423963">Riduci</translation> <translation id="3505030558724226696">Revoca accesso ai dispositivi</translation> -<translation id="3506093155988721483">Usa i comandi vocali invece della tastiera per avviare l'assistente</translation> <translation id="3507421388498836150">Autorizzazioni attuali di "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Rimuovi app Linux per Chromebook</translation> <translation id="3507888235492474624">Ripeti la ricerca di dispositivi Bluetooth</translation> @@ -2057,7 +2055,6 @@ <translation id="4100733287846229632">Lo spazio sul dispositivo sta per esaurirsi</translation> <translation id="4103091233824664032">Inserisci la password per configurare il blocco schermo e l'accesso</translation> <translation id="4104163789986725820">E&sporta...</translation> -<translation id="4105563239298244027">Ottieni 1 TB gratis con Google Drive</translation> <translation id="4107048419833779140">Identifica ed espelli i dispositivi di archiviazione</translation> <translation id="4109135793348361820">Sposta finestra su <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Naviga sul Web in modalità Contrasto elevato</translation> @@ -5328,7 +5325,6 @@ <translation id="9214520840402538427">Spiacenti. L'inizializzazione degli attributi installation-time è scaduta. Contatta il tuo rappresentante dell'assistenza.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" aggiunta</translation> -<translation id="9215934040295798075">Imposta sfondo</translation> <translation id="9218430445555521422">Imposta come predefinito</translation> <translation id="9219103736887031265">Immagini</translation> <translation id="9220525904950070496">Rimuovi account</translation>
diff --git a/chrome/app/resources/generated_resources_iw.xtb b/chrome/app/resources/generated_resources_iw.xtb index a3f2380..55e90ab 100644 --- a/chrome/app/resources/generated_resources_iw.xtb +++ b/chrome/app/resources/generated_resources_iw.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">הצגת הגדרות סינכרון</translation> <translation id="1124772482545689468">משתמש</translation> <translation id="1125550662859510761">נראה כמו <ph name="WIDTH" /> x <ph name="HEIGHT" /> (במקור)</translation> -<translation id="1127216846847548354">הפעלה קולית</translation> <translation id="1128109161498068552">אל תאפשר לאף אתר להשתמש בהודעות בלעדיות של המערכת כדי לגשת למכשירי MIDI.</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">עריכת מנוע חיפוש</translation> @@ -1640,7 +1639,6 @@ <translation id="3495660573538963482">ההגדרות של Google Assistant</translation> <translation id="3496213124478423963">התרחק</translation> <translation id="3505030558724226696">בטל גישה למכשירים</translation> -<translation id="3506093155988721483">שימוש בדיבור במקום במקלדת כשמפעילים את ה-Assistant</translation> <translation id="3507421388498836150">הרשאות נוכחיות של "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">הסרת אפליקציות Linux מה-Chromebook</translation> <translation id="3507888235492474624">סריקה חוזרת לאיתור מכשירי Bluetooth</translation> @@ -2058,7 +2056,6 @@ <translation id="4100733287846229632">שטח האחסון במכשיר כמעט נגמר</translation> <translation id="4103091233824664032">צריך להזין את הסיסמה כדי להגדיר את נעילת המסך ואת הכניסה</translation> <translation id="4104163789986725820">יי&צא...</translation> -<translation id="4105563239298244027">קבל 1TB בחינם עם Google Drive</translation> <translation id="4107048419833779140">לזהות ולהוציא התקני אחסון</translation> <translation id="4109135793348361820">העבר חלון אל <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">גלישה באינטרנט במצב ניגודיות גבוהה</translation> @@ -2286,7 +2283,7 @@ <translation id="4524832533047962394">מצב ההרשמה שסופק לא נתמך על ידי הגרסה הזו של מערכת ההפעלה. כדאי לוודא שמשתמשים בגרסה החדשה ביותר.</translation> <translation id="4525382759303819021">קבלת העדכונים האחרונים והמלצות לגבי אפליקציות מחנות Play</translation> <translation id="4530494379350999373">מקור</translation> -<translation id="4533846798469727141">עכשיו צריך לומר "Hey Google"</translation> +<translation id="4533846798469727141">עכשיו אומרים "Hey Google"</translation> <translation id="4533985347672295764">זמן CPU (יחידת עיבוד מרכזית)</translation> <translation id="4534661889221639075">יש לנסות שוב.</translation> <translation id="4535127706710932914">פרופיל ברירת מחדל</translation> @@ -5331,7 +5328,6 @@ <translation id="9214520840402538427">אופס! תם הזמן הקצוב לאתחול של מאפייני זמן ההתקנה. פנה אל נציג התמיכה שלך.</translation> <translation id="9214695392875603905">קאפקייק</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" נוסף</translation> -<translation id="9215934040295798075">הגדר טפט</translation> <translation id="9218430445555521422">הגדר כברירת מחדל</translation> <translation id="9219103736887031265">תמונות</translation> <translation id="9220525904950070496">הסר חשבון</translation>
diff --git a/chrome/app/resources/generated_resources_ja.xtb b/chrome/app/resources/generated_resources_ja.xtb index fb50b0d..326db05 100644 --- a/chrome/app/resources/generated_resources_ja.xtb +++ b/chrome/app/resources/generated_resources_ja.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">同期設定を表示</translation> <translation id="1124772482545689468">ユーザー</translation> <translation id="1125550662859510761">表示上のサイズ: <ph name="WIDTH" />x<ph name="HEIGHT" />(ネイティブ)</translation> -<translation id="1127216846847548354">音声認識</translation> <translation id="1128109161498068552">システム エクスクルーシブ メッセージを使用して MIDI デバイスにアクセスすることをサイトに許可しない</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">検索エンジンの編集</translation> @@ -775,7 +774,7 @@ <translation id="2144536955299248197">証明書ビューア: <ph name="CERTIFICATE_NAME" /></translation> <translation id="2148219725039824548">共有フォルダのマウントエラー。指定された共有フォルダがネットワークで見つかりませんでした。</translation> <translation id="2148756636027685713">フォーマットが完了しました</translation> -<translation id="2148892889047469596">タブをキャストしています</translation> +<translation id="2148892889047469596">タブをキャスト</translation> <translation id="2149850907588596975">パスワードとフォーム</translation> <translation id="2150139952286079145">送信先の検索</translation> <translation id="2150661552845026580">「<ph name="EXTENSION_NAME" />」を追加しますか?</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Google アシスタントの設定</translation> <translation id="3496213124478423963">縮小</translation> <translation id="3505030558724226696">デバイスのアクセスを取り消す</translation> -<translation id="3506093155988721483">キーボードの代わりに音声入力でアシスタントを起動する</translation> <translation id="3507421388498836150">「<ph name="EXTENSION_NAME" />」の現在の権限</translation> <translation id="3507547268929739059">Chromebook から Linux アプリを削除する</translation> <translation id="3507888235492474624">Bluetooth デバイスを再スキャン</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">端末の空き領域が非常に少なくなっています</translation> <translation id="4103091233824664032">画面ロックとログインを設定するにはパスワードを入力します</translation> <translation id="4104163789986725820">エクスポート(&X)</translation> -<translation id="4105563239298244027">Google ドライブは 1TB まで無料</translation> <translation id="4107048419833779140">ストレージ デバイスの認識と取り外し</translation> <translation id="4109135793348361820"><ph name="USER_NAME" />(<ph name="USER_EMAIL" />)にウィンドウを移動</translation> <translation id="4110895898888439383">ハイ コントラスト モードでウェブをブラウジングする</translation> @@ -3794,7 +3791,7 @@ <translation id="6812841287760418429">変更を保持</translation> <translation id="6817174620439930047">サイトがシステム エクスクルーシブ メッセージを使用して MIDI デバイスにアクセスする際に確認する(推奨)</translation> <translation id="6820687829547641339">gzip で圧縮された tar アーカイブ</translation> -<translation id="682123305478866682">デスクトップをキャストしています</translation> +<translation id="682123305478866682">デスクトップをキャスト</translation> <translation id="6823506025919456619">デバイスを見るには Chrome にログインする必要があります</translation> <translation id="6824564591481349393">メール アドレスをコピー(&E)</translation> <translation id="6825184156888454064">名前順</translation> @@ -5337,7 +5334,6 @@ <translation id="9214520840402538427">installation-time 属性の初期化がタイムアウトしました。サポート担当者にお問い合わせください。</translation> <translation id="9214695392875603905">カップケーキ</translation> <translation id="9215293857209265904">「<ph name="EXTENSION_NAME" />」が追加されました</translation> -<translation id="9215934040295798075">壁紙を設定</translation> <translation id="9218430445555521422">デフォルトとして設定</translation> <translation id="9219103736887031265">画像</translation> <translation id="9220525904950070496">アカウントを削除</translation>
diff --git a/chrome/app/resources/generated_resources_kn.xtb b/chrome/app/resources/generated_resources_kn.xtb index 03eaaf4..8c2c6ae 100644 --- a/chrome/app/resources/generated_resources_kn.xtb +++ b/chrome/app/resources/generated_resources_kn.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">ಸಿಂಕ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೋರಿಸಿ</translation> <translation id="1124772482545689468">ಬಳಕೆದಾರ</translation> <translation id="1125550662859510761"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (ಸ್ಥಳೀಯ) ನಂತೆ ತೋರುತ್ತಿದೆ</translation> -<translation id="1127216846847548354">ಧ್ವನಿ ಸಕ್ರಿಯಗೊಳಿಸುವಿಕೆ</translation> <translation id="1128109161498068552">MIDI ಸಾಧನಗಳನ್ನು ಪ್ರವೇಶಿಸುವುದಕ್ಕೆ ಸಿಸ್ಟಂ ವಿಶೇಷ ಸಂದೇಶಗಳನ್ನು ಬಳಸಲು ಯಾವುದೇ ಸೈಟ್ಗಳಿಗೆ ಅನುಮತಿಸಬೇಡಿ</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">ಹುಡುಕಾಟ ಎಂಜಿನ್ ಅನ್ನು ಎಡಿಟ್ ಮಾಡಿ</translation> @@ -1639,7 +1638,6 @@ <translation id="3495660573538963482">Google ಸಹಾಯಕ ಸೆಟ್ಟಿಂಗ್ಗಳು</translation> <translation id="3496213124478423963">ಝೂಮ್ ಔಟ್</translation> <translation id="3505030558724226696">ಸಾಧನ ಪ್ರವೇಶವನ್ನು ಹಿಂತೆಗೆದುಕೊಳ್ಳಿ</translation> -<translation id="3506093155988721483">ನಿಮ್ಮ ಅಸಿಸ್ಟೆಂಟ್ ಅನ್ನು ನೀವು ಪ್ರಾರಂಭಿಸಿದಾಗ ಕೀಬೋರ್ಡ್ ಬದಲಿಗೆ ಧ್ವನಿಯನ್ನು ಬಳಸಿ</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" ಗೆ ಪ್ರಸ್ತುತ ಅನುಮತಿಗಳು</translation> <translation id="3507547268929739059">Chromebook ನಿಂದ Linux ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ತೆಗೆದುಹಾಕಿ</translation> <translation id="3507888235492474624">ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ಮರು-ಸ್ಕ್ಯಾನ್ ಮಾಡಿ</translation> @@ -2057,7 +2055,6 @@ <translation id="4100733287846229632">ಸಾಧನ ಸ್ಥಳಾವಕಾಶ ತೀರಾ ಕಡಿಮೆ ಇದೆ</translation> <translation id="4103091233824664032">ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಕಾನ್ಫಿಗರ್ ಮಾಡಲು ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ ನಮೂದಿಸಿ ಮತ್ತು ಸೈನ್ ಇನ್ ಮಾಡಿ</translation> <translation id="4104163789986725820">ರ&ಫ್ತು...</translation> -<translation id="4105563239298244027">Google ಡ್ರೈವ್ನೊಂದಿಗೆ 1 TB ಉಚಿತ ಪಡೆಯಿರಿ</translation> <translation id="4107048419833779140">ಸಂಗ್ರಹಣೆ ಸಾಧನಗಳನ್ನು ಗುರುತಿಸಿ ಮತ್ತು ತೆಗೆದುಹಾಕಿ</translation> <translation id="4109135793348361820">ವಿಂಡೋವನ್ನು <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />) ಗೆ ಸರಿಸಿ</translation> <translation id="4110895898888439383">ಅಧಿಕ ಕಾಂಟ್ರಾಸ್ಟ್ ಮೋಡ್ನಲ್ಲಿ ವೆಬ್ ಅನ್ನು ಬ್ರೌಸ್ ಮಾಡಿ</translation> @@ -5329,7 +5326,6 @@ <translation id="9214520840402538427">ಓಹ್! ಸ್ಥಾಪನೆ-ಸಮಯದ ಲಕ್ಷಣಗಳ ಸ್ಥಾಪನೆಯ ಅವಧಿ ಮುಗಿದಿದೆ. ದಯವಿಟ್ಟು ನಿಮ್ಮ ಬೆಂಬಲ ಪ್ರತಿನಿಧಿಯನ್ನು ಸಂಪರ್ಕಿಸಿ.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" ಸೇರಿಸಲಾಗಿದೆ</translation> -<translation id="9215934040295798075">ವಾಲ್ಪೇಪರ್ ಹೊಂದಿಸಿ</translation> <translation id="9218430445555521422">ಡಿಫಾಲ್ಟ್ ಆಗಿ ಹೊಂದಿಸಿ</translation> <translation id="9219103736887031265">ಚಿತ್ರಗಳು</translation> <translation id="9220525904950070496">ಖಾತೆಯನ್ನು ತೆಗೆದುಹಾಕಿ</translation>
diff --git a/chrome/app/resources/generated_resources_ko.xtb b/chrome/app/resources/generated_resources_ko.xtb index c27471b..12af769 100644 --- a/chrome/app/resources/generated_resources_ko.xtb +++ b/chrome/app/resources/generated_resources_ko.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">동기화 설정 표시</translation> <translation id="1124772482545689468">사용자</translation> <translation id="1125550662859510761"><ph name="WIDTH" />x<ph name="HEIGHT" />(기본)처럼 보입니다.</translation> -<translation id="1127216846847548354">음성 활성화</translation> <translation id="1128109161498068552">사이트에서 시스템 전용 메시지를 사용하여 MIDI 기기에 액세스하도록 허용하지 않음</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">검색 엔진 수정</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Google 어시스턴트 설정</translation> <translation id="3496213124478423963">축소</translation> <translation id="3505030558724226696">기기 액세스 취소</translation> -<translation id="3506093155988721483">어시스턴트를 시작할 때 키보드 대신 음성을 사용합니다.</translation> <translation id="3507421388498836150">'<ph name="EXTENSION_NAME" />'의 현재 권한</translation> <translation id="3507547268929739059">Chromebook용 Linux 앱 삭제</translation> <translation id="3507888235492474624">블루투스 기기 다시 검색</translation> @@ -2059,7 +2057,6 @@ <translation id="4100733287846229632">기기 저장 공간 매우 부족</translation> <translation id="4103091233824664032">비밀번호를 입력하여 화면 잠금을 설정하고 로그인하세요.</translation> <translation id="4104163789986725820">내보내기(&X)...</translation> -<translation id="4105563239298244027">Google 드라이브에서 1TB를 무료로 사용하세요.</translation> <translation id="4107048419833779140">외부 저장장치 식별 및 제거</translation> <translation id="4109135793348361820">창을 <ph name="USER_NAME" />(<ph name="USER_EMAIL" />)님에게로 이동</translation> <translation id="4110895898888439383">고대비 모드로 웹 탐색</translation> @@ -5334,7 +5331,6 @@ <translation id="9214520840402538427">설치 시간 속성의 시작 시간이 초과되었습니다. 지원 담당자에게 문의하시기 바랍니다.</translation> <translation id="9214695392875603905">컵케이크</translation> <translation id="9215293857209265904">'<ph name="EXTENSION_NAME" />'이(가) 추가됨</translation> -<translation id="9215934040295798075">배경화면 설정</translation> <translation id="9218430445555521422">기본 브라우저로 설정</translation> <translation id="9219103736887031265">이미지</translation> <translation id="9220525904950070496">계정 삭제</translation>
diff --git a/chrome/app/resources/generated_resources_lt.xtb b/chrome/app/resources/generated_resources_lt.xtb index 71083fe8..63c4c513 100644 --- a/chrome/app/resources/generated_resources_lt.xtb +++ b/chrome/app/resources/generated_resources_lt.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Rodyti sinchronizavimo nustatymus</translation> <translation id="1124772482545689468">Naudotojas</translation> <translation id="1125550662859510761">Atrodo kaip <ph name="WIDTH" /> × <ph name="HEIGHT" /> (savasis)</translation> -<translation id="1127216846847548354">Balso aktyvinimas</translation> <translation id="1128109161498068552">Neleisti jokioms svetainėms naudoti sistemos išskirtinių pranešimų MIDI įrenginiams pasiekti</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Paieškos variklio redagavimas</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">„Google“ padėjėjo nustatymai</translation> <translation id="3496213124478423963">Tolinti</translation> <translation id="3505030558724226696">Panaikinti įrenginio prieigą</translation> -<translation id="3506093155988721483">Paleidus Padėjėją vietoje klaviatūros naudoti kalbą</translation> <translation id="3507421388498836150">Dabartiniai „<ph name="EXTENSION_NAME" />“ leidimai</translation> <translation id="3507547268929739059">Pašalinti „Linux“ programas iš „Chromebook“</translation> <translation id="3507888235492474624">Pakartotinai nuskaityti ieškant „Bluetooth“ įrenginių</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Labai mažai vietos įrenginyje</translation> <translation id="4103091233824664032">Įveskite slaptažodį ir konfigūruokite ekrano užraktą bei prisijungimą</translation> <translation id="4104163789986725820">Eksportuoti...</translation> -<translation id="4105563239298244027">Gaukite 1 TB nemokamai naudodami „Google“ diską</translation> <translation id="4107048419833779140">Identifikuoti ir pašalinti saugyklos įrenginius</translation> <translation id="4109135793348361820">Perkelti langą <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Žiniatinklio naršymas didelio kontrasto režimu</translation> @@ -5337,7 +5334,6 @@ <translation id="9214520840402538427">Oi! Diegimo trukmės atributų iniciacijos laikas baigėsi. Susisiekite su palaikymo komandos atstovu.</translation> <translation id="9214695392875603905">Keksinis pyragaitis</translation> <translation id="9215293857209265904">Pridėtas „<ph name="EXTENSION_NAME" />“</translation> -<translation id="9215934040295798075">Nustatyti ekrano foną</translation> <translation id="9218430445555521422">Nustatyti kaip numatytąją</translation> <translation id="9219103736887031265">Vaizdai</translation> <translation id="9220525904950070496">Pašalinti paskyrą</translation>
diff --git a/chrome/app/resources/generated_resources_lv.xtb b/chrome/app/resources/generated_resources_lv.xtb index b208c9f..30dbd017 100644 --- a/chrome/app/resources/generated_resources_lv.xtb +++ b/chrome/app/resources/generated_resources_lv.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Rādīt sinhronizācijas iestatījumus</translation> <translation id="1124772482545689468">Lietotājs</translation> <translation id="1125550662859510761">Noteiktā izšķirtspēja: <ph name="WIDTH" /> x <ph name="HEIGHT" /> (iebūvētā)</translation> -<translation id="1127216846847548354">Aktivizācija ar balsi</translation> <translation id="1128109161498068552">Neļaut nevienai vietnei izmantot ekskluzīvus sistēmas ziņojumus, lai piekļūtu MIDI ierīcēm</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Meklētājprogrammas rediģēšana</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Google asistenta iestatījumi</translation> <translation id="3496213124478423963">Tālināt</translation> <translation id="3505030558724226696">Atsaukt piekļuvi ierīcei</translation> -<translation id="3506093155988721483">Izmantot runu, nevis tastatūru, kad tiek palaists Asistents</translation> <translation id="3507421388498836150">“<ph name="EXTENSION_NAME" />” pašreizējās atļaujas</translation> <translation id="3507547268929739059">Noņemt Linux lietotnes no Chromebook datora</translation> <translation id="3507888235492474624">Atkārtoti meklēt Bluetooth ierīces</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Ierīces diskā gandrīz nav vietas</translation> <translation id="4103091233824664032">Lai konfigurētu ekrāna bloķēšanu un pierakstīšanos, ievadiet savu paroli.</translation> <translation id="4104163789986725820">E&ksportēt...</translation> -<translation id="4105563239298244027">Izmantojot pakalpojumu Google disks, iegūsiet 1 TB lielu bezmaksas krātuvi</translation> <translation id="4107048419833779140">Identificēt un atvienot atmiņas ierīces</translation> <translation id="4109135793348361820">Pārvietot logu uz šī lietotāja darbvirsmu: <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Pārlūkojiet tīmekli augsta kontrasta režīmā</translation> @@ -5336,7 +5333,6 @@ <translation id="9214520840402538427">Instalācijas laika atribūtu inicializēšanā diemžēl iestājās noildze. Lūdzu, sazinieties ar savu atbalsta pārstāvi.</translation> <translation id="9214695392875603905">Glazūrkēkss</translation> <translation id="9215293857209265904">Ir pievienots paplašinājums <ph name="EXTENSION_NAME" /></translation> -<translation id="9215934040295798075">Iestatīt fona tapeti</translation> <translation id="9218430445555521422">Iestatīt kā noklusējumu</translation> <translation id="9219103736887031265">Attēli</translation> <translation id="9220525904950070496">Konta noņemšana</translation>
diff --git a/chrome/app/resources/generated_resources_ml.xtb b/chrome/app/resources/generated_resources_ml.xtb index 816de2f..6cf78320 100644 --- a/chrome/app/resources/generated_resources_ml.xtb +++ b/chrome/app/resources/generated_resources_ml.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">സമന്വയ ക്രമീകരണം കാണിക്കുക</translation> <translation id="1124772482545689468">ഉപയോക്താവ്</translation> <translation id="1125550662859510761"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (നേറ്റീവ്) പോലെ തോന്നുന്നു</translation> -<translation id="1127216846847548354">വോയിസ് ആക്റ്റിവേഷൻ</translation> <translation id="1128109161498068552">MIDI ഉപകരണങ്ങൾ ആക്സസ്സുചെയ്യുന്നതിന് സിസ്റ്റം എക്സ്ക്ലൂസീവ് സന്ദേശങ്ങൾ ഉപയോഗിക്കുന്നതിന് ഒരു സൈറ്റിനെയും അനുവദിക്കരുത്.</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">തിരയൽ എഞ്ചിൻ എഡിറ്റ് ചെയ്യുക</translation> @@ -1640,7 +1639,6 @@ <translation id="3495660573538963482">Google അസിസ്റ്റന്റ് ക്രമീകരണം</translation> <translation id="3496213124478423963">സൂം ഔട്ട്</translation> <translation id="3505030558724226696">ഉപകരണ ആക്സസ്സ് റദ്ദാക്കുക</translation> -<translation id="3506093155988721483">അസിസ്റ്റന്റ് ആരംഭിക്കുമ്പോൾ കീബോർഡ് ഉപയോഗിക്കുന്നതിന് പകരം സംസാരിക്കുക</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" എന്നതിനായുള്ള നിലവിലെ അനുമതികൾ</translation> <translation id="3507547268929739059">Chromebook-നായുള്ള Linux ആപ്പുകൾ നീക്കം ചെയ്യുക</translation> <translation id="3507888235492474624">Bluetooth ഉപകരണങ്ങൾ വീണ്ടും സ്കാൻ ചെയ്യുക</translation> @@ -2057,7 +2055,6 @@ <translation id="4100733287846229632">ഉപകരണത്തിൽ ഇടം വളരെ കുറവാണ്</translation> <translation id="4103091233824664032">സ്ക്രീൻ ലോക്കും സൈൻ-ഇന്നും കോൺഫിഗർ ചെയ്യാൻ നിങ്ങളുടെ പാസ്വേഡ് നൽകുക</translation> <translation id="4104163789986725820">കയ&റ്റുമതി ചെയ്യുക...</translation> -<translation id="4105563239298244027">Google ഡ്രൈവിൽ 1 TB സൗജന്യമായി നേടുക</translation> <translation id="4107048419833779140">സ്റ്റോറേജ് ഉപകരണം തിരിച്ചറിഞ്ഞ് ഒഴിവാക്കുക</translation> <translation id="4109135793348361820">വിൻഡോ <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />) എന്നതിലേക്ക് നീക്കുക</translation> <translation id="4110895898888439383">ഉയർന്ന ദൃശ്യതീവ്രതാ മോഡിൽ വെബ് ബ്രൗസ് ചെയ്യുക</translation> @@ -5334,7 +5331,6 @@ <translation id="9214520840402538427">ക്ഷമിക്കണം! ഇൻസ്റ്റാളേഷൻ സമയ-ആട്രിബ്യൂട്ടുകളുടെ സമാരംഭിക്കൽ കാലഹരണപ്പെട്ടു. നിങ്ങളുടെ പിന്തുണ പ്രതിനിധിയെ ബന്ധപ്പെടുക.</translation> <translation id="9214695392875603905">കപ്പ്കേക്ക്</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" ചേർത്തു</translation> -<translation id="9215934040295798075">വാൾപേപ്പർ സജ്ജമാക്കുക</translation> <translation id="9218430445555521422">സ്ഥിരസ്ഥിതിയാക്കുക</translation> <translation id="9219103736887031265">ചിത്രങ്ങൾ</translation> <translation id="9220525904950070496">അക്കൗണ്ട് നീക്കംചെയ്യൽ</translation>
diff --git a/chrome/app/resources/generated_resources_mr.xtb b/chrome/app/resources/generated_resources_mr.xtb index 215f157..df17d2f4 100644 --- a/chrome/app/resources/generated_resources_mr.xtb +++ b/chrome/app/resources/generated_resources_mr.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">सिंक सेटिंग्ज दाखवा</translation> <translation id="1124772482545689468">वापरकर्ता</translation> <translation id="1125550662859510761"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (नेटिव्ह) सारखे दिसते</translation> -<translation id="1127216846847548354">व्हॉइस अॅक्टिव्हेशन</translation> <translation id="1128109161498068552">MIDI डिव्हाइसवर प्रवेश करण्यासाठी सिस्टम विशेष संदेश वापरण्याकरिता कोणत्याही साइटला अनुमती देऊ नका</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">शोध इंजिन संपादित करा</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Google साहाय्यक सेटिंग्ज</translation> <translation id="3496213124478423963">झूम कमी करा</translation> <translation id="3505030558724226696">डिव्हाइस प्रवेश रद्द करा</translation> -<translation id="3506093155988721483">तुम्ही तुमचा असिस्टंट सुरू केल्यावर कीबोर्डऐवजी स्पीच वापरा</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" साठी वर्तमान परवानग्या</translation> <translation id="3507547268929739059">Chromebook साठी Linux अॅप्स काढून टाका</translation> <translation id="3507888235492474624">ब्ल्यूटूथ डिव्हाइस पुन्हा स्कॅन करा</translation> @@ -2060,7 +2058,6 @@ <translation id="4100733287846229632">डिव्हाइस वरील स्थान खूप कमी आहे</translation> <translation id="4103091233824664032">स्क्रीन लॉक कॉन्फिगर करण्यासाठी तुमचा पासवर्ड एंटर करा आणि साइन इन करा</translation> <translation id="4104163789986725820">नि&र्यात करा...</translation> -<translation id="4105563239298244027">Google ड्राइव्हसह 1 TB विनामूल्य मिळवा</translation> <translation id="4107048419833779140">स्टोरेज डिव्हाइस ओळखा आणि बाहेर काढा</translation> <translation id="4109135793348361820"><ph name="USER_NAME" /> (<ph name="USER_EMAIL" />) वर विंडो हलवा</translation> <translation id="4110895898888439383">उच्च कॉन्ट्रास्ट मोडमध्ये वेब ब्राउझ करा</translation> @@ -5335,7 +5332,6 @@ <translation id="9214520840402538427">अरेरे! स्थापना-वेळ विशेषतांचा प्रारंभ कालबाह्य झाला. कृपया आपल्या समर्थन प्रतिनिधीशी संपर्क साधा.</translation> <translation id="9214695392875603905">कपकेक</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" जोडले</translation> -<translation id="9215934040295798075">वॉलपेपर सेट करा</translation> <translation id="9218430445555521422">डीफॉल्ट म्हणून सेट करा</translation> <translation id="9219103736887031265">इमेज</translation> <translation id="9220525904950070496">खाते काढून टाका</translation>
diff --git a/chrome/app/resources/generated_resources_ms.xtb b/chrome/app/resources/generated_resources_ms.xtb index b1d416f..c2f3ab9 100644 --- a/chrome/app/resources/generated_resources_ms.xtb +++ b/chrome/app/resources/generated_resources_ms.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Tunjukkan tetapan penyegerakan</translation> <translation id="1124772482545689468">Pengguna</translation> <translation id="1125550662859510761">Kelihatan seperti <ph name="WIDTH" /> x <ph name="HEIGHT" /> (Asal)</translation> -<translation id="1127216846847548354">Pengaktifan suara</translation> <translation id="1128109161498068552">Jangan benarkan mana-mana tapak menggunakan mesej eksklusif sistem untuk mengakses peranti MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Edit enjin carian</translation> @@ -1644,7 +1643,6 @@ <translation id="3495660573538963482">Tetapan Google Assistant</translation> <translation id="3496213124478423963">Zum Keluar</translation> <translation id="3505030558724226696">Batalkan akses peranti</translation> -<translation id="3506093155988721483">Gunakan pertuturan dan bukannya papan kekunci apabila anda memulakan Assistant</translation> <translation id="3507421388498836150">Kebenaran Semasa untuk "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Alih keluar Apl Linux untuk Chromebook</translation> <translation id="3507888235492474624">Imbas semula peranti Bluetooth</translation> @@ -2062,7 +2060,6 @@ <translation id="4100733287846229632">Ruang peranti terlalu rendah</translation> <translation id="4103091233824664032">Masukkan kata laluan anda untuk mengkonfigurasi kunci skrin dan log masuk</translation> <translation id="4104163789986725820">E&ksport...</translation> -<translation id="4105563239298244027">Dapatkan 1 TB percuma dengan Google Drive</translation> <translation id="4107048419833779140">Kenal pasti dan keluarkan peranti storan</translation> <translation id="4109135793348361820">Alihkan tetingkap ke <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Semak imbas web dalam mod kontras tinggi</translation> @@ -5338,7 +5335,6 @@ <translation id="9214520840402538427">Alamak! Pemulaan sifat masa pemasangan telah tamat masa. Sila hubungi wakil sokongan anda.</translation> <translation id="9214695392875603905">Kek cawan</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" ditambah</translation> -<translation id="9215934040295798075">Tetapkan kertas dinding</translation> <translation id="9218430445555521422">Tetapkan sebagai lalai</translation> <translation id="9219103736887031265">Imej</translation> <translation id="9220525904950070496">Alih keluar akaun</translation>
diff --git a/chrome/app/resources/generated_resources_nl.xtb b/chrome/app/resources/generated_resources_nl.xtb index 13c5a1f..144b4ea 100644 --- a/chrome/app/resources/generated_resources_nl.xtb +++ b/chrome/app/resources/generated_resources_nl.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Synchronisatie-instellingen weergeven</translation> <translation id="1124772482545689468">Gebruiker</translation> <translation id="1125550662859510761">Ziet eruit als <ph name="WIDTH" /> x <ph name="HEIGHT" /> (systeemeigen resolutie)</translation> -<translation id="1127216846847548354">Spraakactivering</translation> <translation id="1128109161498068552">Sites niet toestaan berichten exclusief voor het systeem te gebruiken om toegang te krijgen tot MIDI-apparaten</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Zoekmachine bewerken</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Instellingen van de Google Assistent</translation> <translation id="3496213124478423963">Kleiner</translation> <translation id="3505030558724226696">Apparaattoegang intrekken</translation> -<translation id="3506093155988721483">Gebruik spraak in plaats van het toetsenbord wanneer je de Assistent start</translation> <translation id="3507421388498836150">Huidige rechten voor '<ph name="EXTENSION_NAME" />'</translation> <translation id="3507547268929739059">Linux-apps voor Chromebook verwijderen</translation> <translation id="3507888235492474624">Opnieuw scannen naar Bluetooth-apparaten</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Er is zeer weinig ruimte beschikbaar op het apparaat</translation> <translation id="4103091233824664032">Geef je wachtwoord op om de schermvergrendeling in te stellen en in te loggen</translation> <translation id="4104163789986725820">E&xporteren...</translation> -<translation id="4105563239298244027">Ontvang 1 TB gratis met Google Drive</translation> <translation id="4107048419833779140">Opslagapparaten identificeren en verwijderen</translation> <translation id="4109135793348361820">Venster verplaatsen naar <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Surf op internet in de modus voor hoog contrast</translation> @@ -5337,7 +5334,6 @@ <translation id="9214520840402538427">De initialisatie van de kenmerken van de installatietijd is verlopen. Neem contact op met je ondersteuningsmedewerker.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">'<ph name="EXTENSION_NAME" />' toegevoegd</translation> -<translation id="9215934040295798075">Achtergrond instellen</translation> <translation id="9218430445555521422">Instellen als standaard</translation> <translation id="9219103736887031265">Afbeeldingen</translation> <translation id="9220525904950070496">Rekening verwijderen</translation>
diff --git a/chrome/app/resources/generated_resources_no.xtb b/chrome/app/resources/generated_resources_no.xtb index 3396f30..b7a5af7 100644 --- a/chrome/app/resources/generated_resources_no.xtb +++ b/chrome/app/resources/generated_resources_no.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Vis innstillingene for synkronisering</translation> <translation id="1124772482545689468">Bruker</translation> <translation id="1125550662859510761">Ser ut som <ph name="WIDTH" /> x <ph name="HEIGHT" /> (innebygd)</translation> -<translation id="1127216846847548354">Taleaktivering</translation> <translation id="1128109161498068552">Ikke tillat at nettsteder bruker systemeksklusive meldinger for å få tilgang til MIDI-enheter</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Endre i søkemotoren</translation> @@ -1638,7 +1637,6 @@ <translation id="3495660573538963482">Innstillinger for Google-assistenten</translation> <translation id="3496213124478423963">Zoom ut</translation> <translation id="3505030558724226696">Opphev enhetstilgangen</translation> -<translation id="3506093155988721483">Bruk tale i stedet for tastaturet når du starter assistenten</translation> <translation id="3507421388498836150">Nåværende tillatelser for «<ph name="EXTENSION_NAME" />»</translation> <translation id="3507547268929739059">Fjern Linux-apper for Chromebook</translation> <translation id="3507888235492474624">Skann etter Bluetooth-enheter på nytt</translation> @@ -2054,7 +2052,6 @@ <translation id="4100733287846229632">Det er kritisk lite plass på enheten</translation> <translation id="4103091233824664032">Skriv inn passordet ditt for å konfigurere skjermlåsen og påloggingen</translation> <translation id="4104163789986725820">E&ksportér</translation> -<translation id="4105563239298244027">Få 1 TB gratis lagring med Google Disk</translation> <translation id="4107048419833779140">Identifiser og løs ut lagringsenheter</translation> <translation id="4109135793348361820">Flytt vinduet til <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Surf på nettet i høykontrastmodus</translation> @@ -5327,7 +5324,6 @@ <translation id="9214520840402538427">Beklager. Oppstarten av attributtene for installasjonstid er tidsavbrutt. Ta kontakt med brukerstøtterepresentanten din.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">«<ph name="EXTENSION_NAME" />» ble lagt til</translation> -<translation id="9215934040295798075">Velg bakgrunn</translation> <translation id="9218430445555521422">Bruk som standard</translation> <translation id="9219103736887031265">Bilder</translation> <translation id="9220525904950070496">Fjern konto</translation>
diff --git a/chrome/app/resources/generated_resources_pl.xtb b/chrome/app/resources/generated_resources_pl.xtb index 75a32ae..0cea933 100644 --- a/chrome/app/resources/generated_resources_pl.xtb +++ b/chrome/app/resources/generated_resources_pl.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Pokaż ustawienia synchronizacji</translation> <translation id="1124772482545689468">Użytkownik</translation> <translation id="1125550662859510761">Wygląda na <ph name="WIDTH" /> × <ph name="HEIGHT" /> (natywna)</translation> -<translation id="1127216846847548354">Aktywacja głosu</translation> <translation id="1128109161498068552">Nie zezwalaj żadnym witrynom na używanie wiadomości zarezerwowanych dla systemu w celu uzyskania dostępu do urządzeń MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Edytuj wyszukiwarkę</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Ustawienia Asystenta Google</translation> <translation id="3496213124478423963">Pomniejsz</translation> <translation id="3505030558724226696">Anuluj dostęp do urządzeń</translation> -<translation id="3506093155988721483">Używaj mowy zamiast klawiatury po uruchomieniu Asystenta</translation> <translation id="3507421388498836150">Obecne uprawnienia rozszerzenia „<ph name="EXTENSION_NAME" />”</translation> <translation id="3507547268929739059">Usuń aplikacje na Linuksa z Chromebooka</translation> <translation id="3507888235492474624">Skanuj ponownie w poszukiwaniu urządzeń Bluetooth</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Na urządzeniu już prawie nie ma miejsca</translation> <translation id="4103091233824664032">Wpisz hasło, by skonfigurować blokadę ekranu i logowanie</translation> <translation id="4104163789986725820">E&ksportuj</translation> -<translation id="4105563239298244027">Uzyskaj 1 TB miejsca na Dysku Google za darmo</translation> <translation id="4107048419833779140">Rozpoznawanie i wysuwanie urządzeń pamięci</translation> <translation id="4109135793348361820">Przesuń okno do: <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Przeglądaj strony w trybie dużego kontrastu</translation> @@ -5337,7 +5334,6 @@ <translation id="9214520840402538427">Upłynął limit czasu inicjowania atrybutów instalacyjnych. Skontaktuj się z przedstawicielem obsługi klienta.</translation> <translation id="9214695392875603905">Babeczka</translation> <translation id="9215293857209265904">Dodano „<ph name="EXTENSION_NAME" />”</translation> -<translation id="9215934040295798075">Ustaw tapetę</translation> <translation id="9218430445555521422">Ustaw jako domyślną</translation> <translation id="9219103736887031265">Grafika</translation> <translation id="9220525904950070496">Usuń konto</translation>
diff --git a/chrome/app/resources/generated_resources_pt-BR.xtb b/chrome/app/resources/generated_resources_pt-BR.xtb index c8d5588..2a7bffb 100644 --- a/chrome/app/resources/generated_resources_pt-BR.xtb +++ b/chrome/app/resources/generated_resources_pt-BR.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Mostrar configurações de sincronização</translation> <translation id="1124772482545689468">Usuário</translation> <translation id="1125550662859510761">Resolução: <ph name="WIDTH" /> x <ph name="HEIGHT" /> (nativa)</translation> -<translation id="1127216846847548354">Ativação por voz</translation> <translation id="1128109161498068552">Não permitir que nenhum site use mensagens exclusivas do sistema para acessar dispositivos MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Editar mecanismo de pesquisa</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Configurações do Google Assistente</translation> <translation id="3496213124478423963">Afastar</translation> <translation id="3505030558724226696">Revogar acesso ao dispositivo</translation> -<translation id="3506093155988721483">Use a voz em vez do teclado ao iniciar seu Assistente</translation> <translation id="3507421388498836150">Permissões atuais para "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Remover apps do Linux para Chromebook</translation> <translation id="3507888235492474624">Procurar dispositivos Bluetooth novamente</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Espaço em disco do dispositivo criticamente baixo</translation> <translation id="4103091233824664032">Digite sua senha para configurar o bloqueio de tela e o login</translation> <translation id="4104163789986725820">E&xportar...</translation> -<translation id="4105563239298244027">Obtenha 1 TB gratuitos no Google Drive</translation> <translation id="4107048419833779140">Identificar e ejetar dispositivos de armazenamento</translation> <translation id="4109135793348361820">Mover janela para <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Navegue na Web usando o modo de alto contraste</translation> @@ -5339,7 +5336,6 @@ <translation id="9214520840402538427">Ops! A inicialização dos atributos de tempo de instalação ultrapassou o tempo limite. Entre em contato com o representante de suporte.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" adicionada</translation> -<translation id="9215934040295798075">Definir plano de fundo</translation> <translation id="9218430445555521422">Definir como padrão</translation> <translation id="9219103736887031265">Imagens</translation> <translation id="9220525904950070496">Remover conta</translation>
diff --git a/chrome/app/resources/generated_resources_pt-PT.xtb b/chrome/app/resources/generated_resources_pt-PT.xtb index 2885331..d7434d98 100644 --- a/chrome/app/resources/generated_resources_pt-PT.xtb +++ b/chrome/app/resources/generated_resources_pt-PT.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Mostrar definições de sincronização</translation> <translation id="1124772482545689468">Utilizador</translation> <translation id="1125550662859510761">Parece ter <ph name="WIDTH" /> x <ph name="HEIGHT" /> (nativo)</translation> -<translation id="1127216846847548354">Ativação por voz</translation> <translation id="1128109161498068552">Não permitir que os sites utilizem mensagens exclusivas do sistema para aceder a dispositivos MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Editar motor de pesquisa</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Definições do Assistente Google</translation> <translation id="3496213124478423963">Reduzir</translation> <translation id="3505030558724226696">Revogar acesso aos dispositivos</translation> -<translation id="3506093155988721483">Utilize a voz em vez do teclado ao iniciar o Assistente.</translation> <translation id="3507421388498836150">Autorizações atuais para "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Remover aplicações do Linux do Chromebook</translation> <translation id="3507888235492474624">Procurar novamente dispositivos Bluetooth</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Espaço do dispositivo criticamente baixo</translation> <translation id="4103091233824664032">Introduza a palavra-passe para configurar o bloqueio de ecrã e iniciar sessão.</translation> <translation id="4104163789986725820">E&xportar...</translation> -<translation id="4105563239298244027">Obtenha 1 TB grátis com o Google Drive</translation> <translation id="4107048419833779140">Identificar e ejetar dispositivos de armazenamento</translation> <translation id="4109135793348361820">Mover a janela para <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Navegar na Web no Modo de alto contraste</translation> @@ -5336,7 +5333,6 @@ <translation id="9214520840402538427">Ups! A inicialização dos atributos de tempo de instalação expirou. Contacte o seu representante de suporte.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" adicionada</translation> -<translation id="9215934040295798075">Definir imagem de fundo</translation> <translation id="9218430445555521422">Definir como predefinição</translation> <translation id="9219103736887031265">Imagens</translation> <translation id="9220525904950070496">Remover conta</translation>
diff --git a/chrome/app/resources/generated_resources_ro.xtb b/chrome/app/resources/generated_resources_ro.xtb index e8c2247..ab5f056 100644 --- a/chrome/app/resources/generated_resources_ro.xtb +++ b/chrome/app/resources/generated_resources_ro.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Afișează setările de sincronizare</translation> <translation id="1124772482545689468">Utilizator</translation> <translation id="1125550662859510761"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Nativ)</translation> -<translation id="1127216846847548354">Activare vocală</translation> <translation id="1128109161498068552">Nu permiteți niciunui site să utilizeze mesajele rezervate sistemului pentru a accesa dispozitive MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Editează motorul de căutare</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Setări Asistent Google</translation> <translation id="3496213124478423963">Micșorează</translation> <translation id="3505030558724226696">Revocă accesul la dispozitiv</translation> -<translation id="3506093155988721483">Folosește vorbirea în locul tastaturii atunci când pornești Asistentul</translation> <translation id="3507421388498836150">Permisiuni actuale pentru „<ph name="EXTENSION_NAME" />”</translation> <translation id="3507547268929739059">Elimină aplicațiile Linux pentru Chromebook</translation> <translation id="3507888235492474624">Caută din nou dispozitive Bluetooth</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Spațiul de pe dispozitiv este foarte redus</translation> <translation id="4103091233824664032">Introdu parola pentru a configura blocarea ecranului și conectarea</translation> <translation id="4104163789986725820">E&xportă...</translation> -<translation id="4105563239298244027">Primiți 1 TB spațiu de stocare gratuit în Google Drive</translation> <translation id="4107048419833779140">Identifică și elimină dispozitivele de stocare</translation> <translation id="4109135793348361820">Mutați fereastra la <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Navighează pe web în modul Contrast ridicat</translation> @@ -5336,7 +5333,6 @@ <translation id="9214520840402538427">Hopa! Inițializarea atributelor necesare în momentul instalării a expirat. Contactați reprezentantul dvs. de asistență.</translation> <translation id="9214695392875603905">Brioșă</translation> <translation id="9215293857209265904">S-a adăugat „<ph name="EXTENSION_NAME" />”</translation> -<translation id="9215934040295798075">Setează o imagine de fundal</translation> <translation id="9218430445555521422">Setează ca prestabilit</translation> <translation id="9219103736887031265">Imagini</translation> <translation id="9220525904950070496">Eliminați contul</translation>
diff --git a/chrome/app/resources/generated_resources_ru.xtb b/chrome/app/resources/generated_resources_ru.xtb index 776dd3bb..d0e65fc 100644 --- a/chrome/app/resources/generated_resources_ru.xtb +++ b/chrome/app/resources/generated_resources_ru.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Открыть настройки синхронизации</translation> <translation id="1124772482545689468">Пользователь</translation> <translation id="1125550662859510761">Выглядит как <ph name="WIDTH" /> x <ph name="HEIGHT" /> (аппаратное разрешение)</translation> -<translation id="1127216846847548354">Активация голосом</translation> <translation id="1128109161498068552">Запретить сайтам доступ к устройствам MIDI с помощью системных сообщений</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Изменить поисковую систему</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Настройки Google Ассистента</translation> <translation id="3496213124478423963">Уменьшить</translation> <translation id="3505030558724226696">Запретить доступ к устройствам</translation> -<translation id="3506093155988721483">Запускайте Ассистента с помощью голоса вместо клавиатуры</translation> <translation id="3507421388498836150">Текущие разрешения расширения "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Удалить приложения Linux с устройства Chromebook</translation> <translation id="3507888235492474624">Повторите поиск устройств Bluetooth</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">На устройстве почти нет свободного места</translation> <translation id="4103091233824664032">Чтобы настроить блокировку экрана и параметры входа, введите пароль.</translation> <translation id="4104163789986725820">Э&кспорт...</translation> -<translation id="4105563239298244027">1 ТБ пространства в Google Диске бесплатно</translation> <translation id="4107048419833779140">Идентификация и извлечение запоминающих устройств</translation> <translation id="4109135793348361820">Перенести окно на рабочий стол пользователя <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Просматривайте веб-страницы в режиме высокой контрастности.</translation> @@ -5335,7 +5332,6 @@ <translation id="9214520840402538427">К сожалению, срок инициализации для атрибутов времени установки истек. Обратитесь в службу поддержки.</translation> <translation id="9214695392875603905">Кекс</translation> <translation id="9215293857209265904">Добавлено расширение или приложение: <ph name="EXTENSION_NAME" /></translation> -<translation id="9215934040295798075">Выбрать обои</translation> <translation id="9218430445555521422">Сделать браузером по умолчанию</translation> <translation id="9219103736887031265">Картинки</translation> <translation id="9220525904950070496">Удалить аккаунт</translation>
diff --git a/chrome/app/resources/generated_resources_sk.xtb b/chrome/app/resources/generated_resources_sk.xtb index 319f1bd..04698475 100644 --- a/chrome/app/resources/generated_resources_sk.xtb +++ b/chrome/app/resources/generated_resources_sk.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Zobraziť nastavenia synchronizácie</translation> <translation id="1124772482545689468">Používateľ</translation> <translation id="1125550662859510761">Vyzerá ako <ph name="WIDTH" /> x <ph name="HEIGHT" /> (natívne)</translation> -<translation id="1127216846847548354">Aktivácia hlasom</translation> <translation id="1128109161498068552">Žadnym stránkam nepovoliť používanie exkluzívnych správ na prístup k zariadeniam MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Úprava vyhľadávača</translation> @@ -1642,7 +1641,6 @@ <translation id="3495660573538963482">Nastavenia Asistenta Google</translation> <translation id="3496213124478423963">Oddialiť</translation> <translation id="3505030558724226696">Odvolať prístup k zariadeniam</translation> -<translation id="3506093155988721483">Spúšťajte svojho Asistenta hlasom namiesto klávesnice</translation> <translation id="3507421388498836150">Aktuálne povolenia pre rozšírenie <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Odstrániť aplikácie Linux pre Chromebook</translation> <translation id="3507888235492474624">Znova vyhľadať zariadenia Bluetooth</translation> @@ -2060,7 +2058,6 @@ <translation id="4100733287846229632">V zariadení je kriticky málo miesta</translation> <translation id="4103091233824664032">Ak chcete konfigurovať zámku obrazovky a prihlásenie, zadajte heslo</translation> <translation id="4104163789986725820">E&xportovať...</translation> -<translation id="4105563239298244027">Získajte 1 TB zadarmo so službou Disk Google</translation> <translation id="4107048419833779140">Identifikovať a vysunúť zariadenia s úložiskom</translation> <translation id="4109135793348361820">Presunúť okno k používateľovi <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Prehliadajte web v režime vysokého kontrastu</translation> @@ -5334,7 +5331,6 @@ <translation id="9214520840402538427">Ojoj! Časový limit pre inicializáciu atribútov času inštalácie uplynul. Kontaktujte zástupcu podpory.</translation> <translation id="9214695392875603905">Koláčik</translation> <translation id="9215293857209265904">Položka „<ph name="EXTENSION_NAME" />“ bola pridaná</translation> -<translation id="9215934040295798075">Nastaviť tapetu</translation> <translation id="9218430445555521422">Nastaviť ako predvolený</translation> <translation id="9219103736887031265">Obrázky</translation> <translation id="9220525904950070496">Odstrániť účet</translation>
diff --git a/chrome/app/resources/generated_resources_sl.xtb b/chrome/app/resources/generated_resources_sl.xtb index 91d56d2..19f222b 100644 --- a/chrome/app/resources/generated_resources_sl.xtb +++ b/chrome/app/resources/generated_resources_sl.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Prikaži nastavitve sinhronizacije</translation> <translation id="1124772482545689468">Uporabnik</translation> <translation id="1125550662859510761">Videti je <ph name="WIDTH" /> x <ph name="HEIGHT" /> (izvorna)</translation> -<translation id="1127216846847548354">Glasovna aktivacija</translation> <translation id="1128109161498068552">Nobenemu spletnemu mestu ne dovoli uporabe sporočil sysex za dostop do naprav MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Urejanje iskalnika</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Nastavitve Pomočnika Google</translation> <translation id="3496213124478423963">Pomanjšaj</translation> <translation id="3505030558724226696">Umakni dostop do naprav</translation> -<translation id="3506093155988721483">Uporaba govora namesto tipkovnice ob zagonu Pomočnika</translation> <translation id="3507421388498836150">Trenutna dovoljenja za »<ph name="EXTENSION_NAME" />«</translation> <translation id="3507547268929739059">Odstranjevanje aplikacij za Linux za Chromebook</translation> <translation id="3507888235492474624">Vnovično iskanje naprav Bluetooth</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">V napravi kritično primanjkuje prostora</translation> <translation id="4103091233824664032">Vnesite geslo, če želite konfigurirati zaklepanje zaslona in prijavo</translation> <translation id="4104163789986725820">I&zvozi ...</translation> -<translation id="4105563239298244027">Zagotovite si 1 TB brezplačnega prostora za shranjevanje v storitvi Google Drive</translation> <translation id="4107048419833779140">Prepoznavanje in izmet naprav za shranjevanje</translation> <translation id="4109135793348361820">Premakni okno uporabniku <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Brskajte po spletu v visokokontrastnem načinu</translation> @@ -5337,7 +5334,6 @@ <translation id="9214520840402538427">Ojoj! Potekla je časovna omejitev inicializacije atributov časa namestitve. Obrnite se na predstavnika podpore.</translation> <translation id="9214695392875603905">Tortica</translation> <translation id="9215293857209265904">Razširitev »<ph name="EXTENSION_NAME" />« je dodana</translation> -<translation id="9215934040295798075">Nastavi sliko za ozadje</translation> <translation id="9218430445555521422">Nastavi za privzeti brskalnik</translation> <translation id="9219103736887031265">Slike</translation> <translation id="9220525904950070496">Odstranitev računa</translation>
diff --git a/chrome/app/resources/generated_resources_sr.xtb b/chrome/app/resources/generated_resources_sr.xtb index d0b50c4..bb4cded 100644 --- a/chrome/app/resources/generated_resources_sr.xtb +++ b/chrome/app/resources/generated_resources_sr.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Прикажи подешавања синхронизације</translation> <translation id="1124772482545689468">Корисник</translation> <translation id="1125550662859510761">Изгледа да је у питању <ph name="WIDTH" />×<ph name="HEIGHT" /> (основно)</translation> -<translation id="1127216846847548354">Активирање гласовне претраге</translation> <translation id="1128109161498068552">Не дозволи ниједном сајту да користи ексклузивне поруке система да би приступао MIDI уређајима</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Измена претраживача</translation> @@ -1639,7 +1638,6 @@ <translation id="3495660573538963482">Подешавања Google помоћника</translation> <translation id="3496213124478423963">Умањи</translation> <translation id="3505030558724226696">Опозови приступ уређају</translation> -<translation id="3506093155988721483">Користите говор уместо тастатуре када покрећете Помоћник</translation> <translation id="3507421388498836150">Тренутне дозволе за „<ph name="EXTENSION_NAME" />“</translation> <translation id="3507547268929739059">Уклоните Linux апликације за Chromebook</translation> <translation id="3507888235492474624">Поново скенирајте Bluetooth уређаје</translation> @@ -2057,7 +2055,6 @@ <translation id="4100733287846229632">Простор на уређају је изузетно мали</translation> <translation id="4103091233824664032">Унесите лозинку да бисте конфигурисали закључавање екрана и пријављивање</translation> <translation id="4104163789986725820">И&звези...</translation> -<translation id="4105563239298244027">Набавите 1 TB бесплатно на Google диску</translation> <translation id="4107048419833779140">идентификује и избацује меморијске уређаје</translation> <translation id="4109135793348361820">Премести прозор код <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Прегледајте веб у режиму високог контраста</translation> @@ -5334,7 +5331,6 @@ <translation id="9214520840402538427">Упс! Време покретања атрибута за време инсталације је истекло. Контактирајте представника подршке.</translation> <translation id="9214695392875603905">Мафин</translation> <translation id="9215293857209265904">Додат је „<ph name="EXTENSION_NAME" />“</translation> -<translation id="9215934040295798075">Подеси позадину</translation> <translation id="9218430445555521422">Подеси као подразумеван</translation> <translation id="9219103736887031265">Слике</translation> <translation id="9220525904950070496">Уклањање налога</translation>
diff --git a/chrome/app/resources/generated_resources_sv.xtb b/chrome/app/resources/generated_resources_sv.xtb index 1cfa83c..8d43c46f 100644 --- a/chrome/app/resources/generated_resources_sv.xtb +++ b/chrome/app/resources/generated_resources_sv.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Visa synkroniseringsinställningar</translation> <translation id="1124772482545689468">Användare</translation> <translation id="1125550662859510761">Ser ut som <ph name="WIDTH" /> × <ph name="HEIGHT" /> (fast)</translation> -<translation id="1127216846847548354">Röstaktivering</translation> <translation id="1128109161498068552">Tillåt inte att några webbplatser använder systemexklusiva meddelanden för att komma åt MIDI-enheter</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Redigera sökmotor</translation> @@ -1642,7 +1641,6 @@ <translation id="3495660573538963482">Inställningar för Google Assistent</translation> <translation id="3496213124478423963">Zooma ut</translation> <translation id="3505030558724226696">Återkalla enhetsåtkomst</translation> -<translation id="3506093155988721483">Starta assistenten med rösten i stället för tangentbordet.</translation> <translation id="3507421388498836150">Aktuella behörigheter för <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Ta bort Linux-appar för Chromebook</translation> <translation id="3507888235492474624">Sök efter Bluetooth-enheter igen</translation> @@ -2060,7 +2058,6 @@ <translation id="4100733287846229632">Mycket ont om utrymme på enheten</translation> <translation id="4103091233824664032">Ange lösenordet om du vill konfigurera skärmlåset och logga in</translation> <translation id="4104163789986725820">E&xportera...</translation> -<translation id="4105563239298244027">Få 1 TB gratis med Google Drive</translation> <translation id="4107048419833779140">Identifiera och mata ut lagringsenheter</translation> <translation id="4109135793348361820">Flytta fönster till <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Surfa på webben i högkontrastläge</translation> @@ -5335,7 +5332,6 @@ <translation id="9214520840402538427">Hoppsan! Initieringen av attributen för installationstiden har gått ut. Kontakta din representant för kundsupport.</translation> <translation id="9214695392875603905">Muffin</translation> <translation id="9215293857209265904"><ph name="EXTENSION_NAME" /> har lagts till</translation> -<translation id="9215934040295798075">Ange bakgrund</translation> <translation id="9218430445555521422">Använd som standard</translation> <translation id="9219103736887031265">Bilder</translation> <translation id="9220525904950070496">Ta bort konto</translation>
diff --git a/chrome/app/resources/generated_resources_sw.xtb b/chrome/app/resources/generated_resources_sw.xtb index da95a8d..7d413167 100644 --- a/chrome/app/resources/generated_resources_sw.xtb +++ b/chrome/app/resources/generated_resources_sw.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Onyesha mipangilio ya usawazishaji</translation> <translation id="1124772482545689468">Mtumiaji</translation> <translation id="1125550662859510761">Inaonekana kama <ph name="WIDTH" /> x <ph name="HEIGHT" /> (Ya asili)</translation> -<translation id="1127216846847548354">Kuwasha sauti</translation> <translation id="1128109161498068552">Usiruhusu tovuti zozote kutumia ujumbe wa kipekee kufikia vifaa vya MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Badilisha mtambo wa kutafuta</translation> @@ -1636,7 +1635,6 @@ <translation id="3495660573538963482">Mipangilio ya Mratibu wa Google</translation> <translation id="3496213124478423963">Kuza</translation> <translation id="3505030558724226696">Batilisha uwezo wa kufikia kifaa</translation> -<translation id="3506093155988721483">Tumia matamshi badala ya kibodi unapowasha programu ya Mratibu</translation> <translation id="3507421388498836150">Ruhusa za Sasa za "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Ondoa Programu za Linux za Chromebook</translation> <translation id="3507888235492474624">Tafuta tena vifaa vya Bluetooth</translation> @@ -2052,7 +2050,6 @@ <translation id="4100733287846229632">Hifadhi ya kifaa ni ndogo sana</translation> <translation id="4103091233824664032">Andika nenosiri lako ili uweke mipangilio ya kufunga skrini na kuingia katika akaunti</translation> <translation id="4104163789986725820">&Hamisha...</translation> -<translation id="4105563239298244027">Pata TB 1 isiyolipiwa kutoka Hifadhi ya Google</translation> <translation id="4107048419833779140">Tambua na uondoe vifaa vya hifadhi</translation> <translation id="4109135793348361820">Hamisha dirisha hadi kwa <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Vinjari wavuti katika hali ya utofautishaji wa juu</translation> @@ -5330,7 +5327,6 @@ <translation id="9214520840402538427">Lo! Uanzishaji wa muda wa usakinishaji sifa umechina. Tafadhali wasiliana na mwakilishi wako wa kutoa msaada.</translation> <translation id="9214695392875603905">Keki dogo</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" limeongezwa</translation> -<translation id="9215934040295798075">Weka mandhari</translation> <translation id="9218430445555521422">Weka iwe chaguomsingi</translation> <translation id="9219103736887031265">Picha</translation> <translation id="9220525904950070496">Ondoa akaunti</translation>
diff --git a/chrome/app/resources/generated_resources_ta.xtb b/chrome/app/resources/generated_resources_ta.xtb index 5eaec5f..a94967f 100644 --- a/chrome/app/resources/generated_resources_ta.xtb +++ b/chrome/app/resources/generated_resources_ta.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">ஒத்திசைவு அமைப்புகளைக் காட்டு</translation> <translation id="1124772482545689468">பயனர்</translation> <translation id="1125550662859510761"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (இயல்பு) போல் தெரிகிறது</translation> -<translation id="1127216846847548354">குரல் மூலம் இயக்குதல்</translation> <translation id="1128109161498068552">MIDI சாதனங்களை அணுக, அமைப்புக்கேற்ற செய்திகளைப் பயன்படுத்துவதற்கு எந்தத் தளங்களையும் அனுமதிக்க வேண்டாம்</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">தேடல் இன்ஜினை மாற்று</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Google அசிஸ்டண்ட் அமைப்புகள்</translation> <translation id="3496213124478423963">சிறிதாக்கு</translation> <translation id="3505030558724226696">சாதன அணுகலை ரத்துசெய்</translation> -<translation id="3506093155988721483">உங்கள் அசிஸ்டண்ட்டைத் தொடங்கும்போது, கீபோர்டுக்குப் பதிலாகப் பேச்சைப் பயன்படுத்தவும்</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" இன் தற்போதைய அனுமதிகள்</translation> <translation id="3507547268929739059">Chromebook இல் Linux பயன்பாடுகளை அகற்று</translation> <translation id="3507888235492474624">புளூடூத் சாதனங்களை மீண்டும் ஸ்கேன் செய்யும்</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">சாதனத்தில் இடம் மிகவும் குறைவாக உள்ளது</translation> <translation id="4103091233824664032">திரைப் பூட்டை உள்ளமைத்து உள்நுழைய, கடவுச்சொல்லை உள்ளிடவும்</translation> <translation id="4104163789986725820">ஏற்று&மதி...</translation> -<translation id="4105563239298244027">Google இயக்ககம் மூலம் 1 டெ.பை. இலவசமாகப் பெறுக</translation> <translation id="4107048419833779140">சேமிப்பகச் சாதனங்களைக் கண்டறிந்து, வெளியேற்றுதல்</translation> <translation id="4109135793348361820"><ph name="USER_NAME" /> (<ph name="USER_EMAIL" />) க்குச் சாளரத்தை நகர்த்து</translation> <translation id="4110895898888439383">அதிக ஒளி மாறுபாட்டுப் பயன்முறையில் இணையத்தில் உலாவுதல்</translation> @@ -5339,7 +5336,6 @@ <translation id="9214520840402538427">அச்சச்சோ! நிறுவல் நேர பண்புக்கூறுகளின் தொடக்க நேரம் முடிந்தது. உங்கள் ஆதரவு பிரதிநிதியைத் தொடர்புகொள்ளவும்.</translation> <translation id="9214695392875603905">கப்கேக்</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" சேர்க்கப்பட்டது</translation> -<translation id="9215934040295798075">வால்பேப்பரை அமை</translation> <translation id="9218430445555521422">இயல்பாக அமை</translation> <translation id="9219103736887031265">படங்கள்</translation> <translation id="9220525904950070496">கணக்கை அகற்றுக</translation>
diff --git a/chrome/app/resources/generated_resources_te.xtb b/chrome/app/resources/generated_resources_te.xtb index 1a00535..dabbf4a 100644 --- a/chrome/app/resources/generated_resources_te.xtb +++ b/chrome/app/resources/generated_resources_te.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">సమకాలీకరణ సెట్టింగ్లను చూపు</translation> <translation id="1124772482545689468">వినియోగదారు</translation> <translation id="1125550662859510761"><ph name="WIDTH" /> x <ph name="HEIGHT" /> ఉన్నట్టుంది (అసలైనది)</translation> -<translation id="1127216846847548354">వాయిస్ యాక్టివేషన్</translation> <translation id="1128109161498068552">MIDI పరికరాలను ప్రాప్యత చేయడం కోసం సిస్టమ్ విశిష్ట సందేశాలను ఉపయోగించడానికి ఏ సైట్లను అనుమతించవద్దు</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">శోధన ఇంజిన్ని సవరించండి</translation> @@ -357,7 +356,7 @@ <translation id="1510785804673676069">మీరు ప్రాక్సీ సర్వర్ను ఉపయోగిస్తుంటే, ప్రాక్సీ సర్వర్ పని చేస్తోందని తనిఖీ చేయడానికి మీ ప్రాక్సీ సెట్టింగ్లను తనిఖీ చేయండి లేదా మీ నెట్వర్క్ నిర్వాహకుడిని సంప్రదించండి. మీరు ప్రాక్సీ సర్వర్ను ఉపయోగిస్తున్నారని - విశ్వసించకుంటే, మీ <ph name="LINK_START" />ప్రాక్సీ సెట్టింగ్ల<ph name="LINK_END" />ను సర్దుబాటు చేయండి.</translation> + తెలియకుంటే, మీ <ph name="LINK_START" />ప్రాక్సీ సెట్టింగ్ల<ph name="LINK_END" />ను సర్దుబాటు చేయండి.</translation> <translation id="1511388193702657997">మీ వెబ్ పాస్వర్డ్లను సేవ్ చేసే సదుపాయం అందిస్తుంది</translation> <translation id="1512210426710821809">దీనిని చర్యరద్దు చేయడానికి <ph name="IDS_SHORT_PRODUCT_OS_NAME" />ని రీ-ఇన్స్టాల్ చేయడమే ఏకైక మార్గం</translation> <translation id="151501797353681931">Safari నుండి దిగుమతి చేయబడింది</translation> @@ -405,7 +404,7 @@ <ph name="EXTENSION_NAME" /></translation> <translation id="1587275751631642843">&JavaScript కన్సోల్</translation> <translation id="1588438908519853928">సాధారణ</translation> -<translation id="158849752021629804"> హోమ్ నెట్వర్క్ అవసరం</translation> +<translation id="158849752021629804">హోమ్ నెట్వర్క్ అవసరం</translation> <translation id="1588870296199743671">దీనితో లింక్ తెరువు...</translation> <translation id="1589055389569595240">అక్షరక్రమం మరియు వ్యాకరణం చూపించు</translation> <translation id="1593594475886691512">ఆకృతీకరిస్తోంది...</translation> @@ -714,7 +713,7 @@ <translation id="2048653237708779538">చర్య అందుబాటులో లేదు</translation> <translation id="204914487372604757">సత్వరమార్గాన్ని సృష్టించు</translation> <translation id="2050339315714019657">నిలువు</translation> -<translation id="2052369079215022979">మీ సంస్థ ద్వారా నిర్వహించబడుతున్నాయి</translation> +<translation id="2052369079215022979">మీ సంస్థ ద్వారా నిర్వహించబడుతున్నవి</translation> <translation id="2053312383184521053">నిష్క్రియ స్థితి డేటా</translation> <translation id="205560151218727633">Google సహాయకం లోగో</translation> <translation id="2058456167109518507">పరికరం కనుగొనబడింది</translation> @@ -901,7 +900,7 @@ <translation id="2336381494582898602">పవర్వాష్ చేయి</translation> <translation id="2339120501444485379">కొత్త పేరు నమోదు చేయండి</translation> <translation id="2340263603246777781"><ph name="ORIGIN" /> దీనితో జత చేయాలనుకుంటోంది</translation> -<translation id="2342740338116612727">జోడించిన బుక్మార్క్లు</translation> +<translation id="2342740338116612727">బుక్మార్క్లు జోడించబడ్డాయి</translation> <translation id="2344028582131185878">స్వయంచాలక డౌన్లోడ్లు</translation> <translation id="2345723121311404059"><ph name="PRINTER_NAME" />కు 1 పేజీ</translation> <translation id="2347644257713614136">Hangouts మరియు Cast for Educationల వినియోగం Google గోప్యతా విధానానికి అనుగుణంగా ఉంటుంది.</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Google సహాయకం సెట్టింగ్లు</translation> <translation id="3496213124478423963">దూరంగా జూమ్ చేయి</translation> <translation id="3505030558724226696">పరికర ప్రాప్యతను ఉపసంహరించు</translation> -<translation id="3506093155988721483">మీరు మీ అసిస్టెంట్ని ప్రారంభించినప్పుడు మీ కీబోర్డ్కి బదులుగా ప్రసంగాన్ని ఉపయోగించండి</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" ప్రస్తుత అనుమతులు</translation> <translation id="3507547268929739059">Chromebook కోసం Linux యాప్లను తీసివేయండి</translation> <translation id="3507888235492474624">బ్లూటూత్ పరికరాలను మళ్లీ స్కాన్ చేయండి</translation> @@ -1710,7 +1708,7 @@ <translation id="360180734785106144">కొత్త ఫీచర్లు అందుబాటులోకి వస్తే వాటిని అందించడం</translation> <translation id="3602290021589620013">పరిదృశ్యం</translation> <translation id="3603533104205588786">మీరు పేజీని బుక్మార్క్ చేసేందుకు నక్షత్రం గుర్తును క్లిక్ చేయవచ్చు</translation> -<translation id="3603622770190368340">నెట్వర్క్ ప్రమాణపత్రాన్ని పొందండి</translation> +<translation id="3603622770190368340">నెట్వర్క్ సర్టిఫికెట్ను పొందండి</translation> <translation id="3604048165392640554">మొబైల్ కనెక్షన్ ఏదీ కనుగొనబడలేదు. మీ ఇతర పరికరాలలో తక్షణ టెథెరింగ్ను ఆన్ చేసి మళ్లీ ప్రయత్నించండి. <a target="_blank" href="<ph name="URL" />">మరింత తెలుసుకోండి</a></translation> <translation id="3605780360466892872">బటన్డౌన్</translation> <translation id="3608576286259426129">వినియోగదారు చిత్ర పరిదృశ్యం</translation> @@ -2061,11 +2059,10 @@ <translation id="4100733287846229632">పరికరంలో ఖాళీ స్థలం చాలా తక్కువగా ఉంది</translation> <translation id="4103091233824664032">స్క్రీన్ లాక్ మరియు సైన్ ఇన్ని కాన్ఫిగర్ చేయడం కోసం మీ పాస్వర్డ్ని నమోదు చేయండి</translation> <translation id="4104163789986725820">ఎ&గుమతి...</translation> -<translation id="4105563239298244027">Google డిస్క్తో 1 TB నిల్వని ఉచితంగా పొందండి</translation> <translation id="4107048419833779140">నిల్వ డివైజ్లను గుర్తించి, తొలగించండి</translation> <translation id="4109135793348361820">విండోను <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)కి తరలించండి</translation> <translation id="4110895898888439383">అధిక కాంట్రాస్ట్ మోడ్లో వెబ్ని బ్రౌజ్ చేయండి</translation> -<translation id="4115002065223188701">నెట్వర్క్ పరిధిలో లేదు</translation> +<translation id="4115002065223188701">నెట్వర్క్ అందుబాటులో లేదు</translation> <translation id="4115080753528843955">రక్షిత కంటెంట్కు యాక్సెస్ను ప్రామాణీకరించేందుకు కొన్ని కంటెంట్ సేవలు ప్రత్యేక ఐడెంటిఫైయర్లను ఉపయోగిస్తాయి</translation> <translation id="4118579674665737931">దయచేసి పరికరాన్ని రీబూట్ చేసి, మళ్లీ ప్రయత్నించండి.</translation> <translation id="4120817667028078560">పథం చాలా పొడవుగా ఉంది</translation> @@ -3292,7 +3289,7 @@ <translation id="6029587122245504742">అత్యంత నెమ్మది</translation> <translation id="6032912588568283682">ఫైల్ సిస్టమ్</translation> <translation id="6038929619733116134">సైట్ అనుచితమైన లేదా తప్పుదారి పట్టించే ప్రకటనలను చూపినట్లయితే బ్లాక్ చేయండి</translation> -<translation id="6039651071822577588">నెట్వర్క్ లక్షణం నిఘంటువు తప్పుడు ఆకృతి చేయబడింది</translation> +<translation id="6039651071822577588">నెట్వర్క్ ఫీచర్ నిఘంటువు తప్పు ఫార్మాట్లో ఉంది</translation> <translation id="604001903249547235">Cloud బ్యాకప్</translation> <translation id="6040143037577758943">మూసివేయి</translation> <translation id="6040852767465482106">అనామక గుర్తింపు</translation> @@ -3477,7 +3474,7 @@ <translation id="6308937455967653460">లిం&క్ను ఇలా సేవ్ చెయ్యి...</translation> <translation id="6311220991371174222">మీ ప్రొఫైల్ను తెరుస్తున్నప్పుడు ఏదో తప్పు జరిగినందున Chromeని తెరవడం సాధ్యపడదు. Chromeని పునఃప్రారంభించడానికి ప్రయత్నించండి.</translation> <translation id="6312400084708441752">మీ కంప్యూటర్లో ఉన్న హానికరమైన సాఫ్ట్వేర్, సిస్టమ్ సెట్టింగ్లు మరియు ప్రక్రియల గురించిన సమాచారం ఉంటుంది</translation> -<translation id="6312403991423642364">తెలియని నెట్వర్క్ లోపం</translation> +<translation id="6312403991423642364">తెలియని నెట్వర్క్ ఎర్రర్</translation> <translation id="6313320178014547270">మీరు ఈ వెబ్సైట్తో నమోదు కాని కీని ఉపయోగిస్తున్నారు</translation> <translation id="6313641880021325787">VRని నిష్క్రమించు</translation> <translation id="6314819609899340042">మీరు ఈ <ph name="IDS_SHORT_PRODUCT_NAME" /> పరికరంలో డీబగ్గింగ్ లక్షణాలను విజయవంతంగా ప్రారంభించారు.</translation> @@ -4183,7 +4180,7 @@ <translation id="7417705661718309329">Google మ్యాప్</translation> <translation id="741906494724992817">ఈ అనువర్తనానికి ప్రత్యేక అనుమతులు ఏవీ అవసరం లేదు.</translation> <translation id="7419433794191666278">మీ ఫోన్కి మీ Chromebookను కనెక్ట్ చేయండి. <ph name="LINK_BEGIN" />మరింత తెలుసుకోండి.<ph name="LINK_END" /></translation> -<translation id="742130257665691897">తీసివేయబడిన బుక్మార్క్లు</translation> +<translation id="742130257665691897">బుక్మార్క్లు తీసివేయబడ్డాయి</translation> <translation id="7421925624202799674">పేజీ మూలాన్ని &వీక్షించండి</translation> <translation id="7422192691352527311">ప్రాధాన్యతలు...</translation> <translation id="7423098979219808738">ముందుగా అడుగుతుంది</translation> @@ -4578,7 +4575,7 @@ పొడిగింపు: <ph name="EXTENSION_FILE" />కీ ఫైల్: <ph name="KEY_FILE" />మీ కీ ఫైల్ను ఒక సురక్షితమైన స్థలంలో ఉంచండి. మీ పొడిగింపు యొక్క క్రొత్త సంస్కరణను సృష్టించడానికి మీకు ఇది అవసరం అవుతుంది.</translation> <translation id="799923393800005025">వీక్షించవచ్చు</translation> -<translation id="8000066093800657092">ఏ నెట్వర్క్ లేదు</translation> +<translation id="8000066093800657092">నెట్వర్క్ లేదు</translation> <translation id="8004582292198964060">బ్రౌజర్</translation> <translation id="8005600846065423578">క్లిప్బోర్డ్ను చూడటానికి ఎల్లప్పుడూ <ph name="HOST" />ని అనుమతించు</translation> <translation id="8008356846765065031">ఇంటర్నెట్ డిస్కనెక్ట్ చేయబడింది. దయచేసి మీ ఇంటర్నెట్ కనెక్షన్ను తనిఖీ చేయండి.</translation> @@ -5308,7 +5305,7 @@ <translation id="9154418932169119429">ఈ చిత్రం ఆఫ్లైన్లో అందుబాటులో లేదు.</translation> <translation id="91568222606626347">సత్వరమార్గాన్ని సృష్టించు...</translation> <translation id="9157697743260533322">వినియోగదారులందరి కోసం స్వయంచాలక నవీకరణలను సెటప్ చేయడం విఫలమైంది (ప్రీఫ్లయిట్ ప్రారంభ లోపం: <ph name="ERROR_NUMBER" />)</translation> -<translation id="9158715103698450907">అయ్యో! ప్రమాణీకరణ సమయంలో నెట్వర్క్ కమ్యూనికేషన్ సమస్య సంభవించింది. దయచేసి మీ నెట్వర్క్ కనెక్షన్ను తనిఖీ చేసి, మళ్లీ ప్రయత్నించండి.</translation> +<translation id="9158715103698450907">అయ్యో! ప్రామాణీకరణ సమయంలో నెట్వర్క్ కమ్యూనికేషన్ సమస్య ఏర్పడింది. దయచేసి మీ నెట్వర్క్ కనెక్షన్ను తనిఖీ చేసి, మళ్లీ ప్రయత్నించండి.</translation> <translation id="916607977885256133">చిత్రంలో చిత్రం</translation> <translation id="9168436347345867845">దీనిని తర్వాత చేయి</translation> <translation id="9169496697824289689">కీబోర్డ్ సత్వరమార్గాలను వీక్షించండి</translation> @@ -5333,7 +5330,6 @@ <translation id="9214520840402538427">అయ్యో! ఇన్స్టాలేషన్-సమయ లక్షణాల ప్రారంభ సమయం ముగిసింది. దయచేసి మీ మద్దతు ప్రతినిధిని సంప్రదించండి.</translation> <translation id="9214695392875603905">కప్ కేక్</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" జోడించబడింది</translation> -<translation id="9215934040295798075">వాల్పేపర్ను సెట్ చేయండి</translation> <translation id="9218430445555521422">డిఫాల్ట్ లా సెట్ చెయ్యండి</translation> <translation id="9219103736887031265">చిత్రాలు</translation> <translation id="9220525904950070496">ఖాతాను తీసివేయి</translation>
diff --git a/chrome/app/resources/generated_resources_th.xtb b/chrome/app/resources/generated_resources_th.xtb index 48ef4f6..49d5726 100644 --- a/chrome/app/resources/generated_resources_th.xtb +++ b/chrome/app/resources/generated_resources_th.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">แสดงการตั้งค่าการซิงค์</translation> <translation id="1124772482545689468">ผู้ใช้</translation> <translation id="1125550662859510761">ดูเหมือน <ph name="WIDTH" /> x <ph name="HEIGHT" /> (ค่าดั้งเดิม)</translation> -<translation id="1127216846847548354">การเปิดใช้งานด้วยเสียง</translation> <translation id="1128109161498068552">ไม่อนุญาตให้ไซต์ใดๆ ใช้ข้อความเฉพาะของระบบในการเข้าถึงอุปกรณ์ MIDI</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">แก้ไขเครื่องมือค้นหา</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">การตั้งค่า Google Assistant</translation> <translation id="3496213124478423963">ย่อ</translation> <translation id="3505030558724226696">เพิกถอนสิทธิ์การเข้าถึงอุปกรณ์</translation> -<translation id="3506093155988721483">ใช้เสียงแทนแป้นพิมพ์เมื่อเริ่มใช้งาน Assistant</translation> <translation id="3507421388498836150">สิทธิ์ปัจจุบันสำหรับ "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">นำแอป Linux สำหรับ Chromebook ออก</translation> <translation id="3507888235492474624">สแกนหาอุปกรณ์บลูทูธอีกครั้ง</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">พื้นที่ดิสก์เกือบเต็มแล้ว</translation> <translation id="4103091233824664032">ป้อนรหัสผ่านเพื่อกำหนดค่าการล็อกหน้าจอและการลงชื่อเข้าใช้</translation> <translation id="4104163789986725820">ส่ง&ออก</translation> -<translation id="4105563239298244027">รับ 1 TB ฟรีๆ ด้วย Google ไดรฟ์</translation> <translation id="4107048419833779140">ระบุและยกเลิกการต่อเชื่อมอุปกรณ์จัดเก็บข้อมูล</translation> <translation id="4109135793348361820">ย้ายหน้าต่างไปยัง <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">ท่องเว็บในโหมดคอนทราสต์สูง</translation> @@ -5336,7 +5333,6 @@ <translation id="9214520840402538427">อ๊ะ! การเริ่มแอตทริบิวต์เวลาการติดตั้งได้หมดเวลาแล้ว โปรดติดต่อตัวแทนการสนับสนุึนของคุณ</translation> <translation id="9214695392875603905">คัปเค้ก</translation> <translation id="9215293857209265904">เพิ่ม "<ph name="EXTENSION_NAME" />" แล้ว</translation> -<translation id="9215934040295798075">ตั้งค่าวอลเปเปอร์</translation> <translation id="9218430445555521422">ตั้งเป็นค่าเริ่มต้น</translation> <translation id="9219103736887031265">ภาพ</translation> <translation id="9220525904950070496">ลบบัญชี</translation>
diff --git a/chrome/app/resources/generated_resources_tr.xtb b/chrome/app/resources/generated_resources_tr.xtb index fb7a070..334b765 100644 --- a/chrome/app/resources/generated_resources_tr.xtb +++ b/chrome/app/resources/generated_resources_tr.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Senkronizasyon ayarlarını göster</translation> <translation id="1124772482545689468">Kullanıcı</translation> <translation id="1125550662859510761"><ph name="WIDTH" /> x <ph name="HEIGHT" /> şeklinde görünür (Yerel)</translation> -<translation id="1127216846847548354">Ses etkinleştirme</translation> <translation id="1128109161498068552">Hiçbir sitenin MIDI cihazlarına erişmek için sisteme özel mesajları kullanmasına izin verme</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Arama motorunu düzenleyin</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Google Asistan ayarları</translation> <translation id="3496213124478423963">Uzaklaştır</translation> <translation id="3505030558724226696">Cihaz erişimini iptal et</translation> -<translation id="3506093155988721483">Asistanınızı başlattığınızda klavye yerine konuşmayı kullanın</translation> <translation id="3507421388498836150">"<ph name="EXTENSION_NAME" />" için Geçerli İzinler</translation> <translation id="3507547268929739059">Chromebook için Linux Uygulamalarını Kaldırın</translation> <translation id="3507888235492474624">Bluetooth cihazları yeniden tara</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Cihazda kullanılabilir alan kritik düzeyde az</translation> <translation id="4103091233824664032">Ekran kilidini yapılandırmak ve oturum açmak için şifrenizi girin</translation> <translation id="4104163789986725820">&Dışa Aktar...</translation> -<translation id="4105563239298244027">Google Drive ile 1 TB ücretsiz depolama alanı edinin.</translation> <translation id="4107048419833779140">Depolama cihazlarını tanımlama ve çıkarma</translation> <translation id="4109135793348361820">Pencereyi <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />) kullanıcısına taşı</translation> <translation id="4110895898888439383">Web'e yüksek karşıtlık modunda göz atın</translation> @@ -5336,7 +5333,6 @@ <translation id="9214520840402538427">Hata! Yükleme zamanı özniteliklerini başlatma işlemi zaman aşımına uğradı. Lütfen destek temsilcinizle görüşün.</translation> <translation id="9214695392875603905">Küçük kek</translation> <translation id="9215293857209265904">"<ph name="EXTENSION_NAME" />" eklendi</translation> -<translation id="9215934040295798075">Duvar kağıdını ayarla</translation> <translation id="9218430445555521422">Varsayılan olarak ayarla</translation> <translation id="9219103736887031265">Resimler</translation> <translation id="9220525904950070496">Hesabı kaldır</translation>
diff --git a/chrome/app/resources/generated_resources_uk.xtb b/chrome/app/resources/generated_resources_uk.xtb index 2c9b333d..68e0c45 100644 --- a/chrome/app/resources/generated_resources_uk.xtb +++ b/chrome/app/resources/generated_resources_uk.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Показати налаштування синхронізації</translation> <translation id="1124772482545689468">Користувач</translation> <translation id="1125550662859510761"><ph name="WIDTH" />x<ph name="HEIGHT" /> (оригінальна)</translation> -<translation id="1127216846847548354">Активація голосом</translation> <translation id="1128109161498068552">Заборонити всім сайтам використовувати виняткові повідомлення системи, щоб отримувати доступ до пристроїв MIDI</translation> <translation id="1128128132059598906">EAP – TTLS</translation> <translation id="1128591060186966949">Змінити пошукову систему</translation> @@ -1306,7 +1305,7 @@ <translation id="2961090598421146107"><ph name="CERTIFICATE_NAME" /> (розширення встановлено)</translation> <translation id="2961695502793809356">Натисніть, щоб перейти далі; утримуйте, щоб переглянути історію</translation> <translation id="2963151496262057773">Плагін <ph name="PLUGIN_NAME" /> не відповідає. Зупинити?</translation> -<translation id="2966937470348689686">Керуйте налаштуваннями Android</translation> +<translation id="2966937470348689686">Змінити налаштування Android</translation> <translation id="2972557485845626008">Мікропрограма</translation> <translation id="2972581237482394796">&Повторити</translation> <translation id="2972642118232180842">Запускати лише важливий вміст (рекомендовано)</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Налаштування Google Асистента</translation> <translation id="3496213124478423963">Зменшити</translation> <translation id="3505030558724226696">Скасувати доступ до пристрою</translation> -<translation id="3506093155988721483">Запускайте Асистент за допомогою голосу, а не клавіатури</translation> <translation id="3507421388498836150">Поточні дозволи розширення <ph name="EXTENSION_NAME" /></translation> <translation id="3507547268929739059">Видалити додатки Linux для Chromebook</translation> <translation id="3507888235492474624">Шукати пристрої Bluetooth знову</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">На пристрої дуже мало вільного місця</translation> <translation id="4103091233824664032">Введіть пароль, щоб налаштувати блокування екрана та вхід</translation> <translation id="4104163789986725820">Е&кспортувати...</translation> -<translation id="4105563239298244027">Отримайте безкоштовно 1 ТБ на Диску Google</translation> <translation id="4107048419833779140">Виявляти й вилучати пристрої пам’яті</translation> <translation id="4109135793348361820">Перемістити вікно на робочий стіл користувача <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Переглядати сторінки в режимі високого контрасту</translation> @@ -3718,7 +3715,7 @@ <translation id="6686817083349815241">Зберегти пароль</translation> <translation id="6690659332373509948">Неможливо проаналізувати файл: <ph name="FILE_NAME" /></translation> <translation id="6690751852586194791">Виберіть, якого контрольованого користувача додати на цей пристрій.</translation> -<translation id="6691331417640343772">Керувати синхронізованими даними на інформаційній панелі Google</translation> +<translation id="6691331417640343772">Керувати синхронізованими даними в Особистому кабінеті Google</translation> <translation id="6691936601825168937">&Переслати</translation> <translation id="6697492270171225480">Показувати пропозиції схожих сторінок, коли не вдається знайти сторінку</translation> <translation id="6698810901424468597">Читати та змінювати свої дані на веб-сайтах <ph name="WEBSITE_1" /> і <ph name="WEBSITE_2" /></translation> @@ -5336,7 +5333,6 @@ <translation id="9214520840402538427">На жаль, ініціалізація атрибутів часу встановлення минула. Зв’яжіться з представником служби підтримки.</translation> <translation id="9214695392875603905">Кекс</translation> <translation id="9215293857209265904">Додано розширення "<ph name="EXTENSION_NAME" />"</translation> -<translation id="9215934040295798075">Вибрати фоновий малюнок</translation> <translation id="9218430445555521422">Установити за умовчанням</translation> <translation id="9219103736887031265">Зображення</translation> <translation id="9220525904950070496">Видалення облікового запису</translation>
diff --git a/chrome/app/resources/generated_resources_vi.xtb b/chrome/app/resources/generated_resources_vi.xtb index 59399fc..c8774f75 100644 --- a/chrome/app/resources/generated_resources_vi.xtb +++ b/chrome/app/resources/generated_resources_vi.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">Hiển thị mục cài đặt đồng bộ hóa</translation> <translation id="1124772482545689468">Người dùng</translation> <translation id="1125550662859510761">Có vẻ như là <ph name="WIDTH" /> x <ph name="HEIGHT" /> (Gốc)</translation> -<translation id="1127216846847548354">Kích hoạt giọng nói</translation> <translation id="1128109161498068552">Không cho phép bất cứ trang web nào 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="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">Chỉnh sửa công cụ tìm kiếm</translation> @@ -1643,7 +1642,6 @@ <translation id="3495660573538963482">Cài đặt Trợ lý Google</translation> <translation id="3496213124478423963">Thu Nhỏ</translation> <translation id="3505030558724226696">Thu hồi quyền truy cập thiết bị</translation> -<translation id="3506093155988721483">Sử dụng giọng nói thay vì bàn phím khi bạn khởi động Trợ lý</translation> <translation id="3507421388498836150">Quyền hiện tại cho "<ph name="EXTENSION_NAME" />"</translation> <translation id="3507547268929739059">Xóa ứng dụng Linux cho Chromebook</translation> <translation id="3507888235492474624">Quét lại các thiết bị Bluetooth</translation> @@ -2061,7 +2059,6 @@ <translation id="4100733287846229632">Dung lượng của thiết bị quá thấp</translation> <translation id="4103091233824664032">Nhập mật khẩu để định cấu hình khóa màn hình rồi đăng nhập</translation> <translation id="4104163789986725820">X&uất...</translation> -<translation id="4105563239298244027">Nhận 1 TB miễn phí với Google Drive</translation> <translation id="4107048419833779140">Nhận dạng và ngắt kết nối thiết bị lưu trữ</translation> <translation id="4109135793348361820">Di chuyển cửa sổ đến <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">Duyệt web trong chế độ tương phản cao</translation> @@ -5336,7 +5333,6 @@ <translation id="9214520840402538427">Rất tiếc! Việc chạy thuộc tính thời gian cài đặt đã hết thời gian. Vui lòng liên hệ với người đại diện hỗ trợ của bạn.</translation> <translation id="9214695392875603905">Cupcake</translation> <translation id="9215293857209265904">Đã thêm "<ph name="EXTENSION_NAME" />"</translation> -<translation id="9215934040295798075">Đặt hình nền</translation> <translation id="9218430445555521422">Đặt làm mặc định</translation> <translation id="9219103736887031265">Hình ảnh</translation> <translation id="9220525904950070496">Xóa tài khoản</translation>
diff --git a/chrome/app/resources/generated_resources_zh-CN.xtb b/chrome/app/resources/generated_resources_zh-CN.xtb index 29489a1..e36be91f 100644 --- a/chrome/app/resources/generated_resources_zh-CN.xtb +++ b/chrome/app/resources/generated_resources_zh-CN.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">显示同步设置</translation> <translation id="1124772482545689468">用户</translation> <translation id="1125550662859510761">有效分辨率:<ph name="WIDTH" /> x <ph name="HEIGHT" />(原生)</translation> -<translation id="1127216846847548354">启动语音操作</translation> <translation id="1128109161498068552">禁止任何网站使用系统专有消息访问 MIDI 设备</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">修改搜索引擎</translation> @@ -1636,7 +1635,6 @@ <translation id="3495660573538963482">Google 助理设置</translation> <translation id="3496213124478423963">缩小</translation> <translation id="3505030558724226696">撤消对设备的访问权限</translation> -<translation id="3506093155988721483">使用语音(而非键盘)启动 Google 助理</translation> <translation id="3507421388498836150">“<ph name="EXTENSION_NAME" />”目前拥有的权限</translation> <translation id="3507547268929739059">从 Chromebook 中移除 Linux 应用</translation> <translation id="3507888235492474624">重新扫描蓝牙设备</translation> @@ -2053,7 +2051,6 @@ <translation id="4100733287846229632">设备存储空间严重不足</translation> <translation id="4103091233824664032">需输入您的密码,才能配置屏幕锁定和登录</translation> <translation id="4104163789986725820">导出(&X)...</translation> -<translation id="4105563239298244027">获取 1 TB 免费的 Google 云端硬盘存储空间</translation> <translation id="4107048419833779140">识别并弹出存储设备</translation> <translation id="4109135793348361820">将窗口移至<ph name="USER_NAME" />(<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">以高反差模式浏览网页</translation> @@ -5320,7 +5317,6 @@ <translation id="9214520840402538427">糟糕!安装时间属性的初始化已过期,请与您的支持代表联系。</translation> <translation id="9214695392875603905">纸杯蛋糕</translation> <translation id="9215293857209265904">已添加“<ph name="EXTENSION_NAME" />”</translation> -<translation id="9215934040295798075">设置壁纸</translation> <translation id="9218430445555521422">设为默认浏览器</translation> <translation id="9219103736887031265">图片</translation> <translation id="9220525904950070496">移除帐号</translation>
diff --git a/chrome/app/resources/generated_resources_zh-TW.xtb b/chrome/app/resources/generated_resources_zh-TW.xtb index d18bd3d..8fe6c1c9 100644 --- a/chrome/app/resources/generated_resources_zh-TW.xtb +++ b/chrome/app/resources/generated_resources_zh-TW.xtb
@@ -91,7 +91,6 @@ <translation id="1123187597739372905">顯示同步處理設定</translation> <translation id="1124772482545689468">使用者</translation> <translation id="1125550662859510761">螢幕解析度:<ph name="WIDTH" /> x <ph name="HEIGHT" /> (原生)</translation> -<translation id="1127216846847548354">啟動語音操作</translation> <translation id="1128109161498068552">禁止任何網站使用系統專用訊息存取 MIDI 裝置</translation> <translation id="1128128132059598906">EAP-TTLS</translation> <translation id="1128591060186966949">編輯搜尋引擎</translation> @@ -1642,7 +1641,6 @@ <translation id="3495660573538963482">Google 助理設定</translation> <translation id="3496213124478423963">縮小</translation> <translation id="3505030558724226696">撤銷裝置存取權</translation> -<translation id="3506093155988721483">啟動 Google 助理時使用語音操作代替鍵盤操作</translation> <translation id="3507421388498836150">「<ph name="EXTENSION_NAME" />」目前擁有的權限</translation> <translation id="3507547268929739059">移除 Chromebook 的 Linux 應用程式</translation> <translation id="3507888235492474624">重新掃描藍牙裝置</translation> @@ -2059,7 +2057,6 @@ <translation id="4100733287846229632">裝置空間嚴重不足</translation> <translation id="4103091233824664032">如要設定螢幕鎖定和登入,請輸入你的密碼</translation> <translation id="4104163789986725820">匯出(&X)...</translation> -<translation id="4105563239298244027">取得 1 TB 的免費 Google 雲端硬碟空間</translation> <translation id="4107048419833779140">識別並退出儲存裝置</translation> <translation id="4109135793348361820">將視窗傳送給 <ph name="USER_NAME" /> (<ph name="USER_EMAIL" />)</translation> <translation id="4110895898888439383">以高對比模式瀏覽網路</translation> @@ -5332,7 +5329,6 @@ <translation id="9214520840402538427">糟糕!系統嘗試初始設定安裝時間 (installation-time) 屬性,但是動作已逾時。請洽詢你的支援代表。</translation> <translation id="9214695392875603905">杯子蛋糕</translation> <translation id="9215293857209265904">已新增「<ph name="EXTENSION_NAME" />」</translation> -<translation id="9215934040295798075">設定桌布</translation> <translation id="9218430445555521422">設定為預設瀏覽器</translation> <translation id="9219103736887031265">圖片</translation> <translation id="9220525904950070496">移除帳戶</translation>
diff --git a/chrome/app/resources/google_chrome_strings_vi.xtb b/chrome/app/resources/google_chrome_strings_vi.xtb index afde25f..5fbbee71 100644 --- a/chrome/app/resources/google_chrome_strings_vi.xtb +++ b/chrome/app/resources/google_chrome_strings_vi.xtb
@@ -131,7 +131,7 @@ <translation id="4331809312908958774">Chrome OS </translation> <translation id="4343195214584226067"><ph name="EXTENSION_NAME" /> đã được thêm vào Chrome</translation> -<translation id="4407807842708586359">Hệ điều hành Google Chrome</translation> +<translation id="4407807842708586359">Google Chrome OS</translation> <translation id="4458462641685292929">Một hoạt động khác trên Google Chrome đang diễn ra. Vui lòng thử lại sau.</translation> <translation id="4480040274068703980">Chrome OS không thể đồng bộ hóa dữ liệu của bạn do lỗi khi đăng nhập.</translation> <translation id="4561051373932531560">Google Chrome cho phép bạn nhấp vào số điện thoại trên web và gọi tới số đó bằng Skype!</translation>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index fed24db..69bb906 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -1876,6 +1876,9 @@ <message name="IDS_SETTINGS_INTERNET_NETWORK_AUTO_CONNECT" desc="Settings > Internet > Network details: Label for the checkbox determining whether to automatically connect to the network."> Automatically connect to this network </message> + <message name="IDS_SETTINGS_INTERNET_NETWORK_ALWAYS_ON_VPN" desc="Settings > Internet > Network details: Label for the checkbox determining that all internet traffic has to go through this VPN (virtual private network), and all other network connections are blocked."> + Always connect through this VPN + </message> <message name="IDS_SETTINGS_INTERNET_NETWORK_IP_CONFIG_AUTO" desc="Settings > Internet > Network details: Label for the checkbox determining whether to automatically configure the network IP config."> Configure IP address automatically </message> @@ -3326,9 +3329,6 @@ <message name="IDS_SETTINGS_CHANGE_PICTURE_PROFILE_PHOTO" desc="The text on the Google profile photo of the user."> Google Profile photo </message> - <message name="IDS_SETTINGS_PEOPLE_SYNC_UNIFIED_CONSENT_TOGGLE_TITLE" desc="The title of the toggle to opt into unified consent and enable all its services."> - Use sync and all services - </message> <message name="IDS_SETTINGS_PEOPLE_SIGN_OUT" desc="The label of the button that lets user sign-out of Chrome."> Sign out </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 9a3f7bef..098cd3bff 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2300,8 +2300,8 @@ "android/oom_intervention/oom_intervention_tab_helper.h", "android/partner_browser_customizations.cc", "android/partner_browser_customizations.h", - "android/password_manager/password_accessory_view_android.cc", - "android/password_manager/password_accessory_view_android.h", + "android/password_manager/manual_filling_view_android.cc", + "android/password_manager/manual_filling_view_android.h", "android/password_manager/password_generation_dialog_view_android.cc", "android/password_manager/password_generation_dialog_view_android.h", "android/password_ui_view_android.cc", @@ -2419,6 +2419,10 @@ "autofill/android/personal_data_manager_android.cc", "autofill/android/personal_data_manager_android.h", "autofill/android/phone_number_util_android.cc", + "autofill/manual_filling_controller.h", + "autofill/manual_filling_controller_impl.cc", + "autofill/manual_filling_controller_impl.h", + "autofill/manual_filling_view_interface.h", "banners/app_banner_infobar_delegate_android.cc", "banners/app_banner_infobar_delegate_android.h", "banners/app_banner_manager_android.cc", @@ -2484,10 +2488,10 @@ "password_manager/credential_android.h", "password_manager/generated_password_saved_infobar_delegate_android.cc", "password_manager/generated_password_saved_infobar_delegate_android.h", - "password_manager/password_accessory_controller.cc", "password_manager/password_accessory_controller.h", + "password_manager/password_accessory_controller_impl.cc", + "password_manager/password_accessory_controller_impl.h", "password_manager/password_accessory_metrics_util.h", - "password_manager/password_accessory_view_interface.h", "password_manager/password_generation_dialog_view_interface.h", "password_manager/password_manager_infobar_delegate_android.cc", "password_manager/password_manager_infobar_delegate_android.h", @@ -4611,7 +4615,6 @@ "../android/java/src/org/chromium/chrome/browser/DevToolsServer.java", "../android/java/src/org/chromium/chrome/browser/IntentHeadersRecorder.java", "../android/java/src/org/chromium/chrome/browser/IntentHelper.java", - "../android/java/src/org/chromium/chrome/browser/JavascriptAppModalDialog.java", "../android/java/src/org/chromium/chrome/browser/NearOomMonitor.java", "../android/java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java", "../android/java/src/org/chromium/chrome/browser/SearchGeolocationDisclosureTabHelper.java", @@ -4632,7 +4635,7 @@ "../android/java/src/org/chromium/chrome/browser/autofill/PasswordGenerationPopupBridge.java", "../android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java", "../android/java/src/org/chromium/chrome/browser/autofill/PhoneNumberUtil.java", - "../android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/PasswordAccessoryBridge.java", + "../android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/ManualFillingBridge.java", "../android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java", "../android/java/src/org/chromium/chrome/browser/banners/AppBannerManager.java", "../android/java/src/org/chromium/chrome/browser/banners/AppBannerUiDelegateAndroid.java", @@ -4707,7 +4710,6 @@ "../android/java/src/org/chromium/chrome/browser/historyreport/HistoryReportJniBridge.java", "../android/java/src/org/chromium/chrome/browser/infobar/AdsBlockedInfoBar.java", "../android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java", - "../android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java", "../android/java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java", "../android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java", "../android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java", @@ -4736,6 +4738,7 @@ "../android/java/src/org/chromium/chrome/browser/infobar/UpdatePasswordInfoBar.java", "../android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsSettings.java", "../android/java/src/org/chromium/chrome/browser/invalidation/InvalidationServiceFactory.java", + "../android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptAppModalDialog.java", "../android/java/src/org/chromium/chrome/browser/jsdialog/JavascriptTabModalDialog.java", "../android/java/src/org/chromium/chrome/browser/locale/LocaleManager.java", "../android/java/src/org/chromium/chrome/browser/locale/LocaleTemplateUrlLoader.java",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 00af0b78..6ad90bc 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -338,28 +338,6 @@ error_page::switches::kShowSavedCopy, error_page::switches::kDisableShowSavedCopy}}; -const FeatureEntry::Choice kDefaultTileWidthChoices[] = { - {flags_ui::kGenericExperimentChoiceDefault, "", ""}, - {flag_descriptions::kDefaultTileWidthShort, switches::kDefaultTileWidth, - "128"}, - {flag_descriptions::kDefaultTileWidthTall, switches::kDefaultTileWidth, - "256"}, - {flag_descriptions::kDefaultTileWidthGrande, switches::kDefaultTileWidth, - "512"}, - {flag_descriptions::kDefaultTileWidthVenti, switches::kDefaultTileWidth, - "1024"}}; - -const FeatureEntry::Choice kDefaultTileHeightChoices[] = { - {flags_ui::kGenericExperimentChoiceDefault, "", ""}, - {flag_descriptions::kDefaultTileHeightShort, switches::kDefaultTileHeight, - "128"}, - {flag_descriptions::kDefaultTileHeightTall, switches::kDefaultTileHeight, - "256"}, - {flag_descriptions::kDefaultTileHeightGrande, switches::kDefaultTileHeight, - "512"}, - {flag_descriptions::kDefaultTileHeightVenti, switches::kDefaultTileHeight, - "1024"}}; - #if defined(OS_WIN) const FeatureEntry::Choice kUseAngleChoices[] = { {flag_descriptions::kUseAngleDefault, "", ""}, @@ -1873,12 +1851,6 @@ {"show-saved-copy", flag_descriptions::kShowSavedCopyName, flag_descriptions::kShowSavedCopyDescription, kOsAll, MULTI_VALUE_TYPE(kShowSavedCopyChoices)}, - {"default-tile-width", flag_descriptions::kDefaultTileWidthName, - flag_descriptions::kDefaultTileWidthDescription, kOsAll, - MULTI_VALUE_TYPE(kDefaultTileWidthChoices)}, - {"default-tile-height", flag_descriptions::kDefaultTileHeightName, - flag_descriptions::kDefaultTileHeightDescription, kOsAll, - MULTI_VALUE_TYPE(kDefaultTileHeightChoices)}, #if defined(OS_CHROMEOS) {"enable-virtual-keyboard", flag_descriptions::kVirtualKeyboardName, flag_descriptions::kVirtualKeyboardDescription, kOsCrOS, @@ -2057,10 +2029,6 @@ FEATURE_VALUE_TYPE(chrome::android::kHomepageTile)}, #endif // OS_ANDROID #if defined(OS_ANDROID) - {"enable-tab-modal-js-dialog-android", - flag_descriptions::kTabModalJsDialogName, - flag_descriptions::kTabModalJsDialogDescription, kOsAndroid, - FEATURE_VALUE_TYPE(chrome::android::kTabModalJsDialog)}, {"enable-modal-permission-dialog-view", flag_descriptions::kModalPermissionDialogViewName, flag_descriptions::kModalPermissionDialogViewDescription, kOsAndroid, @@ -3308,12 +3276,6 @@ flag_descriptions::kOOPHPStackModeDescription, kOsAll, MULTI_VALUE_TYPE(kOOPHPStackModeChoices)}, - {"omnibox-ui-elide-suggestion-url-after-host", - flag_descriptions::kOmniboxUIElideSuggestionUrlAfterHostName, - flag_descriptions::kOmniboxUIElideSuggestionUrlAfterHostDescription, - kOsAll, - FEATURE_VALUE_TYPE(omnibox::kUIExperimentElideSuggestionUrlAfterHost)}, - {"omnibox-ui-hide-steady-state-url-scheme", flag_descriptions::kOmniboxUIHideSteadyStateUrlSchemeName, flag_descriptions::kOmniboxUIHideSteadyStateUrlSchemeDescription, kOsAll, @@ -3330,11 +3292,6 @@ flag_descriptions::kOmniboxUIHideSteadyStateUrlPathQueryAndRefDescription, kOsAll, FEATURE_VALUE_TYPE(omnibox::kHideSteadyStateUrlPathQueryAndRef)}, - {"omnibox-ui-jog-textfield-on-popup", - flag_descriptions::kOmniboxUIJogTextfieldOnPopupName, - flag_descriptions::kOmniboxUIJogTextfieldOnPopupDescription, kOsDesktop, - FEATURE_VALUE_TYPE(omnibox::kUIExperimentJogTextfieldOnPopup)}, - {"omnibox-ui-one-click-unelide", flag_descriptions::kOmniboxUIOneClickUnelideName, flag_descriptions::kOmniboxUIOneClickUnelideDescription, kOsAll, @@ -3348,11 +3305,6 @@ kOmniboxUIMaxAutocompleteMatchesVariations, "OmniboxUIMaxAutocompleteVariations")}, - {"omnibox-ui-show-suggestion-favicons", - flag_descriptions::kOmniboxUIShowSuggestionFaviconsName, - flag_descriptions::kOmniboxUIShowSuggestionFaviconsDescription, kOsDesktop, - FEATURE_VALUE_TYPE(omnibox::kUIExperimentShowSuggestionFavicons)}, - {"omnibox-ui-swap-title-and-url", flag_descriptions::kOmniboxUISwapTitleAndUrlName, flag_descriptions::kOmniboxUISwapTitleAndUrlDescription, kOsDesktop, @@ -4479,6 +4431,13 @@ kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kAllowRemoteContextForNotifications)}, #endif // defined(OS_ANDROID) + +#if defined(OS_CHROMEOS) + {"ash-enable-pip-rounded-corners", + flag_descriptions::kAshEnablePipRoundedCornersName, + flag_descriptions::kAshEnablePipRoundedCornersDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kPipRoundedCorners)}, +#endif // defined(OS_CHROMEOS) }; class FlagsStateSingleton {
diff --git a/chrome/browser/accessibility/interstitial_accessibility_browsertest.cc b/chrome/browser/accessibility/interstitial_accessibility_browsertest.cc index c8ef662..d49feb6 100644 --- a/chrome/browser/accessibility/interstitial_accessibility_browsertest.cc +++ b/chrome/browser/accessibility/interstitial_accessibility_browsertest.cc
@@ -2,19 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/feature_list.h" #include "chrome/browser/ssl/ssl_blocking_page.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" -#include "components/security_interstitials/content/security_interstitial_tab_helper.h" #include "components/security_interstitials/core/controller_client.h" #include "content/public/browser/interstitial_page.h" #include "content/public/browser/navigation_entry.h" #include "content/public/test/browser_test_utils.h" -#include "content/public/test/test_navigation_observer.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/request_handler_util.h" @@ -40,30 +36,7 @@ protected: net::EmbeddedTestServer https_server_mismatched_; - bool IsShowingInterstitial(content::WebContents* tab) { - if (base::FeatureList::IsEnabled(features::kSSLCommittedInterstitials)) { - security_interstitials::SecurityInterstitialTabHelper* helper = - security_interstitials::SecurityInterstitialTabHelper:: - FromWebContents(tab); - if (!helper) { - return false; - } - return helper - ->GetBlockingPageForCurrentlyCommittedNavigationForTesting() != - nullptr; - } - return tab->ShowingInterstitialPage(); - } - void ProceedThroughInterstitial(content::WebContents* web_contents) { - if (base::FeatureList::IsEnabled(features::kSSLCommittedInterstitials)) { - content::TestNavigationObserver nav_observer(web_contents, 1); - std::string javascript = - "window.certificateErrorPageController.proceed();"; - ASSERT_TRUE(content::ExecuteScript(web_contents, javascript)); - nav_observer.Wait(); - return; - } content::InterstitialPage* interstitial_page = web_contents->GetInterstitialPage(); ASSERT_TRUE(interstitial_page); @@ -92,7 +65,7 @@ // Ensure that we got an interstitial page. ASSERT_FALSE(web_contents->IsCrashed()); - EXPECT_TRUE(IsShowingInterstitial(web_contents)); + EXPECT_TRUE(web_contents->ShowingInterstitialPage()); // Now check from the perspective of accessibility - we should be focused // on a page with title "Privacy error". Keep waiting on accessibility
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index 01e6e4f1..6b4e3bd 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -406,9 +406,6 @@ const base::Feature kSpecialLocaleWrapper{"SpecialLocaleWrapper", base::FEATURE_ENABLED_BY_DEFAULT}; -const base::Feature kTabModalJsDialog{"TabModalJsDialog", - base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kTabReparenting{"TabReparenting", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index e68d570..beee5e1 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -82,7 +82,6 @@ extern const base::Feature kSpannableInlineAutocomplete; extern const base::Feature kSpecialLocaleFeature; extern const base::Feature kSpecialLocaleWrapper; -extern const base::Feature kTabModalJsDialog; extern const base::Feature kTabReparenting; extern const base::Feature kTrustedWebActivity; extern const base::Feature kTrustedWebActivityPostMessage;
diff --git a/chrome/browser/android/customtabs/detached_resource_request_unittest.cc b/chrome/browser/android/customtabs/detached_resource_request_unittest.cc index d2542f7..ead61536 100644 --- a/chrome/browser/android/customtabs/detached_resource_request_unittest.cc +++ b/chrome/browser/android/customtabs/detached_resource_request_unittest.cc
@@ -41,10 +41,12 @@ constexpr const char kCacheable[] = "/cachetime"; constexpr const char kLargeHeadersAndResponseSize[] = "/large-headers-and-response-size"; +constexpr const char kLargeResponseAndCookie[] = "/large-response-and-cookie"; constexpr const char kCookieKey[] = "cookie"; constexpr const char kUrlKey[] = "url"; constexpr const char kCookieFromNoContent[] = "no-content-cookie"; +constexpr const char kCookieFromLargeResponse[] = "large-response-cookie"; constexpr const char kIndexKey[] = "index"; constexpr const char kMaxKey[] = "max"; @@ -149,6 +151,24 @@ return response; } +// /large-response-and-cookie +std::unique_ptr<HttpResponse> LargeResponseAndCookie( + const HttpRequest& request) { + const GURL& url = request.GetURL(); + if (url.path() != kLargeResponseAndCookie) + return nullptr; + + auto response = std::make_unique<net::test_server::BasicHttpResponse>(); + response->AddCustomHeader("Set-Cookie", kCookieFromLargeResponse); + response->AddCustomHeader( + "X-Large-Header", + std::string(DetachedResourceRequest::kMaxResponseSize, 'b')); + response->set_code(net::HTTP_OK); + response->set_content( + std::string(DetachedResourceRequest::kMaxResponseSize + 1, 'a')); + return response; +} + // Waits for |expected_requests| requests to |path|, then reports the headers // in |headers| and calls |closure|. // Output parameters can be nullptr. @@ -185,6 +205,8 @@ base::BindRepeating(&ManyRedirects)); embedded_test_server()->RegisterRequestHandler( base::BindRepeating(&LargeHeadersAndResponseSize)); + embedded_test_server()->RegisterRequestHandler( + base::BindRepeating(&LargeResponseAndCookie)); embedded_test_server()->AddDefaultHandlers( base::FilePath("chrome/test/data")); host_resolver_ = std::make_unique<content::TestHostResolver>(); @@ -377,6 +399,36 @@ } } +TEST_F(DetachedResourceRequestTest, CookieSetWithTruncatedResponse) { + base::HistogramTester histogram_tester; + ASSERT_TRUE(embedded_test_server()->Start()); + GURL site_for_cookies(embedded_test_server()->base_url()); + base::RunLoop request_waiter; + GURL url(embedded_test_server()->GetURL(kLargeResponseAndCookie)); + + std::string cookie = content::GetCookies(browser_context(), url); + ASSERT_EQ("", cookie); + + DetachedResourceRequest::CreateAndStart( + browser_context(), url, site_for_cookies, + content::Referrer::GetDefaultReferrerPolicy(), kMotivation, + base::BindLambdaForTesting([&](int net_error) { + EXPECT_NE(net::OK, net_error); + request_waiter.Quit(); + })); + request_waiter.Run(); + histogram_tester.ExpectUniqueSample( + "CustomTabs.DetachedResourceRequest.RedirectsCount.Failure", 0, 1); + histogram_tester.ExpectTotalCount( + "CustomTabs.DetachedResourceRequest.Duration.Failure", 1); + histogram_tester.ExpectBucketCount( + "CustomTabs.DetachedResourceRequest.FinalStatus", + -net::ERR_INSUFFICIENT_RESOURCES, 1); + + cookie = content::GetCookies(browser_context(), url); + ASSERT_EQ(kCookieFromLargeResponse, cookie); +} + TEST_F(DetachedResourceRequestTest, MultipleRequests) { base::RunLoop request_waiter; int expected_requests = 2;
diff --git a/chrome/browser/android/digital_asset_links/digital_asset_links_handler.cc b/chrome/browser/android/digital_asset_links/digital_asset_links_handler.cc index 4fc527b..d0f07893 100644 --- a/chrome/browser/android/digital_asset_links/digital_asset_links_handler.cc +++ b/chrome/browser/android/digital_asset_links/digital_asset_links_handler.cc
@@ -19,34 +19,81 @@ #include "services/network/public/cpp/resource_response.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/simple_url_loader.h" +#include "url/origin.h" namespace { -const char kDigitalAssetLinksBaseURL[] = - "https://digitalassetlinks.googleapis.com"; -const char kDigitalAssetLinksCheckAPI[] = "/v1/assetlinks:check?"; -const char kTargetOriginParam[] = "source.web.site"; -const char kSourcePackageNameParam[] = "target.androidApp.packageName"; -const char kSourceFingerprintParam[] = - "target.androidApp.certificate.sha256Fingerprint"; -const char kRelationshipParam[] = "relation"; -GURL GetUrlForCheckingRelationship(const std::string& web_domain, - const std::string& package_name, - const std::string& fingerprint, - const std::string& relationship) { - GURL request_url = - GURL(kDigitalAssetLinksBaseURL).Resolve(kDigitalAssetLinksCheckAPI); - request_url = - net::AppendQueryParameter(request_url, kTargetOriginParam, web_domain); - request_url = net::AppendQueryParameter(request_url, kSourcePackageNameParam, - package_name); - request_url = net::AppendQueryParameter(request_url, kSourceFingerprintParam, - fingerprint); - request_url = - net::AppendQueryParameter(request_url, kRelationshipParam, relationship); - DCHECK(request_url.is_valid()); - return request_url; +// Location on a website where the asset links file can be found, see +// https://developers.google.com/digital-asset-links/v1/getting-started. +const char kAssetLinksAbsolutePath[] = ".well-known/assetlinks.json"; + +GURL GetUrlForAssetLinks(const url::Origin& origin) { + return origin.GetURL().Resolve(kAssetLinksAbsolutePath); } + +// An example, well formed asset links file for reference: +// [{ +// "relation": ["delegate_permission/common.handle_all_urls"], +// "target": { +// "namespace": "android_app", +// "package_name": "com.peter.trustedpetersactivity", +// "sha256_cert_fingerprints": [ +// "FA:2A:03: ... :9D" +// ] +// } +// }, { +// "relation": ["delegate_permission/common.handle_all_urls"], +// "target": { +// "namespace": "android_app", +// "package_name": "com.example.firstapp", +// "sha256_cert_fingerprints": [ +// "64:2F:D4: ... :C1" +// ] +// } +// }] + +bool StatementHasMatchingRelationship(const base::Value& statement, + const std::string& target_relation) { + const base::Value* relations = + statement.FindKeyOfType("relation", base::Value::Type::LIST); + + if (!relations) + return false; + + for (const auto& relation : relations->GetList()) { + if (relation.is_string() && relation.GetString() == target_relation) + return true; + } + + return false; +} + +bool StatementHasMatchingPackage(const base::Value& statement, + const std::string& target_package) { + const base::Value* package = statement.FindPathOfType( + {"target", "package_name"}, base::Value::Type::STRING); + + return package && package->GetString() == target_package; +} + +bool StatementHasMatchingFingerprint(const base::Value& statement, + const std::string& target_fingerprint) { + const base::Value* fingerprints = statement.FindPathOfType( + {"target", "sha256_cert_fingerprints"}, base::Value::Type::LIST); + + if (!fingerprints) + return false; + + for (const auto& fingerprint : fingerprints->GetList()) { + if (fingerprint.is_string() && + fingerprint.GetString() == target_fingerprint) { + return true; + } + } + + return false; +} + } // namespace namespace digital_asset_links { @@ -60,6 +107,9 @@ DigitalAssetLinksHandler::~DigitalAssetLinksHandler() = default; void DigitalAssetLinksHandler::OnURLLoadComplete( + const std::string& package, + const std::string& fingerprint, + const std::string& relationship, std::unique_ptr<std::string> response_body) { int response_code = -1; if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers) @@ -84,7 +134,8 @@ /* connector=*/nullptr, // Connector is unused on Android. *response_body, base::Bind(&DigitalAssetLinksHandler::OnJSONParseSucceeded, - weak_ptr_factory_.GetWeakPtr()), + weak_ptr_factory_.GetWeakPtr(), package, fingerprint, + relationship), base::Bind(&DigitalAssetLinksHandler::OnJSONParseFailed, weak_ptr_factory_.GetWeakPtr())); @@ -92,13 +143,26 @@ } void DigitalAssetLinksHandler::OnJSONParseSucceeded( - std::unique_ptr<base::Value> result) { - base::Value* success = result->FindKeyOfType( - kDigitalAssetLinksCheckResponseKeyLinked, base::Value::Type::BOOLEAN); + const std::string& package, + const std::string& fingerprint, + const std::string& relationship, + std::unique_ptr<base::Value> statement_list) { + if (!statement_list->is_list()) { + std::move(callback_).Run(RelationshipCheckResult::FAILURE); + return; + } - std::move(callback_).Run(success && success->GetBool() - ? RelationshipCheckResult::SUCCESS - : RelationshipCheckResult::FAILURE); + for (const auto& statement : statement_list->GetList()) { + if (statement.is_dict() && + StatementHasMatchingRelationship(statement, relationship) && + StatementHasMatchingPackage(statement, package) && + StatementHasMatchingFingerprint(statement, fingerprint)) { + std::move(callback_).Run(RelationshipCheckResult::SUCCESS); + return; + } + } + + std::move(callback_).Run(RelationshipCheckResult::FAILURE); } void DigitalAssetLinksHandler::OnJSONParseFailed( @@ -113,11 +177,11 @@ bool DigitalAssetLinksHandler::CheckDigitalAssetLinkRelationship( RelationshipCheckResultCallback callback, const std::string& web_domain, - const std::string& package_name, + const std::string& package, const std::string& fingerprint, const std::string& relationship) { - GURL request_url = GetUrlForCheckingRelationship(web_domain, package_name, - fingerprint, relationship); + // TODO(peconn): Propegate the use of url::Origin backwards to clients. + GURL request_url = GetUrlForAssetLinks(url::Origin::Create(GURL(web_domain))); if (!request_url.is_valid()) return false; @@ -159,7 +223,8 @@ url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( shared_url_loader_factory_.get(), base::BindOnce(&DigitalAssetLinksHandler::OnURLLoadComplete, - weak_ptr_factory_.GetWeakPtr())); + weak_ptr_factory_.GetWeakPtr(), package, fingerprint, + relationship)); return true; }
diff --git a/chrome/browser/android/digital_asset_links/digital_asset_links_handler.h b/chrome/browser/android/digital_asset_links/digital_asset_links_handler.h index e1f55d56..6b3bb9b 100644 --- a/chrome/browser/android/digital_asset_links/digital_asset_links_handler.h +++ b/chrome/browser/android/digital_asset_links/digital_asset_links_handler.h
@@ -42,9 +42,9 @@ // Checks whether the given "relationship" has been declared by the target // |web_domain| for the source Android app which is uniquely defined by the - // |package_name| and SHA256 |fingerprint| (a string with 32 hexadecimals - // with : in between) given. Any error in the string params - // here will result in a bad request and a nullptr response to the callback. + // |package| and SHA256 |fingerprint| (a string with 32 hexadecimals with : + // between) given. Any error in the string params here will result in a bad + // request and a nullptr response to the callback. // // Calling this multiple times on the same handler will cancel the previous // checks. @@ -54,15 +54,21 @@ bool CheckDigitalAssetLinkRelationship( RelationshipCheckResultCallback callback, const std::string& web_domain, - const std::string& package_name, + const std::string& package, const std::string& fingerprint, const std::string& relationship); private: - void OnURLLoadComplete(std::unique_ptr<std::string> response_body); + void OnURLLoadComplete(const std::string& package, + const std::string& fingerprint, + const std::string& relationship, + std::unique_ptr<std::string> response_body); // Callbacks for the SafeJsonParser. - void OnJSONParseSucceeded(std::unique_ptr<base::Value> result); + void OnJSONParseSucceeded(const std::string& package, + const std::string& fingerprint, + const std::string& relationship, + std::unique_ptr<base::Value> result); void OnJSONParseFailed(const std::string& error_message); scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_;
diff --git a/chrome/browser/android/digital_asset_links/digital_asset_links_handler_unittest.cc b/chrome/browser/android/digital_asset_links/digital_asset_links_handler_unittest.cc index 93f6485..b71f0a0 100644 --- a/chrome/browser/android/digital_asset_links/digital_asset_links_handler_unittest.cc +++ b/chrome/browser/android/digital_asset_links/digital_asset_links_handler_unittest.cc
@@ -21,6 +21,39 @@ #include "services/network/test/test_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" +namespace { + +const char kStatementList[] = R"( +[{ + "relation": ["other_relationship"], + "target": { + "namespace": "android_app", + "package_name": "com.peter.trustedpetersactivity", + "sha256_cert_fingerprints": [ + "FA:2A:03:CB:38:9C:F3:BE:28:E3:CA:7F:DA:2E:FA:4F:4A:96:F3:BC:45:2C:08:A2:16:A1:5D:FD:AB:46:BC:9D" + ] + } +}, { + "relation": ["delegate_permission/common.handle_all_urls"], + "target": { + "namespace": "android_app", + "package_name": "com.example.firstapp", + "sha256_cert_fingerprints": [ + "64:2F:D4:BE:1C:4D:F8:36:2E:D3:50:C4:69:53:96:A1:3D:14:0A:23:AD:2F:BF:EB:6E:C6:E4:64:54:3B:34:C1" + ] + } +}] +)"; + +const char kDomain[] = "https://www.example.com"; +const char kValidPackage[] = "com.example.firstapp"; +const char kValidRelation[] = "delegate_permission/common.handle_all_urls"; +const char kValidFingerprint[] = + "64:2F:D4:BE:1C:4D:F8:36:2E:D3:50:C4:69:53:96:A1:3D:14:0A:23:AD:2F:BF:EB:" + "6E:C6:E4:64:54:3B:34:C1"; + +} // namespace + namespace digital_asset_links { namespace { @@ -45,50 +78,37 @@ &test_url_loader_factory_); } - void AddResponse(net::Error error, int response_code, bool linked) { - std::string response_string; - if (error == net::OK && response_code == net::HTTP_OK && linked) { - response_string = - R"({ - "linked": true , - "maxAge": "40.188652381s" - })"; - } else if (error == net::OK && response_code == net::HTTP_OK) { - response_string = - R"({ - "linked": false , - "maxAge": "40.188652381s" - })"; - } else if (error == net::OK && response_code == net::HTTP_BAD_REQUEST) { - response_string = - R"({ - "code": 400 , - "message": "Invalid statement query received." - "status": "INVALID_ARGUMENT" - })"; - } - auto& url = test_url_loader_factory_.pending_requests()->at(0).request.url; - if (response_string.empty()) { - network::ResourceResponseHead response_head; - std::string status_line = - "HTTP/1.1 " + base::NumberToString(response_code) + " " + - net::GetHttpReasonPhrase( - static_cast<net::HttpStatusCode>(response_code)); - response_head.headers = - base::MakeRefCounted<net::HttpResponseHeaders>(status_line); - test_url_loader_factory_.AddResponse( - url, response_head, response_string, - network::URLLoaderCompletionStatus(error)); - } else { - test_url_loader_factory_.AddResponse( - url.spec(), response_string, - static_cast<net::HttpStatusCode>(response_code)); - } + void AddErrorResponse(net::Error error, int response_code) { + request_url_ = + test_url_loader_factory_.pending_requests()->at(0).request.url; + + network::ResourceResponseHead response_head; + std::string status_line = + "HTTP/1.1 " + base::NumberToString(response_code) + " " + + net::GetHttpReasonPhrase( + static_cast<net::HttpStatusCode>(response_code)); + response_head.headers = + base::MakeRefCounted<net::HttpResponseHeaders>(status_line); + test_url_loader_factory_.AddResponse( + request_url_, response_head, "", + network::URLLoaderCompletionStatus(error)); + + base::RunLoop().RunUntilIdle(); + } + + void AddResponse(const std::string& response) { + request_url_ = + test_url_loader_factory_.pending_requests()->at(0).request.url; + + test_url_loader_factory_.AddResponse(request_url_.spec(), response, + net::HTTP_OK); + base::RunLoop().RunUntilIdle(); } int num_invocations_; RelationshipCheckResult result_; + GURL request_url_; private: base::test::ScopedTaskEnvironment task_environment_; @@ -100,25 +120,122 @@ }; } // namespace +TEST_F(DigitalAssetLinksHandlerTest, CorrectAssetLinksUrl) { + DigitalAssetLinksHandler handler(GetSharedURLLoaderFactory()); + handler.CheckDigitalAssetLinkRelationship( + base::BindOnce(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, + base::Unretained(this)), + kDomain, kValidPackage, kValidFingerprint, kValidRelation); + AddResponse(""); + + EXPECT_EQ(request_url_, + "https://www.example.com/.well-known/assetlinks.json"); +} + TEST_F(DigitalAssetLinksHandlerTest, PositiveResponse) { DigitalAssetLinksHandler handler(GetSharedURLLoaderFactory()); handler.CheckDigitalAssetLinkRelationship( - base::Bind(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, - base::Unretained(this)), - "", "", "", ""); - AddResponse(net::OK, net::HTTP_OK, true); + base::BindOnce(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, + base::Unretained(this)), + kDomain, kValidPackage, kValidFingerprint, kValidRelation); + AddResponse(kStatementList); EXPECT_EQ(1, num_invocations_); EXPECT_EQ(result_, RelationshipCheckResult::SUCCESS); } -TEST_F(DigitalAssetLinksHandlerTest, NegativeResponse) { +TEST_F(DigitalAssetLinksHandlerTest, PackageMismatch) { DigitalAssetLinksHandler handler(GetSharedURLLoaderFactory()); handler.CheckDigitalAssetLinkRelationship( - base::Bind(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, - base::Unretained(this)), - "", "", "", ""); - AddResponse(net::OK, net::HTTP_OK, false); + base::BindOnce(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, + base::Unretained(this)), + kDomain, "evil.package", kValidFingerprint, kValidRelation); + AddResponse(kStatementList); + + EXPECT_EQ(1, num_invocations_); + EXPECT_EQ(result_, RelationshipCheckResult::FAILURE); +} + +TEST_F(DigitalAssetLinksHandlerTest, SignatureMismatch) { + DigitalAssetLinksHandler handler(GetSharedURLLoaderFactory()); + handler.CheckDigitalAssetLinkRelationship( + base::BindOnce(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, + base::Unretained(this)), + kDomain, kValidPackage, "66:66:66:66:66:66", kValidRelation); + AddResponse(kStatementList); + + EXPECT_EQ(1, num_invocations_); + EXPECT_EQ(result_, RelationshipCheckResult::FAILURE); +} + +TEST_F(DigitalAssetLinksHandlerTest, RelationshipMismatch) { + DigitalAssetLinksHandler handler(GetSharedURLLoaderFactory()); + handler.CheckDigitalAssetLinkRelationship( + base::BindOnce(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, + base::Unretained(this)), + kDomain, kValidPackage, kValidFingerprint, "take_firstborn_child"); + AddResponse(kStatementList); + + EXPECT_EQ(1, num_invocations_); + EXPECT_EQ(result_, RelationshipCheckResult::FAILURE); +} + +TEST_F(DigitalAssetLinksHandlerTest, StatementIsolation) { + // Ensure we don't merge separate statements together. + DigitalAssetLinksHandler handler(GetSharedURLLoaderFactory()); + handler.CheckDigitalAssetLinkRelationship( + base::BindOnce(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, + base::Unretained(this)), + kDomain, kValidPackage, kValidFingerprint, "other_relationship"); + AddResponse(kStatementList); + + EXPECT_EQ(1, num_invocations_); + EXPECT_EQ(result_, RelationshipCheckResult::FAILURE); +} + +TEST_F(DigitalAssetLinksHandlerTest, BadAssetLinks_Empty) { + DigitalAssetLinksHandler handler(GetSharedURLLoaderFactory()); + handler.CheckDigitalAssetLinkRelationship( + base::BindOnce(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, + base::Unretained(this)), + kDomain, kValidPackage, kValidFingerprint, kValidRelation); + AddResponse(""); + + EXPECT_EQ(1, num_invocations_); + EXPECT_EQ(result_, RelationshipCheckResult::FAILURE); +} + +TEST_F(DigitalAssetLinksHandlerTest, BadAssetLinks_NotList) { + DigitalAssetLinksHandler handler(GetSharedURLLoaderFactory()); + handler.CheckDigitalAssetLinkRelationship( + base::BindOnce(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, + base::Unretained(this)), + kDomain, kValidPackage, kValidFingerprint, kValidRelation); + AddResponse(R"({ "key": "value"})"); + + EXPECT_EQ(1, num_invocations_); + EXPECT_EQ(result_, RelationshipCheckResult::FAILURE); +} + +TEST_F(DigitalAssetLinksHandlerTest, BadAssetLinks_StatementNotDict) { + DigitalAssetLinksHandler handler(GetSharedURLLoaderFactory()); + handler.CheckDigitalAssetLinkRelationship( + base::BindOnce(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, + base::Unretained(this)), + kDomain, kValidPackage, kValidFingerprint, kValidRelation); + AddResponse(R"([ [], [] ])"); + + EXPECT_EQ(1, num_invocations_); + EXPECT_EQ(result_, RelationshipCheckResult::FAILURE); +} + +TEST_F(DigitalAssetLinksHandlerTest, BadAssetLinks_MissingFields) { + DigitalAssetLinksHandler handler(GetSharedURLLoaderFactory()); + handler.CheckDigitalAssetLinkRelationship( + base::BindOnce(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, + base::Unretained(this)), + kDomain, kValidPackage, kValidFingerprint, kValidRelation); + AddResponse(R"([ { "target" : {} } ])"); EXPECT_EQ(1, num_invocations_); EXPECT_EQ(result_, RelationshipCheckResult::FAILURE); @@ -127,10 +244,10 @@ TEST_F(DigitalAssetLinksHandlerTest, BadRequest) { DigitalAssetLinksHandler handler(GetSharedURLLoaderFactory()); handler.CheckDigitalAssetLinkRelationship( - base::Bind(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, - base::Unretained(this)), - "", "", "", ""); - AddResponse(net::OK, net::HTTP_BAD_REQUEST, true); + base::BindOnce(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, + base::Unretained(this)), + kDomain, kValidPackage, kValidFingerprint, kValidRelation); + AddErrorResponse(net::OK, net::HTTP_BAD_REQUEST); EXPECT_EQ(1, num_invocations_); EXPECT_EQ(result_, RelationshipCheckResult::FAILURE); @@ -139,10 +256,10 @@ TEST_F(DigitalAssetLinksHandlerTest, NetworkError) { DigitalAssetLinksHandler handler(GetSharedURLLoaderFactory()); handler.CheckDigitalAssetLinkRelationship( - base::Bind(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, - base::Unretained(this)), - "", "", "", ""); - AddResponse(net::ERR_ABORTED, net::HTTP_OK, true); + base::BindOnce(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, + base::Unretained(this)), + kDomain, kValidPackage, kValidFingerprint, kValidRelation); + AddErrorResponse(net::ERR_ABORTED, net::HTTP_OK); EXPECT_EQ(1, num_invocations_); EXPECT_EQ(result_, RelationshipCheckResult::FAILURE); @@ -151,10 +268,10 @@ TEST_F(DigitalAssetLinksHandlerTest, NetworkDisconnected) { DigitalAssetLinksHandler handler(GetSharedURLLoaderFactory()); handler.CheckDigitalAssetLinkRelationship( - base::Bind(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, - base::Unretained(this)), - "", "", "", ""); - AddResponse(net::ERR_INTERNET_DISCONNECTED, net::HTTP_OK, true); + base::BindOnce(&DigitalAssetLinksHandlerTest::OnRelationshipCheckComplete, + base::Unretained(this)), + kDomain, kValidPackage, kValidFingerprint, kValidRelation); + AddErrorResponse(net::ERR_INTERNET_DISCONNECTED, net::HTTP_OK); EXPECT_EQ(1, num_invocations_); EXPECT_EQ(result_, RelationshipCheckResult::NO_CONNECTION);
diff --git a/chrome/browser/android/download/available_offline_content_provider.cc b/chrome/browser/android/download/available_offline_content_provider.cc index 632f26c..61701e8 100644 --- a/chrome/browser/android/download/available_offline_content_provider.cc +++ b/chrome/browser/android/download/available_offline_content_provider.cc
@@ -14,10 +14,13 @@ #include "base/time/time.h" #include "chrome/browser/android/download/download_manager_service.h" #include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_features.h" +#include "components/ntp_snippets/pref_names.h" #include "components/offline_items_collection/core/offline_content_aggregator.h" #include "components/offline_items_collection/core/offline_item.h" #include "components/offline_items_collection/core/offline_item_state.h" +#include "components/prefs/pref_service.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "ui/base/l10n/time_format.h" @@ -191,14 +194,14 @@ } // namespace AvailableOfflineContentProvider::AvailableOfflineContentProvider( - content::BrowserContext* browser_context) - : browser_context_(browser_context), weak_ptr_factory_(this) {} + Profile* profile) + : profile_(profile), weak_ptr_factory_(this) {} AvailableOfflineContentProvider::~AvailableOfflineContentProvider() = default; void AvailableOfflineContentProvider::Summarize(SummarizeCallback callback) { offline_items_collection::OfflineContentAggregator* aggregator = - OfflineContentAggregatorFactory::GetForBrowserContext(browser_context_); + OfflineContentAggregatorFactory::GetForBrowserContext(profile_); aggregator->GetAllItems( base::BindOnce(&AvailableOfflineContentProvider::SummarizeFinalize, weak_ptr_factory_.GetWeakPtr(), std::move(callback))); @@ -206,16 +209,16 @@ void AvailableOfflineContentProvider::List(ListCallback callback) { if (!base::FeatureList::IsEnabled(features::kNewNetErrorPageUI)) { - std::move(callback).Run({}); + std::move(callback).Run(true, {}); return; } offline_items_collection::OfflineContentAggregator* aggregator = - OfflineContentAggregatorFactory::GetForBrowserContext(browser_context_); + OfflineContentAggregatorFactory::GetForBrowserContext(profile_); aggregator->GetAllItems( base::BindOnce(&AvailableOfflineContentProvider::ListFinalize, weak_ptr_factory_.GetWeakPtr(), std::move(callback), // aggregator is a keyed service, and is alive as long as - // browser_context_, which outlives this. + // profile_, which outlives this. base::Unretained(aggregator))); } @@ -223,7 +226,7 @@ const std::string& item_id, const std::string& name_space) { offline_items_collection::OfflineContentAggregator* aggregator = - OfflineContentAggregatorFactory::GetForBrowserContext(browser_context_); + OfflineContentAggregatorFactory::GetForBrowserContext(profile_); aggregator->OpenItem( offline_items_collection::LaunchLocation::NET_ERROR_SUGGESTION, offline_items_collection::ContentId(name_space, item_id)); @@ -235,14 +238,20 @@ open_prefetched_articles_tab); } +void AvailableOfflineContentProvider::ListVisibilityChanged(bool is_visible) { + profile_->GetPrefs()->SetBoolean(ntp_snippets::prefs::kArticlesListVisible, + is_visible); +} + +// static void AvailableOfflineContentProvider::Create( - content::BrowserContext* browser_context, + Profile* profile, chrome::mojom::AvailableOfflineContentProviderRequest request) { // Strong bindings remain as long as the pipe is error free. The renderer is - // on the other side of the pipe, and the browser_context outlives the - // RenderProcessHost, so the browser_context will outlive the Mojo pipe. + // on the other side of the pipe, and the profile outlives the + // RenderProcessHost, so the profile will outlive the Mojo pipe. mojo::MakeStrongBinding( - std::make_unique<AvailableOfflineContentProvider>(browser_context), + std::make_unique<AvailableOfflineContentProvider>(profile), std::move(request)); } @@ -304,8 +313,12 @@ for (const OfflineItem& item : selected) selected_ids.push_back(item.id); + bool list_visible_by_prefs = profile_->GetPrefs()->GetBoolean( + ntp_snippets::prefs::kArticlesListVisible); + auto complete = [](AvailableOfflineContentProvider::ListCallback callback, std::vector<OfflineItem> selected, + bool list_visible_by_prefs, std::vector<GURL> thumbnail_data_uris) { // Translate OfflineItem to AvailableOfflineContentPtr. std::vector<chrome::mojom::AvailableOfflineContentPtr> result; @@ -313,12 +326,14 @@ result.push_back( CreateAvailableOfflineContent(selected[i], thumbnail_data_uris[i])); } - std::move(callback).Run(std::move(result)); + + std::move(callback).Run(list_visible_by_prefs, std::move(result)); }; ThumbnailFetch::Start( aggregator, selected_ids, - base::BindOnce(complete, std::move(callback), std::move(selected))); + base::BindOnce(complete, std::move(callback), std::move(selected), + list_visible_by_prefs)); } } // namespace android
diff --git a/chrome/browser/android/download/available_offline_content_provider.h b/chrome/browser/android/download/available_offline_content_provider.h index 5db0b3e..53eb9d1 100644 --- a/chrome/browser/android/download/available_offline_content_provider.h +++ b/chrome/browser/android/download/available_offline_content_provider.h
@@ -12,9 +12,7 @@ #include "base/memory/weak_ptr.h" #include "chrome/common/available_offline_content.mojom.h" -namespace content { -class BrowserContext; -} +class Profile; namespace offline_items_collection { class OfflineContentAggregator; @@ -28,8 +26,7 @@ : public chrome::mojom::AvailableOfflineContentProvider { public: // Public for testing. - explicit AvailableOfflineContentProvider( - content::BrowserContext* browser_context); + explicit AvailableOfflineContentProvider(Profile* profile); ~AvailableOfflineContentProvider() override; // chrome::mojom::AvailableOfflineContentProvider methods. @@ -38,9 +35,10 @@ void LaunchItem(const std::string& item_id, const std::string& name_space) override; void LaunchDownloadsPage(bool open_prefetched_articles_tab) override; + void ListVisibilityChanged(bool is_visible) override; static void Create( - content::BrowserContext* browser_context, + Profile* profile, chrome::mojom::AvailableOfflineContentProviderRequest request); private: @@ -53,7 +51,7 @@ offline_items_collection::OfflineContentAggregator* aggregator, const std::vector<offline_items_collection::OfflineItem>& all_items); - content::BrowserContext* browser_context_; + Profile* profile_; base::WeakPtrFactory<AvailableOfflineContentProvider> weak_ptr_factory_;
diff --git a/chrome/browser/android/download/available_offline_content_provider_unittest.cc b/chrome/browser/android/download/available_offline_content_provider_unittest.cc index 43a7445..88e776df 100644 --- a/chrome/browser/android/download/available_offline_content_provider_unittest.cc +++ b/chrome/browser/android/download/available_offline_content_provider_unittest.cc
@@ -14,10 +14,12 @@ #include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/testing_profile.h" +#include "components/ntp_snippets/pref_names.h" #include "components/offline_items_collection/core/offline_content_aggregator.h" #include "components/offline_items_collection/core/offline_item.h" #include "components/offline_items_collection/core/offline_item_state.h" #include "components/offline_items_collection/core/test_support/mock_offline_content_provider.h" +#include "components/prefs/pref_service.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/image/image_unittest_util.h" @@ -135,12 +137,14 @@ content_provider_.SetVisuals({}); } - std::vector<chrome::mojom::AvailableOfflineContentPtr> ListAndWait() { + std::tuple<bool, std::vector<chrome::mojom::AvailableOfflineContentPtr>> + ListAndWait() { + bool list_visible_by_prefs; std::vector<chrome::mojom::AvailableOfflineContentPtr> suggestions; chrome::mojom::AvailableOfflineContentProviderAsyncWaiter waiter( &provider_); - waiter.List(&suggestions); - return suggestions; + waiter.List(&list_visible_by_prefs, &suggestions); + return std::make_tuple(list_visible_by_prefs, std::move(suggestions)); } chrome::mojom::AvailableOfflineContentSummaryPtr SummarizeAndWait() { @@ -161,8 +165,9 @@ }; TEST_F(AvailableOfflineContentTest, NoContent) { - std::vector<chrome::mojom::AvailableOfflineContentPtr> suggestions = - ListAndWait(); + bool list_visible_by_prefs; + std::vector<chrome::mojom::AvailableOfflineContentPtr> suggestions; + std::tie(list_visible_by_prefs, suggestions) = ListAndWait(); chrome::mojom::AvailableOfflineContentSummaryPtr summary = SummarizeAndWait(); EXPECT_EQ(0u, summary->total_items); @@ -171,6 +176,7 @@ EXPECT_FALSE(summary->has_video); EXPECT_FALSE(summary->has_audio); EXPECT_TRUE(suggestions.empty()); + EXPECT_TRUE(list_visible_by_prefs); } TEST_F(AvailableOfflineContentTest, TooFewInterestingItems) { @@ -182,8 +188,9 @@ IncompleteItem(), DangerousItem()}); // Call List() and Summary(). - std::vector<chrome::mojom::AvailableOfflineContentPtr> suggestions = - ListAndWait(); + bool list_visible_by_prefs; + std::vector<chrome::mojom::AvailableOfflineContentPtr> suggestions; + std::tie(list_visible_by_prefs, suggestions) = ListAndWait(); chrome::mojom::AvailableOfflineContentSummaryPtr summary = SummarizeAndWait(); // As interesting items are below the minimum to show, nothing should be @@ -195,6 +202,7 @@ EXPECT_FALSE(summary->has_audio); EXPECT_TRUE(suggestions.empty()); + EXPECT_TRUE(list_visible_by_prefs); } TEST_F(AvailableOfflineContentTest, FourInterestingItems) { @@ -207,8 +215,9 @@ {{SuggestedOfflinePageItem().id, TestThumbnail()}}); // Call List() and Summary(). - std::vector<chrome::mojom::AvailableOfflineContentPtr> suggestions = - ListAndWait(); + bool list_visible_by_prefs; + std::vector<chrome::mojom::AvailableOfflineContentPtr> suggestions; + std::tie(list_visible_by_prefs, suggestions) = ListAndWait(); chrome::mojom::AvailableOfflineContentSummaryPtr summary = SummarizeAndWait(); // Check summary. @@ -223,6 +232,7 @@ EXPECT_EQ(SuggestedOfflinePageItem().id.id, suggestions[0]->id); EXPECT_EQ(VideoItem().id.id, suggestions[1]->id); EXPECT_EQ(AudioItem().id.id, suggestions[2]->id); + EXPECT_TRUE(list_visible_by_prefs); // For a single suggestion, make sure all the fields are correct. We can // assume the other items match. @@ -250,10 +260,44 @@ scoped_feature_list_->InitAndDisableFeature(features::kNewNetErrorPageUI); content_provider_.SetItems({SuggestedOfflinePageItem()}); - std::vector<chrome::mojom::AvailableOfflineContentPtr> suggestions = - ListAndWait(); + bool list_visible_by_prefs; + std::vector<chrome::mojom::AvailableOfflineContentPtr> suggestions; + std::tie(list_visible_by_prefs, suggestions) = ListAndWait(); EXPECT_TRUE(suggestions.empty()); + EXPECT_TRUE(list_visible_by_prefs); +} + +TEST_F(AvailableOfflineContentTest, ListVisibilityChanges) { + // We need at least 4 interesting items for anything to show up at all. + content_provider_.SetItems({UninterestingImageItem(), VideoItem(), + SuggestedOfflinePageItem(), AudioItem(), + OfflinePageItem()}); + + content_provider_.SetVisuals( + {{SuggestedOfflinePageItem().id, TestThumbnail()}}); + // Set pref to hide the list. + profile_.GetPrefs()->SetBoolean(ntp_snippets::prefs::kArticlesListVisible, + false); + + // Call List(). + bool list_visible_by_prefs; + std::vector<chrome::mojom::AvailableOfflineContentPtr> suggestions; + std::tie(list_visible_by_prefs, suggestions) = ListAndWait(); + + // Check that suggestions have been received and the list is not visible. + EXPECT_EQ(3ul, suggestions.size()); + EXPECT_FALSE(list_visible_by_prefs); + + // Simulate visibility changed by the user to "shown". + provider_.ListVisibilityChanged(true); + + EXPECT_TRUE(profile_.GetPrefs()->GetBoolean( + ntp_snippets::prefs::kArticlesListVisible)); + + // Call List() again and check list is not visible. + std::tie(list_visible_by_prefs, suggestions) = ListAndWait(); + EXPECT_TRUE(list_visible_by_prefs); } } // namespace
diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.cc b/chrome/browser/android/omnibox/autocomplete_controller_android.cc index bf9244e9..aaa8573 100644 --- a/chrome/browser/android/omnibox/autocomplete_controller_android.cc +++ b/chrome/browser/android/omnibox/autocomplete_controller_android.cc
@@ -544,10 +544,9 @@ description_class_styles.push_back(description_class.style); } - ScopedJavaLocalRef<jstring> answer_contents = - ConvertUTF16ToJavaString(env, match.answer_contents); - ScopedJavaLocalRef<jstring> answer_type = - ConvertUTF16ToJavaString(env, match.answer_type); + ScopedJavaLocalRef<jobject> janswer; + if (match.answer) + janswer = match.answer->CreateJavaObject(); ScopedJavaLocalRef<jstring> fill_into_edit = ConvertUTF16ToJavaString(env, match.fill_into_edit); ScopedJavaLocalRef<jstring> destination_url = @@ -560,8 +559,8 @@ ToJavaIntArray(env, contents_class_offsets), ToJavaIntArray(env, contents_class_styles), description, ToJavaIntArray(env, description_class_offsets), - ToJavaIntArray(env, description_class_styles), answer_contents, - answer_type, fill_into_edit, destination_url, + ToJavaIntArray(env, description_class_styles), janswer, fill_into_edit, + destination_url, bookmark_model && bookmark_model->IsBookmarked(match.destination_url), match.SupportsDeletion()); }
diff --git a/chrome/browser/android/password_manager/password_accessory_view_android.cc b/chrome/browser/android/password_manager/manual_filling_view_android.cc similarity index 62% rename from chrome/browser/android/password_manager/password_accessory_view_android.cc rename to chrome/browser/android/password_manager/manual_filling_view_android.cc index 85d8e11..131bd8c 100644 --- a/chrome/browser/android/password_manager/password_accessory_view_android.cc +++ b/chrome/browser/android/password_manager/manual_filling_view_android.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/android/password_manager/password_accessory_view_android.h" +#include "chrome/browser/android/password_manager/manual_filling_view_android.h" #include <jni.h> @@ -13,9 +13,9 @@ #include "base/android/jni_android.h" #include "base/android/jni_array.h" #include "base/android/jni_string.h" -#include "chrome/browser/password_manager/password_accessory_controller.h" +#include "chrome/browser/autofill/manual_filling_controller.h" #include "components/autofill/core/browser/accessory_sheet_data.h" -#include "jni/PasswordAccessoryBridge_jni.h" +#include "jni/ManualFillingBridge_jni.h" #include "ui/android/view_android.h" #include "ui/android/window_android.h" #include "ui/gfx/android/java_bitmap.h" @@ -33,15 +33,14 @@ JNIEnv* env, const AccessorySheetData& data) { ScopedJavaLocalRef<jobject> j_data = - Java_PasswordAccessoryBridge_createAccessorySheetData( + Java_ManualFillingBridge_createAccessorySheetData( env, ConvertUTF16ToJavaString(env, data.title())); for (const UserInfo& user_info : data.user_info_list()) { ScopedJavaLocalRef<jobject> j_user_info = - Java_PasswordAccessoryBridge_addUserInfoToAccessorySheetData(env, - j_data); + Java_ManualFillingBridge_addUserInfoToAccessorySheetData(env, j_data); for (const UserInfo::Field& field : user_info.fields()) { - Java_PasswordAccessoryBridge_addFieldToUserInfo( + Java_ManualFillingBridge_addFieldToUserInfo( env, j_user_info, ConvertUTF16ToJavaString(env, field.display_text()), ConvertUTF16ToJavaString(env, field.a11y_description()), field.is_obfuscated(), field.selectable()); @@ -49,7 +48,7 @@ } for (const FooterCommand& footer_command : data.footer_commands()) { - Java_PasswordAccessoryBridge_addFooterCommandToAccessorySheetData( + Java_ManualFillingBridge_addFooterCommandToAccessorySheetData( env, j_data, ConvertUTF16ToJavaString(env, footer_command.display_text())); } @@ -58,76 +57,76 @@ } // namespace -PasswordAccessoryViewAndroid::PasswordAccessoryViewAndroid( - PasswordAccessoryController* controller) +ManualFillingViewAndroid::ManualFillingViewAndroid( + ManualFillingController* controller) : controller_(controller) { ui::ViewAndroid* view_android = controller_->container_view(); DCHECK(view_android); - java_object_.Reset(Java_PasswordAccessoryBridge_create( + java_object_.Reset(Java_ManualFillingBridge_create( base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this), view_android->GetWindowAndroid()->GetJavaObject())); } -PasswordAccessoryViewAndroid::~PasswordAccessoryViewAndroid() { +ManualFillingViewAndroid::~ManualFillingViewAndroid() { DCHECK(!java_object_.is_null()); - Java_PasswordAccessoryBridge_destroy(base::android::AttachCurrentThread(), - java_object_); + Java_ManualFillingBridge_destroy(base::android::AttachCurrentThread(), + java_object_); java_object_.Reset(nullptr); } -void PasswordAccessoryViewAndroid::OnItemsAvailable( +void ManualFillingViewAndroid::OnItemsAvailable( const AccessorySheetData& data) { DCHECK(!java_object_.is_null()); JNIEnv* env = base::android::AttachCurrentThread(); - Java_PasswordAccessoryBridge_onItemsAvailable( + Java_ManualFillingBridge_onItemsAvailable( env, java_object_, ConvertAccessorySheetDataToJavaObject(env, data)); } -void PasswordAccessoryViewAndroid::CloseAccessorySheet() { - Java_PasswordAccessoryBridge_closeAccessorySheet( +void ManualFillingViewAndroid::CloseAccessorySheet() { + Java_ManualFillingBridge_closeAccessorySheet( base::android::AttachCurrentThread(), java_object_); } -void PasswordAccessoryViewAndroid::SwapSheetWithKeyboard() { - Java_PasswordAccessoryBridge_swapSheetWithKeyboard( +void ManualFillingViewAndroid::SwapSheetWithKeyboard() { + Java_ManualFillingBridge_swapSheetWithKeyboard( base::android::AttachCurrentThread(), java_object_); } -void PasswordAccessoryViewAndroid::ShowWhenKeyboardIsVisible() { - Java_PasswordAccessoryBridge_showWhenKeyboardIsVisible( +void ManualFillingViewAndroid::ShowWhenKeyboardIsVisible() { + Java_ManualFillingBridge_showWhenKeyboardIsVisible( base::android::AttachCurrentThread(), java_object_); } -void PasswordAccessoryViewAndroid::Hide() { - Java_PasswordAccessoryBridge_hide(base::android::AttachCurrentThread(), - java_object_); +void ManualFillingViewAndroid::Hide() { + Java_ManualFillingBridge_hide(base::android::AttachCurrentThread(), + java_object_); } -void PasswordAccessoryViewAndroid::OnAutomaticGenerationStatusChanged( +void ManualFillingViewAndroid::OnAutomaticGenerationStatusChanged( bool available) { if (!available && java_object_.is_null()) return; JNIEnv* env = base::android::AttachCurrentThread(); - Java_PasswordAccessoryBridge_onAutomaticGenerationStatusChanged( - env, java_object_, available); + Java_ManualFillingBridge_onAutomaticGenerationStatusChanged(env, java_object_, + available); } -void PasswordAccessoryViewAndroid::OnFaviconRequested( +void ManualFillingViewAndroid::OnFaviconRequested( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, jint desiredSizeInPx, const base::android::JavaParamRef<jobject>& j_callback) { controller_->GetFavicon( desiredSizeInPx, - base::BindOnce(&PasswordAccessoryViewAndroid::OnImageFetched, + base::BindOnce(&ManualFillingViewAndroid::OnImageFetched, base::Unretained(this), // Outlives or cancels request. base::android::ScopedJavaGlobalRef<jobject>(j_callback))); } -void PasswordAccessoryViewAndroid::OnFillingTriggered( +void ManualFillingViewAndroid::OnFillingTriggered( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, jboolean isPassword, @@ -136,7 +135,7 @@ isPassword, base::android::ConvertJavaStringToUTF16(textToFill)); } -void PasswordAccessoryViewAndroid::OnOptionSelected( +void ManualFillingViewAndroid::OnOptionSelected( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, const base::android::JavaParamRef<_jstring*>& selectedOption) { @@ -144,13 +143,13 @@ base::android::ConvertJavaStringToUTF16(selectedOption)); } -void PasswordAccessoryViewAndroid::OnGenerationRequested( +void ManualFillingViewAndroid::OnGenerationRequested( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj) { controller_->OnGenerationRequested(); } -void PasswordAccessoryViewAndroid::OnImageFetched( +void ManualFillingViewAndroid::OnImageFetched( const base::android::ScopedJavaGlobalRef<jobject>& j_callback, const gfx::Image& image) { base::android::ScopedJavaLocalRef<jobject> j_bitmap; @@ -161,8 +160,7 @@ } // static -std::unique_ptr<PasswordAccessoryViewInterface> -PasswordAccessoryViewInterface::Create( - PasswordAccessoryController* controller) { - return std::make_unique<PasswordAccessoryViewAndroid>(controller); +std::unique_ptr<ManualFillingViewInterface> ManualFillingViewInterface::Create( + ManualFillingController* controller) { + return std::make_unique<ManualFillingViewAndroid>(controller); }
diff --git a/chrome/browser/android/password_manager/password_accessory_view_android.h b/chrome/browser/android/password_manager/manual_filling_view_android.h similarity index 65% rename from chrome/browser/android/password_manager/password_accessory_view_android.h rename to chrome/browser/android/password_manager/manual_filling_view_android.h index acc9ed2..cd7c5d7 100644 --- a/chrome/browser/android/password_manager/password_accessory_view_android.h +++ b/chrome/browser/android/password_manager/manual_filling_view_android.h
@@ -2,31 +2,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_ANDROID_PASSWORD_MANAGER_PASSWORD_ACCESSORY_VIEW_ANDROID_H_ -#define CHROME_BROWSER_ANDROID_PASSWORD_MANAGER_PASSWORD_ACCESSORY_VIEW_ANDROID_H_ +#ifndef CHROME_BROWSER_ANDROID_PASSWORD_MANAGER_MANUAL_FILLING_VIEW_ANDROID_H_ +#define CHROME_BROWSER_ANDROID_PASSWORD_MANAGER_MANUAL_FILLING_VIEW_ANDROID_H_ #include <vector> #include "base/android/scoped_java_ref.h" -#include "chrome/browser/password_manager/password_accessory_view_interface.h" +#include "chrome/browser/autofill/manual_filling_view_interface.h" namespace gfx { class Image; } -class PasswordAccessoryController; +class ManualFillingController; -// This Android-specific implementation of the |PasswordAccessoryViewInterface| +// This Android-specific implementation of the |ManualFillingViewInterface| // is the native counterpart of the |PasswordAccessoryViewBridge| java class. -// It's owned by a PasswordAccessoryController which is bound to an activity. -class PasswordAccessoryViewAndroid : public PasswordAccessoryViewInterface { +// It's owned by a ManualFillingController which is bound to an activity. +class ManualFillingViewAndroid : public ManualFillingViewInterface { public: // Builds the UI for the |controller|. - explicit PasswordAccessoryViewAndroid( - PasswordAccessoryController* controller); - ~PasswordAccessoryViewAndroid() override; + explicit ManualFillingViewAndroid(ManualFillingController* controller); + ~ManualFillingViewAndroid() override; - // PasswordAccessoryViewInterface: + // ManualFillingViewInterface: void OnItemsAvailable(const autofill::AccessorySheetData& data) override; void OnAutomaticGenerationStatusChanged(bool available) override; void CloseAccessorySheet() override; @@ -58,12 +57,12 @@ const gfx::Image& image); // The controller provides data for this view and owns it. - PasswordAccessoryController* controller_; + ManualFillingController* controller_; // The corresponding java object. base::android::ScopedJavaGlobalRef<jobject> java_object_; - DISALLOW_COPY_AND_ASSIGN(PasswordAccessoryViewAndroid); + DISALLOW_COPY_AND_ASSIGN(ManualFillingViewAndroid); }; -#endif // CHROME_BROWSER_ANDROID_PASSWORD_MANAGER_PASSWORD_ACCESSORY_VIEW_ANDROID_H_ +#endif // CHROME_BROWSER_ANDROID_PASSWORD_MANAGER_MANUAL_FILLING_VIEW_ANDROID_H_
diff --git a/chrome/browser/android/preferences/website_preference_bridge.cc b/chrome/browser/android/preferences/website_preference_bridge.cc index 824a9ea..46fb5a3 100644 --- a/chrome/browser/android/preferences/website_preference_bridge.cc +++ b/chrome/browser/android/preferences/website_preference_bridge.cc
@@ -18,12 +18,7 @@ #include "base/macros.h" #include "base/stl_util.h" #include "chrome/browser/android/search_permissions/search_permissions_service.h" -#include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h" #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" -#include "chrome/browser/browsing_data/browsing_data_media_license_helper.h" -#include "chrome/browser/browsing_data/browsing_data_quota_helper.h" -#include "chrome/browser/browsing_data/cookies_tree_model.h" -#include "chrome/browser/browsing_data/local_data_container.h" #include "chrome/browser/content_settings/cookie_settings_factory.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/content_settings/tab_specific_content_settings.h" @@ -45,7 +40,7 @@ #include "content/public/browser/storage_partition.h" #include "jni/WebsitePreferenceBridge_jni.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" -#include "storage/browser/quota/quota_manager.h" +#include "services/network/public/mojom/cookie_manager.mojom.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" #include "url/origin.h" #include "url/url_constants.h" @@ -626,102 +621,15 @@ namespace { -class SiteDataDeleteHelper : public CookiesTreeModel::Observer { - public: - SiteDataDeleteHelper(Profile* profile, const GURL& domain) - : profile_(profile), domain_(domain), ending_batch_processing_(false) { +void OnCookiesReceived(network::mojom::CookieManager* cookie_manager, + const GURL& domain, + const std::vector<net::CanonicalCookie>& cookies) { + for (const auto& cookie : cookies) { + if (domain.DomainIs(cookie.Domain())) { + cookie_manager->DeleteCanonicalCookie(cookie, base::DoNothing()); + } } - - void Run() { - content::StoragePartition* storage_partition = - content::BrowserContext::GetDefaultStoragePartition(profile_); - content::IndexedDBContext* indexed_db_context = - storage_partition->GetIndexedDBContext(); - content::ServiceWorkerContext* service_worker_context = - storage_partition->GetServiceWorkerContext(); - content::CacheStorageContext* cache_storage_context = - storage_partition->GetCacheStorageContext(); - storage::FileSystemContext* file_system_context = - storage_partition->GetFileSystemContext(); - auto container = std::make_unique<LocalDataContainer>( - new BrowsingDataCookieHelper(storage_partition), - new BrowsingDataDatabaseHelper(profile_), - new BrowsingDataLocalStorageHelper(profile_), - nullptr /* session_storage_helper */, - new BrowsingDataAppCacheHelper(profile_), - new BrowsingDataIndexedDBHelper(indexed_db_context), - BrowsingDataFileSystemHelper::Create(file_system_context), - BrowsingDataQuotaHelper::Create(profile_), - BrowsingDataChannelIDHelper::Create(profile_->GetRequestContext()), - new BrowsingDataServiceWorkerHelper(service_worker_context), - new BrowsingDataSharedWorkerHelper(storage_partition, - profile_->GetResourceContext()), - new BrowsingDataCacheStorageHelper(cache_storage_context), - nullptr /* flash_data_helper */, - BrowsingDataMediaLicenseHelper::Create(file_system_context)); - - cookies_tree_model_ = std::make_unique<CookiesTreeModel>( - std::move(container), profile_->GetExtensionSpecialStoragePolicy()); - cookies_tree_model_->AddCookiesTreeObserver(this); - } - - // TreeModelObserver: - void TreeNodesAdded(ui::TreeModel* model, - ui::TreeModelNode* parent, - int start, - int count) override {} - void TreeNodesRemoved(ui::TreeModel* model, - ui::TreeModelNode* parent, - int start, - int count) override {} - - // CookiesTreeModel::Observer: - void TreeNodeChanged(ui::TreeModel* model, ui::TreeModelNode* node) override { - } - - void TreeModelBeginBatch(CookiesTreeModel* model) override { - DCHECK(!ending_batch_processing_); // Extra batch-start sent. - } - - void TreeModelEndBatch(CookiesTreeModel* model) override { - DCHECK(!ending_batch_processing_); // Already in end-stage. - ending_batch_processing_ = true; - - RecursivelyFindSiteAndDelete(cookies_tree_model_->GetRoot()); - - // Delete this object after the current iteration of the message loop, - // because we are in a callback from the CookiesTreeModel, which we own, - // so it will be destroyed with this object. - BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this); - } - - void RecursivelyFindSiteAndDelete(CookieTreeNode* node) { - CookieTreeNode::DetailedInfo info = node->GetDetailedInfo(); - for (int i = node->child_count(); i > 0; --i) - RecursivelyFindSiteAndDelete(node->GetChild(i - 1)); - - if (info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE && - info.cookie && domain_.DomainIs(info.cookie->Domain())) - cookies_tree_model_->DeleteCookieNode(node); - } - - private: - friend class base::DeleteHelper<SiteDataDeleteHelper>; - - ~SiteDataDeleteHelper() override {} - - Profile* profile_; - - // The domain we want to delete data for. - GURL domain_; - - // Keeps track of when we're ready to close batch processing. - bool ending_batch_processing_; - - std::unique_ptr<CookiesTreeModel> cookies_tree_model_; - - DISALLOW_COPY_AND_ASSIGN(SiteDataDeleteHelper); -}; +} void OnStorageInfoReady(const ScopedJavaGlobalRef<jobject>& java_callback, const storage::UsageInfoEntries& entries) { @@ -886,10 +794,11 @@ Profile* profile = ProfileManager::GetActiveUserProfile(); GURL url(ConvertJavaStringToUTF8(env, jorigin)); - // Deletes itself when done. - SiteDataDeleteHelper* site_data_deleter = - new SiteDataDeleteHelper(profile, url); - site_data_deleter->Run(); + auto* storage_partition = + content::BrowserContext::GetDefaultStoragePartition(profile); + auto* cookie_manager = storage_partition->GetCookieManagerForBrowserProcess(); + cookie_manager->GetAllCookies( + base::BindOnce(&OnCookiesReceived, cookie_manager, url)); } static void JNI_WebsitePreferenceBridge_ClearBannerData(
diff --git a/chrome/browser/android/tab_web_contents_delegate_android.cc b/chrome/browser/android/tab_web_contents_delegate_android.cc index f3cf479..4fdac07 100644 --- a/chrome/browser/android/tab_web_contents_delegate_android.cc +++ b/chrome/browser/android/tab_web_contents_delegate_android.cc
@@ -279,8 +279,8 @@ content::JavaScriptDialogManager* TabWebContentsDelegateAndroid::GetJavaScriptDialogManager( WebContents* source) { - if (base::FeatureList::IsEnabled(chrome::android::kTabModalJsDialog) || - vr::VrTabHelper::IsInVr(source)) { + // For VR, we use app modal since the dialog view will cover the location bar. + if (!vr::VrTabHelper::IsInVr(source)) { return JavaScriptDialogTabHelper::FromWebContents(source); } return app_modal::JavaScriptDialogManager::GetInstance();
diff --git a/chrome/browser/autofill/manual_filling_controller.h b/chrome/browser/autofill/manual_filling_controller.h new file mode 100644 index 0000000..65c6957 --- /dev/null +++ b/chrome/browser/autofill/manual_filling_controller.h
@@ -0,0 +1,131 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_AUTOFILL_MANUAL_FILLING_CONTROLLER_H_ +#define CHROME_BROWSER_AUTOFILL_MANUAL_FILLING_CONTROLLER_H_ + +#include <memory> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/strings/string16.h" +#include "components/autofill/core/browser/accessory_sheet_data.h" +#include "components/autofill/core/common/filling_status.h" +#include "content/public/browser/web_contents_user_data.h" +#include "ui/gfx/image/image.h" + +// Controller interface for the view that includes the keyboard accessory and +// the accessory sheet below it. Implementations of this interface create and +// own a ManualFillingViewInterface. +// +// The manual filling controller forwards requests from type-specific accessory +// controllers (Passwords and Autofill) to the view. The view notifies this +// controller about interactions (such as requesting to fill a password +// suggestion) and forwards the request to the corresponding type-specific +// accessory controller. +// +// This controller also implements the logic to show/hide the keyboard +// accessory. +// +// ManualFillingController::GetOrCreate() should be used +// by type-specific controllers to obtain an instance of this class for a given +// WebContents. There is only one instance per WebContents, which is created the +// first time |GetOrCreate()| is invoked. +// +// Usage example: +// auto controller = ManualFillingController::GetOrCreate(web_contents); +// DCHECK(controller); +// controller->RefreshSuggestionsForField(...); +class ManualFillingController { + public: + ManualFillingController() = default; + virtual ~ManualFillingController() = default; + + // Returns a weak pointer to the unique ManualFillingController instance + // associated with a WebContents. The first invocation creates an instance + // and attaches it to the WebContents; the same instance is returned by all + // future invocations for the same WebContents. + static base::WeakPtr<ManualFillingController> GetOrCreate( + content::WebContents* contents); + + // -------------------------------------------- + // Methods called by type-specific controllers. + // -------------------------------------------- + + // Forwards |accessory_sheet_data| to the view provided by a type-specific + // controller to be shown on the accessory sheet. If a field lost focus, + // |is_fillable| should be false. + virtual void RefreshSuggestionsForField( + bool is_fillable, + const autofill::AccessorySheetData& accessory_sheet_data) = 0; + + // Completes a filling attempt by recording metrics, giving feedback to the + // user and dismissing the accessory sheet. + virtual void OnFilledIntoFocusedField(autofill::FillingStatus status) = 0; + + // Requests to show the accessory bar. The accessory will only be shown + // when the keyboard becomes visible. + virtual void ShowWhenKeyboardIsVisible() = 0; + + // Requests to hide the accessory. This hides both the accessory sheet + // (if open) and the accessory bar. + virtual void Hide() = 0; + + // Notifies the view that automatic password generation status changed. + // + // TODO(crbug.com/905669): This controller doesn't need to know about password + // generation. Generalize this to send to the UI the information that an + // action (given by an enum param) is available. + virtual void OnAutomaticGenerationStatusChanged(bool available) = 0; + + // -------------------------- + // Methods called by UI code: + // -------------------------- + + // Called by the UI code to request that |text_to_fill| is to be filled into + // the currently focused field. Forwards the request to a type-specific + // accessory controller. + virtual void OnFillingTriggered(bool is_password, + const base::string16& text_to_fill) = 0; + + // Called by the UI code because a user triggered the |selected_option|, + // such as "Manage passwords..." + // TODO(crbug.com/905669): Replace the string param with an enum to indicate + // the selected option. + virtual void OnOptionSelected( + const base::string16& selected_option) const = 0; + + // Called by the UI code to signal that the user requested password + // generation. This should prompt a modal dialog with the generated password. + // + // TODO(crbug.com/905669): This controller doesn't need to know about password + // generation. Generalize this to forward an action request from the UI to a + // type-specific accessory controller. + virtual void OnGenerationRequested() = 0; + + // Gets an icon for the currently focused frame and passes it to + // |icon_callback|. The callback is invoked with an image unless an icon for + // a new origin was called. In the latter case, the callback is dropped. + // The callback is called with an |IsEmpty()| image if there is no favicon. + // + // TODO(crbug.com/905669): This controller doesn't need to know about + // favicons. Generalize this to forward an icon requests from the UI to a + // type-specific accessory controller. + virtual void GetFavicon( + int desired_size_in_pixel, + base::OnceCallback<void(const gfx::Image&)> icon_callback) = 0; + + // ----------------- + // Member accessors: + // ----------------- + + // The web page view containing the focused field. + virtual gfx::NativeView container_view() const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(ManualFillingController); +}; + +#endif // CHROME_BROWSER_AUTOFILL_MANUAL_FILLING_CONTROLLER_H_
diff --git a/chrome/browser/autofill/manual_filling_controller_impl.cc b/chrome/browser/autofill/manual_filling_controller_impl.cc new file mode 100644 index 0000000..b70cbdd6 --- /dev/null +++ b/chrome/browser/autofill/manual_filling_controller_impl.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 "chrome/browser/autofill/manual_filling_controller_impl.h" + +#include <utility> + +#include "base/callback.h" +#include "base/metrics/histogram_macros.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/password_manager/password_accessory_controller.h" +#include "chrome/browser/password_manager/password_accessory_metrics_util.h" +#include "chrome/browser/profiles/profile.h" +#include "content/public/browser/web_contents.h" + +using autofill::AccessorySheetData; + +ManualFillingControllerImpl::~ManualFillingControllerImpl() = default; + +// static +base::WeakPtr<ManualFillingController> ManualFillingController::GetOrCreate( + content::WebContents* contents) { + ManualFillingControllerImpl::CreateForWebContents(contents); + return ManualFillingControllerImpl::FromWebContents(contents)->AsWeakPtr(); +} + +// static +void ManualFillingControllerImpl::CreateForWebContentsForTesting( + content::WebContents* web_contents, + base::WeakPtr<PasswordAccessoryController> pwd_controller, + std::unique_ptr<ManualFillingViewInterface> view) { + DCHECK(web_contents) << "Need valid WebContents to attach controller to!"; + DCHECK(!FromWebContents(web_contents)) << "Controller already attached!"; + DCHECK(pwd_controller); + DCHECK(view); + + web_contents->SetUserData( + UserDataKey(), + base::WrapUnique(new ManualFillingControllerImpl( + web_contents, std::move(pwd_controller), std::move(view)))); +} + +void ManualFillingControllerImpl::OnAutomaticGenerationStatusChanged( + bool available) { + DCHECK(view_); + view_->OnAutomaticGenerationStatusChanged(available); +} + +void ManualFillingControllerImpl::OnFilledIntoFocusedField( + autofill::FillingStatus status) { + if (status != autofill::FillingStatus::SUCCESS) + return; // TODO(crbug.com/853766): Record success rate. + view_->SwapSheetWithKeyboard(); +} + +void ManualFillingControllerImpl::RefreshSuggestionsForField( + bool is_fillable, + const AccessorySheetData& accessory_sheet_data) { + view_->OnItemsAvailable(accessory_sheet_data); + + // TODO(crbug.com/905669): The decision for showing the sheet or not will need + // to take into account if Autofill suggestions are also available. + if (is_fillable) { + view_->SwapSheetWithKeyboard(); + } else { + view_->CloseAccessorySheet(); + } +} + +void ManualFillingControllerImpl::ShowWhenKeyboardIsVisible() { + view_->ShowWhenKeyboardIsVisible(); +} + +void ManualFillingControllerImpl::Hide() { + view_->Hide(); +} + +void ManualFillingControllerImpl::OnFillingTriggered( + bool is_password, + const base::string16& text_to_fill) { + DCHECK(pwd_controller_); + pwd_controller_->OnFillingTriggered(is_password, text_to_fill); +} + +void ManualFillingControllerImpl::OnOptionSelected( + const base::string16& selected_option) const { + DCHECK(pwd_controller_); + pwd_controller_->OnOptionSelected(selected_option); +} + +void ManualFillingControllerImpl::OnGenerationRequested() { + DCHECK(pwd_controller_); + pwd_controller_->OnGenerationRequested(); +} + +void ManualFillingControllerImpl::GetFavicon( + int desired_size_in_pixel, + base::OnceCallback<void(const gfx::Image&)> icon_callback) { + DCHECK(pwd_controller_); + pwd_controller_->GetFavicon(desired_size_in_pixel, std::move(icon_callback)); +} + +gfx::NativeView ManualFillingControllerImpl::container_view() const { + return web_contents_->GetNativeView(); +} + +// Returns a weak pointer for this object. +base::WeakPtr<ManualFillingController> +ManualFillingControllerImpl::AsWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + +ManualFillingControllerImpl::ManualFillingControllerImpl( + content::WebContents* web_contents) + : web_contents_(web_contents), + view_(ManualFillingViewInterface::Create(this)), + weak_factory_(this) { + if (PasswordAccessoryController::AllowedForWebContents(web_contents)) { + pwd_controller_ = + PasswordAccessoryController::GetOrCreate(web_contents)->AsWeakPtr(); + DCHECK(pwd_controller_); + } +} + +ManualFillingControllerImpl::ManualFillingControllerImpl( + content::WebContents* web_contents, + base::WeakPtr<PasswordAccessoryController> pwd_controller, + std::unique_ptr<ManualFillingViewInterface> view) + : web_contents_(web_contents), + pwd_controller_(std::move(pwd_controller)), + view_(std::move(view)), + weak_factory_(this) {}
diff --git a/chrome/browser/autofill/manual_filling_controller_impl.h b/chrome/browser/autofill/manual_filling_controller_impl.h new file mode 100644 index 0000000..4fc85b0 --- /dev/null +++ b/chrome/browser/autofill/manual_filling_controller_impl.h
@@ -0,0 +1,86 @@ +// 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_AUTOFILL_MANUAL_FILLING_CONTROLLER_IMPL_H_ +#define CHROME_BROWSER_AUTOFILL_MANUAL_FILLING_CONTROLLER_IMPL_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/autofill/manual_filling_controller.h" +#include "chrome/browser/autofill/manual_filling_view_interface.h" +#include "content/public/browser/web_contents_user_data.h" + +class PasswordAccessoryController; + +// Use ManualFillingController::GetOrCreate to obtain instances of this class. +class ManualFillingControllerImpl + : public ManualFillingController, + public content::WebContentsUserData<ManualFillingControllerImpl> { + public: + ~ManualFillingControllerImpl() override; + + // ManualFillingController: + void RefreshSuggestionsForField( + bool is_fillable, + const autofill::AccessorySheetData& accessory_sheet_data) override; + void OnFilledIntoFocusedField(autofill::FillingStatus status) override; + void ShowWhenKeyboardIsVisible() override; + void Hide() override; + void OnAutomaticGenerationStatusChanged(bool available) override; + void OnFillingTriggered(bool is_password, + const base::string16& text_to_fill) override; + void OnOptionSelected(const base::string16& selected_option) const override; + void OnGenerationRequested() override; + void GetFavicon( + int desired_size_in_pixel, + base::OnceCallback<void(const gfx::Image&)> icon_callback) override; + gfx::NativeView container_view() const override; + + // Returns a weak pointer for this object. + base::WeakPtr<ManualFillingController> AsWeakPtr(); + + // Like |CreateForWebContents|, it creates the controller and attaches it to + // the given |web_contents|. Additionally, it allows injecting a fake/mock + // view and type-specific controllers. + static void CreateForWebContentsForTesting( + content::WebContents* web_contents, + base::WeakPtr<PasswordAccessoryController> pwd_controller, + std::unique_ptr<ManualFillingViewInterface> test_view); + +#if defined(UNIT_TEST) + // Returns the held view for testing. + ManualFillingViewInterface* view() const { return view_.get(); } +#endif // defined(UNIT_TEST) + + private: + friend class content::WebContentsUserData<ManualFillingControllerImpl>; + + // Required for construction via |CreateForWebContents|: + explicit ManualFillingControllerImpl(content::WebContents* contents); + + // Constructor that allows to inject a mock or fake view. + ManualFillingControllerImpl( + content::WebContents* web_contents, + base::WeakPtr<PasswordAccessoryController> pwd_controller, + std::unique_ptr<ManualFillingViewInterface> view); + + // The tab for which this class is scoped. + content::WebContents* web_contents_; + + // The password accessory controller object to forward view requests to. + base::WeakPtr<PasswordAccessoryController> pwd_controller_; + + // Hold the native instance of the view. Must be last declared and initialized + // member so the view can be created in the constructor with a fully set up + // controller instance. + std::unique_ptr<ManualFillingViewInterface> view_; + + base::WeakPtrFactory<ManualFillingControllerImpl> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(ManualFillingControllerImpl); +}; + +#endif // CHROME_BROWSER_AUTOFILL_MANUAL_FILLING_CONTROLLER_IMPL_H_
diff --git a/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc b/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc new file mode 100644 index 0000000..22af41c --- /dev/null +++ b/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc
@@ -0,0 +1,193 @@ +// 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/autofill/manual_filling_controller_impl.h" + +#include <map> +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/autofill/manual_filling_view_interface.h" +#include "chrome/browser/password_manager/password_accessory_controller.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { +using testing::_; +using testing::AnyNumber; +using testing::NiceMock; +using testing::StrictMock; + +constexpr char kExampleSite[] = "https://example.com"; + +class MockPasswordAccessoryController : public PasswordAccessoryController { + public: + MOCK_METHOD2( + SavePasswordsForOrigin, + void(const std::map<base::string16, const autofill::PasswordForm*>&, + const url::Origin&)); + MOCK_METHOD3( + OnAutomaticGenerationStatusChanged, + void(bool, + const base::Optional< + autofill::password_generation::PasswordGenerationUIData>&, + const base::WeakPtr<password_manager::PasswordManagerDriver>&)); + MOCK_METHOD1(OnFilledIntoFocusedField, void(autofill::FillingStatus)); + MOCK_METHOD3(RefreshSuggestionsForField, + void(const url::Origin&, bool, bool)); + MOCK_METHOD0(DidNavigateMainFrame, void()); + MOCK_METHOD0(ShowWhenKeyboardIsVisible, void()); + MOCK_METHOD0(Hide, void()); + MOCK_METHOD2(GetFavicon, + void(int, base::OnceCallback<void(const gfx::Image&)>)); + MOCK_METHOD2(OnFillingTriggered, void(bool, const base::string16&)); + MOCK_CONST_METHOD1(OnOptionSelected, void(const base::string16&)); + MOCK_METHOD0(OnGenerationRequested, void()); + MOCK_METHOD1(GeneratedPasswordAccepted, void(const base::string16&)); + MOCK_METHOD0(GeneratedPasswordRejected, void()); + MOCK_CONST_METHOD0(native_window, gfx::NativeWindow()); +}; + +// The mock view mocks the platform-specific implementation. That also means +// that we have to care about the lifespan of the Controller because that would +// usually be responsibility of the view. +class MockPasswordAccessoryView : public ManualFillingViewInterface { + public: + MockPasswordAccessoryView() = default; + + MOCK_METHOD1(OnItemsAvailable, void(const autofill::AccessorySheetData&)); + MOCK_METHOD1(OnFillingTriggered, void(const base::string16&)); + MOCK_METHOD0(OnViewDestroyed, void()); + MOCK_METHOD1(OnAutomaticGenerationStatusChanged, void(bool)); + MOCK_METHOD0(CloseAccessorySheet, void()); + MOCK_METHOD0(SwapSheetWithKeyboard, void()); + MOCK_METHOD0(ShowWhenKeyboardIsVisible, void()); + MOCK_METHOD0(Hide, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockPasswordAccessoryView); +}; + +autofill::AccessorySheetData dummy_accessory_sheet_data() { + constexpr char kExampleAccessorySheetDataTitle[] = "Example title"; + return autofill::AccessorySheetData( + base::ASCIIToUTF16(kExampleAccessorySheetDataTitle)); +} + +} // namespace + +class ManualFillingControllerTest : public ChromeRenderViewHostTestHarness { + public: + ManualFillingControllerTest() = default; + + void SetUp() override { + ChromeRenderViewHostTestHarness::SetUp(); + NavigateAndCommit(GURL(kExampleSite)); + ManualFillingControllerImpl::CreateForWebContentsForTesting( + web_contents(), mock_pwd_controller_.AsWeakPtr(), + std::make_unique<StrictMock<MockPasswordAccessoryView>>()); + NavigateAndCommit(GURL(kExampleSite)); + } + + ManualFillingControllerImpl* controller() { + return ManualFillingControllerImpl::FromWebContents(web_contents()); + } + + MockPasswordAccessoryView* view() { + return static_cast<MockPasswordAccessoryView*>(controller()->view()); + } + + protected: + NiceMock<MockPasswordAccessoryController> mock_pwd_controller_; +}; + +TEST_F(ManualFillingControllerTest, IsNotRecreatedForSameWebContents) { + ManualFillingController* initial_controller = + ManualFillingControllerImpl::FromWebContents(web_contents()); + EXPECT_NE(nullptr, initial_controller); + ManualFillingControllerImpl::CreateForWebContents(web_contents()); + EXPECT_EQ(ManualFillingControllerImpl::FromWebContents(web_contents()), + initial_controller); +} + +// TODO(fhorschig): Check for recorded metrics here or similar to this. +TEST_F(ManualFillingControllerTest, ClosesViewWhenRefreshingSuggestions) { + // Ignore Items - only the closing calls are interesting here. + EXPECT_CALL(*view(), OnItemsAvailable(_)).Times(AnyNumber()); + + EXPECT_CALL(*view(), CloseAccessorySheet()); + EXPECT_CALL(*view(), SwapSheetWithKeyboard()) + .Times(0); // Don't touch the keyboard! + controller()->RefreshSuggestionsForField( + /*is_fillable=*/false, dummy_accessory_sheet_data()); +} + +// TODO(fhorschig): Check for recorded metrics here or similar to this. +TEST_F(ManualFillingControllerTest, + SwapSheetWithKeyboardWhenRefreshingSuggestions) { + // Ignore Items - only the closing calls are interesting here. + EXPECT_CALL(*view(), OnItemsAvailable(_)).Times(AnyNumber()); + + EXPECT_CALL(*view(), CloseAccessorySheet()).Times(0); + EXPECT_CALL(*view(), SwapSheetWithKeyboard()); + controller()->RefreshSuggestionsForField( + /*is_fillable=*/true, dummy_accessory_sheet_data()); +} + +// TODO(fhorschig): Check for recorded metrics here or similar to this. +TEST_F(ManualFillingControllerTest, ClosesViewOnSuccessfullFillingOnly) { + // If the filling wasn't successful, no call is expected. + EXPECT_CALL(*view(), CloseAccessorySheet()).Times(0); + EXPECT_CALL(*view(), SwapSheetWithKeyboard()).Times(0); + controller()->OnFilledIntoFocusedField( + autofill::FillingStatus::ERROR_NOT_ALLOWED); + controller()->OnFilledIntoFocusedField( + autofill::FillingStatus::ERROR_NO_VALID_FIELD); + + // If the filling completed successfully, let the view know. + EXPECT_CALL(*view(), SwapSheetWithKeyboard()); + controller()->OnFilledIntoFocusedField(autofill::FillingStatus::SUCCESS); +} + +TEST_F(ManualFillingControllerTest, RelaysShowAndHideKeyboardAccessory) { + EXPECT_CALL(*view(), ShowWhenKeyboardIsVisible()); + controller()->ShowWhenKeyboardIsVisible(); + EXPECT_CALL(*view(), Hide()); + controller()->Hide(); +} + +TEST_F(ManualFillingControllerTest, OnAutomaticGenerationStatusChanged) { + EXPECT_CALL(*view(), OnAutomaticGenerationStatusChanged(true)); + controller()->OnAutomaticGenerationStatusChanged(true); + + EXPECT_CALL(*view(), OnAutomaticGenerationStatusChanged(false)); + controller()->OnAutomaticGenerationStatusChanged(false); +} + +TEST_F(ManualFillingControllerTest, OnFillingTriggered) { + const char kTextToFill[] = "TextToFill"; + const base::string16 text_to_fill(base::ASCIIToUTF16(kTextToFill)); + + EXPECT_CALL(mock_pwd_controller_, OnFillingTriggered(true, text_to_fill)); + controller()->OnFillingTriggered(true, text_to_fill); + + EXPECT_CALL(mock_pwd_controller_, OnFillingTriggered(false, text_to_fill)); + controller()->OnFillingTriggered(false, text_to_fill); +} + +TEST_F(ManualFillingControllerTest, OnGenerationRequested) { + EXPECT_CALL(mock_pwd_controller_, OnGenerationRequested()); + controller()->OnGenerationRequested(); +} + +TEST_F(ManualFillingControllerTest, GetFavicon) { + constexpr int kIconSize = 75; + auto icon_callback = base::BindOnce([](const gfx::Image&) {}); + + EXPECT_CALL(mock_pwd_controller_, GetFavicon(kIconSize, _)); + controller()->GetFavicon(kIconSize, std::move(icon_callback)); +}
diff --git a/chrome/browser/password_manager/password_accessory_view_interface.h b/chrome/browser/autofill/manual_filling_view_interface.h similarity index 80% rename from chrome/browser/password_manager/password_accessory_view_interface.h rename to chrome/browser/autofill/manual_filling_view_interface.h index 7a513c08..5dde843 100644 --- a/chrome/browser/password_manager/password_accessory_view_interface.h +++ b/chrome/browser/autofill/manual_filling_view_interface.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_ACCESSORY_VIEW_INTERFACE_H_ -#define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_ACCESSORY_VIEW_INTERFACE_H_ +#ifndef CHROME_BROWSER_AUTOFILL_MANUAL_FILLING_VIEW_INTERFACE_H_ +#define CHROME_BROWSER_AUTOFILL_MANUAL_FILLING_VIEW_INTERFACE_H_ #include <memory> #include <vector> @@ -12,16 +12,16 @@ #include "build/build_config.h" #include "url/gurl.h" -class PasswordAccessoryController; +class ManualFillingController; namespace autofill { class AccessorySheetData; } // namespace autofill // The interface for creating and controlling a view for the password accessory. -// The view gets data from a given |PasswordAccessoryController| and forwards +// The view gets data from a given |ManualFillingController| and forwards // any request (like filling a suggestion) back to the controller. -class PasswordAccessoryViewInterface { +class ManualFillingViewInterface { public: // Defines which item types exist. // TODO(crbug.com/902425): Remove this once AccessorySheetData is used on the @@ -50,7 +50,7 @@ TOP_DIVIDER = 6, }; - virtual ~PasswordAccessoryViewInterface() = default; + virtual ~ManualFillingViewInterface() = default; // Called with data that should replace the data currently shown on the // accessory sheet. @@ -73,10 +73,10 @@ virtual void Hide() = 0; private: - friend class PasswordAccessoryController; + friend class ManualFillingControllerImpl; // Factory function used to create a concrete instance of this view. - static std::unique_ptr<PasswordAccessoryViewInterface> Create( - PasswordAccessoryController* controller); + static std::unique_ptr<ManualFillingViewInterface> Create( + ManualFillingController* controller); }; -#endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_ACCESSORY_VIEW_INTERFACE_H_ +#endif // CHROME_BROWSER_AUTOFILL_MANUAL_FILLING_VIEW_INTERFACE_H_
diff --git a/chrome/browser/banners/app_banner_infobar_delegate_android.cc b/chrome/browser/banners/app_banner_infobar_delegate_android.cc index 2d6ec207..e400c01 100644 --- a/chrome/browser/banners/app_banner_infobar_delegate_android.cc +++ b/chrome/browser/banners/app_banner_infobar_delegate_android.cc
@@ -6,12 +6,10 @@ #include <utility> -#include "base/android/jni_android.h" #include "chrome/browser/banners/app_banner_ui_delegate_android.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/ui/android/infobars/app_banner_infobar_android.h" #include "content/public/browser/web_contents.h" -#include "jni/AppBannerInfoBarDelegateAndroid_jni.h" namespace banners { @@ -27,9 +25,6 @@ AppBannerInfoBarDelegateAndroid::~AppBannerInfoBarDelegateAndroid() { ui_delegate_.reset(); - Java_AppBannerInfoBarDelegateAndroid_destroy( - base::android::AttachCurrentThread(), java_delegate_); - java_delegate_.Reset(); } const AppBannerUiDelegateAndroid* @@ -37,43 +32,6 @@ return ui_delegate_.get(); } -void AppBannerInfoBarDelegateAndroid::UpdateInstallState( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj) { - if (ui_delegate_->GetType() != AppBannerUiDelegateAndroid::AppType::NATIVE) - return; - - static_cast<AppBannerInfoBarAndroid*>(infobar())->OnInstallStateChanged( - ui_delegate_->GetInstallState()); -} - -void AppBannerInfoBarDelegateAndroid::OnInstallIntentReturned( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - jboolean jis_installing) { - DCHECK(infobar()); - - content::WebContents* web_contents = - InfoBarService::WebContentsFromInfoBar(infobar()); - if (jis_installing) - ui_delegate_->OnNativeAppInstallStarted(web_contents); - - UpdateInstallState(env, obj); -} - -void AppBannerInfoBarDelegateAndroid::OnInstallFinished( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - jboolean success) { - DCHECK(infobar()); - - ui_delegate_->OnNativeAppInstallFinished(success); - if (success) - UpdateInstallState(env, obj); - else - infobar()->RemoveSelf(); -} - bool AppBannerInfoBarDelegateAndroid::Accept() { return ui_delegate_->InstallApp( InfoBarService::WebContentsFromInfoBar(infobar())); @@ -88,14 +46,6 @@ AppBannerInfoBarDelegateAndroid::AppBannerInfoBarDelegateAndroid( std::unique_ptr<AppBannerUiDelegateAndroid> ui_delegate) : ui_delegate_(std::move(ui_delegate)) { - CreateJavaDelegate(base::android::AttachCurrentThread()); - ui_delegate_->CreateInstallerDelegate( - base::android::ScopedJavaLocalRef<jobject>(java_delegate_)); -} - -void AppBannerInfoBarDelegateAndroid::CreateJavaDelegate(JNIEnv* env) { - java_delegate_.Reset(Java_AppBannerInfoBarDelegateAndroid_create( - env, reinterpret_cast<intptr_t>(this))); } infobars::InfoBarDelegate::InfoBarIdentifier
diff --git a/chrome/browser/banners/app_banner_infobar_delegate_android.h b/chrome/browser/banners/app_banner_infobar_delegate_android.h index f5de528..3c4fc75 100644 --- a/chrome/browser/banners/app_banner_infobar_delegate_android.h +++ b/chrome/browser/banners/app_banner_infobar_delegate_android.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/android/scoped_java_ref.h" #include "base/macros.h" #include "base/strings/string16.h" #include "components/infobars/core/confirm_infobar_delegate.h" @@ -32,21 +31,6 @@ const AppBannerUiDelegateAndroid* GetUiDelegate() const; - // Called when the AppBannerInfoBarAndroid's button needs to be updated. - void UpdateInstallState(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj); - - // Called when the native app installation Intent has been handled and focus - // has been returned to Chrome. - void OnInstallIntentReturned(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - jboolean jis_installing); - - // Called when the native app InstallerDelegate task has finished. - void OnInstallFinished(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - jboolean success); - // ConfirmInfoBarDelegate: bool Accept() override; base::string16 GetMessageText() const override; @@ -55,8 +39,6 @@ AppBannerInfoBarDelegateAndroid( std::unique_ptr<AppBannerUiDelegateAndroid> ui_delegate); - void CreateJavaDelegate(JNIEnv* env); - // ConfirmInfoBarDelegate: infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override; void InfoBarDismissed() override; @@ -64,7 +46,6 @@ bool LinkClicked(WindowOpenDisposition disposition) override; std::unique_ptr<AppBannerUiDelegateAndroid> ui_delegate_; - base::android::ScopedJavaGlobalRef<jobject> java_delegate_; DISALLOW_COPY_AND_ASSIGN(AppBannerInfoBarDelegateAndroid); };
diff --git a/chrome/browser/banners/app_banner_manager_android.cc b/chrome/browser/banners/app_banner_manager_android.cc index c9c91dec..4054266a 100644 --- a/chrome/browser/banners/app_banner_manager_android.cc +++ b/chrome/browser/banners/app_banner_manager_android.cc
@@ -283,7 +283,7 @@ ui_delegate_ = AppBannerUiDelegateAndroid::Create( GetWeakPtr(), native_app_title_, base::android::ScopedJavaLocalRef<jobject>(native_app_data_), - primary_icon_, native_app_package_, referrer_); + primary_icon_, native_app_package_); } bool banner_shown = false;
diff --git a/chrome/browser/banners/app_banner_ui_delegate_android.cc b/chrome/browser/banners/app_banner_ui_delegate_android.cc index 3f79e37..9819c4c 100644 --- a/chrome/browser/banners/app_banner_ui_delegate_android.cc +++ b/chrome/browser/banners/app_banner_ui_delegate_android.cc
@@ -47,11 +47,10 @@ const base::string16& app_title, const base::android::ScopedJavaLocalRef<jobject>& native_app_data, const SkBitmap& icon, - const std::string& native_app_package_name, - const std::string& referrer) { + const std::string& native_app_package_name) { return std::unique_ptr<AppBannerUiDelegateAndroid>( new AppBannerUiDelegateAndroid(weak_manager, app_title, native_app_data, - icon, native_app_package_name, referrer)); + icon, native_app_package_name)); } AppBannerUiDelegateAndroid::~AppBannerUiDelegateAndroid() { @@ -86,14 +85,6 @@ return base::android::ScopedJavaLocalRef<jobject>(native_app_data_); } -int AppBannerUiDelegateAndroid::GetInstallState() const { - JNIEnv* env = base::android::AttachCurrentThread(); - base::android::ScopedJavaLocalRef<jstring> jpackage_name( - base::android::ConvertUTF8ToJavaString(env, package_name_)); - return Java_AppBannerUiDelegateAndroid_determineInstallState( - env, java_delegate_, jpackage_name); -} - const SkBitmap& AppBannerUiDelegateAndroid::GetPrimaryIcon() const { return primary_icon_; } @@ -270,14 +261,12 @@ const base::string16& app_title, const base::android::ScopedJavaLocalRef<jobject>& native_app_data, const SkBitmap& icon, - const std::string& native_app_package_name, - const std::string& referrer) + const std::string& native_app_package_name) : weak_manager_(weak_manager), app_title_(app_title), native_app_data_(native_app_data), primary_icon_(icon), package_name_(native_app_package_name), - referrer_(referrer), type_(AppType::NATIVE), has_user_interaction_(false) { DCHECK(!native_app_data_.is_null()); @@ -285,14 +274,6 @@ CreateJavaDelegate(); } -void AppBannerUiDelegateAndroid::CreateInstallerDelegate( - base::android::ScopedJavaLocalRef<jobject> jobserver) { - DCHECK(!java_delegate_.is_null()); - - Java_AppBannerUiDelegateAndroid_createInstallerDelegate( - base::android::AttachCurrentThread(), java_delegate_, jobserver); -} - void AppBannerUiDelegateAndroid::CreateJavaDelegate() { TabAndroid* tab = TabAndroid::FromWebContents(weak_manager_->web_contents()); @@ -306,11 +287,8 @@ TrackUserResponse(USER_RESPONSE_NATIVE_APP_ACCEPTED); JNIEnv* env = base::android::AttachCurrentThread(); - base::android::ScopedJavaLocalRef<jstring> jreferrer( - base::android::ConvertUTF8ToJavaString(env, referrer_)); - bool was_opened = Java_AppBannerUiDelegateAndroid_installOrOpenNativeApp( - env, java_delegate_, native_app_data_, jreferrer); + env, java_delegate_, native_app_data_); if (was_opened) TrackDismissEvent(DISMISS_EVENT_APP_OPEN); @@ -351,13 +329,13 @@ weak_manager_->SendBannerAccepted(); // Send the appinstalled event and perform install time logging. Note that - // this is fired *before* the installation actually takes place (which can be - // a significant amount of time later, especially if using WebAPKs). + // this is only done for webapps as native apps just intent to the Play store. + // Also this event is fired *before* the installation actually takes place + // (which can be a significant amount of time later, especially if using + // WebAPKs). // TODO(mgiuca): Fire the event *after* the installation is completed. - bool is_native = IsForNativeApp(); - weak_manager_->OnInstall(is_native, is_native - ? blink::kWebDisplayModeUndefined - : shortcut_info_->display); + if (!IsForNativeApp()) + weak_manager_->OnInstall(/*is_native=*/false, shortcut_info_->display); } } // namespace banners
diff --git a/chrome/browser/banners/app_banner_ui_delegate_android.h b/chrome/browser/banners/app_banner_ui_delegate_android.h index fe87b13..3fede8c 100644 --- a/chrome/browser/banners/app_banner_ui_delegate_android.h +++ b/chrome/browser/banners/app_banner_ui_delegate_android.h
@@ -52,8 +52,7 @@ const base::string16& app_title, const base::android::ScopedJavaLocalRef<jobject>& native_app_data, const SkBitmap& icon, - const std::string& native_app_package_name, - const std::string& referrer); + const std::string& native_app_package_name); ~AppBannerUiDelegateAndroid(); @@ -61,16 +60,10 @@ base::android::ScopedJavaLocalRef<jobject> GetJavaObject(); const base::android::ScopedJavaLocalRef<jobject> GetNativeAppData() const; - int GetInstallState() const; const SkBitmap& GetPrimaryIcon() const; AppType GetType() const; const GURL& GetWebAppUrl() const; - // Creates the Java-side InstallerDelegate, passing |jobserver| to receive - // progress updates on the installation of a native app. - void CreateInstallerDelegate( - base::android::ScopedJavaLocalRef<jobject> jobserver); - // Called through the JNI to add the app described by this class to home // screen. void AddToHomescreen(JNIEnv* env, @@ -127,8 +120,7 @@ const base::string16& app_title, const base::android::ScopedJavaLocalRef<jobject>& native_app_data, const SkBitmap& icon, - const std::string& native_app_package_name, - const std::string& referrer); + const std::string& native_app_package_name); bool IsForNativeApp() const { return GetType() == AppType::NATIVE; } @@ -154,7 +146,6 @@ const SkBitmap badge_icon_; std::string package_name_; - std::string referrer_; AppType type_; WebappInstallSource install_source_;
diff --git a/chrome/browser/browsing_data/counters/sync_aware_counter_browsertest.cc b/chrome/browser/browsing_data/counters/sync_aware_counter_browsertest.cc index 00373a9..52901d8 100644 --- a/chrome/browser/browsing_data/counters/sync_aware_counter_browsertest.cc +++ b/chrome/browser/browsing_data/counters/sync_aware_counter_browsertest.cc
@@ -9,10 +9,8 @@ #include "chrome/browser/history/web_history_service_factory.h" #include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/unified_consent/unified_consent_service_factory.h" #include "chrome/browser/web_data_service_factory.h" #include "chrome/test/base/in_process_browser_test.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" @@ -25,7 +23,6 @@ #include "components/history/core/browser/web_history_service.h" #include "components/history/core/test/fake_web_history_service.h" #include "components/prefs/pref_service.h" -#include "components/unified_consent/unified_consent_service.h" #include "content/public/browser/browser_thread.h" using browsing_data::BrowsingDataCounter; @@ -119,20 +116,6 @@ WaitForCounting(); EXPECT_TRUE(IsSyncEnabled()); - // When the unified consent was given, it needs to be revoked here before - // the sync_everything flag can be set to false below. This restarts the - // counter. - unified_consent::UnifiedConsentService* consent_service = - UnifiedConsentServiceFactory::GetForProfile(profile); - if (consent_service && consent_service->IsUnifiedConsentGiven()) { - consent_service->SetUnifiedConsentGiven(false); - ASSERT_TRUE( - GetClient(kFirstProfileIndex) - ->AwaitSyncSetupCompletion(/*skip_passphrase_verification=*/false)); - WaitForCounting(); - ASSERT_TRUE(sync_service->GetActiveDataTypes().Has(syncer::AUTOFILL)); - } - // We stop syncing autofill in particular. This restarts the counter. syncer::ModelTypeSet everything_except_autofill = syncer::UserSelectableTypes(); @@ -198,21 +181,6 @@ WaitForCounting(); EXPECT_TRUE(IsSyncEnabled()); - // When the unified consent was given, it needs to be revoked here before - // the sync_everything flag can be set to false below. This restarts the - // counter. - unified_consent::UnifiedConsentService* consent_service = - UnifiedConsentServiceFactory::GetForProfile(profile); - if (consent_service && consent_service->IsUnifiedConsentGiven()) { - consent_service->SetUnifiedConsentGiven(false); - ASSERT_TRUE( - GetClient(kFirstProfileIndex) - ->AwaitSyncSetupCompletion(/*skip_passphrase_verification=*/false)); - WaitForCounting(); - ASSERT_TRUE(sync_service->GetUserSettings()->GetChosenDataTypes().Has( - syncer::PASSWORDS)); - } - // We stop syncing passwords in particular. This restarts the counter. syncer::ModelTypeSet everything_except_passwords = syncer::UserSelectableTypes(); @@ -287,21 +255,6 @@ WaitForCounting(); EXPECT_TRUE(IsSyncEnabled()); - // When the unified consent was given, it needs to be revoked here before - // the sync_everything flag can be set to false below. This restarts the - // counter. - unified_consent::UnifiedConsentService* consent_service = - UnifiedConsentServiceFactory::GetForProfile(profile); - if (consent_service && consent_service->IsUnifiedConsentGiven()) { - consent_service->SetUnifiedConsentGiven(false); - ASSERT_TRUE( - GetClient(kFirstProfileIndex) - ->AwaitSyncSetupCompletion(/*skip_passphrase_verification=*/false)); - WaitForCounting(); - ASSERT_TRUE(sync_service->GetActiveDataTypes().Has( - syncer::HISTORY_DELETE_DIRECTIVES)); - } - // We stop syncing history deletion in particular. This restarts the counter. syncer::ModelTypeSet everything_except_history = syncer::UserSelectableTypes();
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 5d7c4c7..a5cec46 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -3627,9 +3627,11 @@ ui_task_runner); #endif #if defined(OS_ANDROID) + Profile* profile = + Profile::FromBrowserContext(render_process_host->GetBrowserContext()); registry->AddInterface( base::BindRepeating(&android::AvailableOfflineContentProvider::Create, - render_process_host->GetBrowserContext()), + profile), base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI})); #endif
diff --git a/chrome/browser/chrome_navigation_browsertest.cc b/chrome/browser/chrome_navigation_browsertest.cc index 245987e4..3e80e31 100644 --- a/chrome/browser/chrome_navigation_browsertest.cc +++ b/chrome/browser/chrome_navigation_browsertest.cc
@@ -15,7 +15,6 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" @@ -112,13 +111,9 @@ // Test to verify that navigations are not deleting the transient // NavigationEntry when showing an interstitial page and the old renderer // process is trying to navigate. See https://crbug.com/600046. -// With committed interstitials, interstitials are no longer transient -// navigations, so this test does not apply. IN_PROC_BROWSER_TEST_F( ChromeNavigationBrowserTest, MAYBE_TransientEntryPreservedOnMultipleNavigationsDuringInterstitial) { - if (base::FeatureList::IsEnabled(features::kSSLCommittedInterstitials)) - return; StartServerWithExpiredCert(); GURL setup_url =
diff --git a/chrome/browser/chrome_site_per_process_browsertest.cc b/chrome/browser/chrome_site_per_process_browsertest.cc index 0c073f5..75fb89b 100644 --- a/chrome/browser/chrome_site_per_process_browsertest.cc +++ b/chrome/browser/chrome_site_per_process_browsertest.cc
@@ -6,7 +6,6 @@ #include <vector> #include "base/command_line.h" -#include "base/feature_list.h" #include "base/files/file_path.h" #include "base/macros.h" #include "base/path_service.h" @@ -20,7 +19,6 @@ #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/app_modal/javascript_app_modal_dialog.h" @@ -202,21 +200,14 @@ ui_test_utils::NavigateToURL(browser(), bad_cert_url); content::WebContents* active_web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + WaitForInterstitialAttach(active_web_contents); + EXPECT_TRUE(active_web_contents->ShowingInterstitialPage()); - content::RenderFrameHost* interstitial_frame_host; - - if (base::FeatureList::IsEnabled(features::kSSLCommittedInterstitials)) { - interstitial_frame_host = active_web_contents->GetMainFrame(); - } else { - WaitForInterstitialAttach(active_web_contents); - EXPECT_TRUE(active_web_contents->ShowingInterstitialPage()); - - // Here we check the device scale factor in use via the interstitial's - // RenderFrameHost; doing the check directly via the 'active web contents' - // does not give us the device scale factor for the interstitial. - interstitial_frame_host = - active_web_contents->GetInterstitialPage()->GetMainFrame(); - } + // Here we check the device scale factor in use via the interstitial's + // RenderFrameHost; doing the check directly via the 'active web contents' + // does not give us the device scale factor for the interstitial. + content::RenderFrameHost* interstitial_frame_host = + active_web_contents->GetInterstitialPage()->GetMainFrame(); EXPECT_EQ(SitePerProcessHighDPIExpiredCertBrowserTest::kDeviceScaleFactor, GetFrameDeviceScaleFactor(interstitial_frame_host));
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 31c04d7..cc14e36 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1503,8 +1503,12 @@ "policy/device_policy_remover.h", "policy/device_status_collector.cc", "policy/device_status_collector.h", + "policy/display_resolution_handler.cc", + "policy/display_resolution_handler.h", "policy/display_rotation_default_handler.cc", "policy/display_rotation_default_handler.h", + "policy/display_settings_handler.cc", + "policy/display_settings_handler.h", "policy/dm_token_storage.cc", "policy/dm_token_storage.h", "policy/enrollment_config.cc",
diff --git a/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.cc b/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.cc index 9058bc0..c33210fa 100644 --- a/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.cc +++ b/chrome/browser/chromeos/arc/accessibility/accessibility_node_info_data_wrapper.cc
@@ -359,6 +359,11 @@ out_data->AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true); } + if (GetProperty(AXBooleanProperty::SUPPORTS_TEXT_LOCATION)) { + out_data->AddBoolAttribute(ax::mojom::BoolAttribute::kSupportsTextLocation, + true); + } + // Range info. AXRangeInfoData* range_info = node_ptr_->range_info.get(); if (range_info) {
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc index bd1030f..be3fbdc 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc
@@ -486,6 +486,26 @@ action_data->action_type = arc::mojom::AccessibilityActionType::CLEAR_ACCESSIBILITY_FOCUS; break; + case ax::mojom::Action::kGetTextLocation: { + action_data->action_type = + arc::mojom::AccessibilityActionType::GET_TEXT_LOCATION; + action_data->start_index = data.start_index; + action_data->end_index = data.end_index; + + auto* instance = ARC_GET_INSTANCE_FOR_METHOD( + arc_bridge_service_->accessibility_helper(), RefreshWithExtraData); + if (!instance) { + OnActionResult(data, false); + return; + } + + instance->RefreshWithExtraData( + std::move(action_data), + base::BindOnce( + &ArcAccessibilityHelperBridge::OnGetTextLocationDataResult, + base::Unretained(this), data)); + return; + } default: return; } @@ -514,6 +534,17 @@ tree_source->NotifyActionResult(data, result); } +void ArcAccessibilityHelperBridge::OnGetTextLocationDataResult( + const ui::AXActionData& data, + const base::Optional<gfx::Rect>& result_rect) const { + AXTreeSourceArc* tree_source = GetFromTreeId(data.target_tree_id); + + if (!tree_source) + return; + + tree_source->NotifyGetTextLocationDataResult(data, result_rect); +} + void ArcAccessibilityHelperBridge::OnAccessibilityStatusChanged( const chromeos::AccessibilityStatusEventDetails& event_details) { // TODO(yawano): Add case for select to speak and switch access.
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h index 9b8f737..e7ef7f8 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h
@@ -27,6 +27,10 @@ class BrowserContext; } // namespace content +namespace gfx { +class Rect; +} // namespace gfx + namespace arc { class AXTreeSourceArc; @@ -113,6 +117,9 @@ aura::Window* lost_active) override; void OnActionResult(const ui::AXActionData& data, bool result) const; + void OnGetTextLocationDataResult( + const ui::AXActionData& data, + const base::Optional<gfx::Rect>& result_rect) const; void OnAccessibilityStatusChanged( const chromeos::AccessibilityStatusEventDetails& event_details);
diff --git a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc index 3859243..2a1e71b 100644 --- a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc +++ b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc
@@ -184,6 +184,13 @@ data, result); } +void AXTreeSourceArc::NotifyGetTextLocationDataResult( + const ui::AXActionData& data, + const base::Optional<gfx::Rect>& rect) { + extensions::AutomationEventRouter::GetInstance() + ->DispatchGetTextLocationDataResult(data, rect); +} + bool AXTreeSourceArc::GetTreeData(ui::AXTreeData* data) const { data->tree_id = tree_id(); if (focused_id_ >= 0) {
diff --git a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h index c3a9655..64ba87c 100644 --- a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h +++ b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h
@@ -52,6 +52,10 @@ // Notify automation of a result to an action. void NotifyActionResult(const ui::AXActionData& data, bool result); + // Notify automation of result to getTextLocation. + void NotifyGetTextLocationDataResult(const ui::AXActionData& data, + const base::Optional<gfx::Rect>& rect); + // Attaches tree to an aura window and gives it system focus. void Focus(aura::Window* window);
diff --git a/chrome/browser/chromeos/arc/arc_session_manager_browsertest.cc b/chrome/browser/chromeos/arc/arc_session_manager_browsertest.cc index 83405ecc..2551472 100644 --- a/chrome/browser/chromeos/arc/arc_session_manager_browsertest.cc +++ b/chrome/browser/chromeos/arc/arc_session_manager_browsertest.cc
@@ -26,10 +26,7 @@ #include "chrome/browser/policy/test/local_policy_test_server.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/account_tracker_service_factory.h" -#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h" -#include "chrome/browser/signin/fake_signin_manager_builder.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/testing_profile.h" #include "components/account_id/account_id.h" @@ -45,20 +42,18 @@ #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" #include "components/signin/core/browser/account_tracker_service.h" -#include "components/signin/core/browser/fake_profile_oauth2_token_service.h" -#include "components/signin/core/browser/signin_manager_base.h" #include "components/user_manager/scoped_user_manager.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/browser_thread.h" #include "net/base/upload_bytes_element_reader.h" #include "net/base/upload_data_stream.h" #include "net/url_request/url_request_test_job.h" +#include "services/identity/public/cpp/identity_test_environment.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" namespace { -constexpr char kRefreshToken[] = "fake-refresh-token"; // Set managed auth token for Android managed accounts. constexpr char kManagedAuthToken[] = "managed-auth-token"; // Set unmanaged auth token for other Android unmanaged accounts. @@ -147,25 +142,14 @@ TestingProfile::Builder profile_builder; profile_builder.SetPath(temp_dir_.GetPath().AppendASCII("TestArcProfile")); profile_builder.SetProfileName(kFakeUserName); - profile_builder.AddTestingFactory( - ProfileOAuth2TokenServiceFactory::GetInstance(), - base::BindRepeating(&BuildFakeProfileOAuth2TokenService)); - profile_builder.AddTestingFactory( - SigninManagerFactory::GetInstance(), - base::BindRepeating(&BuildFakeSigninManagerForTesting)); - profile_ = profile_builder.Build(); + profile_ = IdentityTestEnvironmentProfileAdaptor:: + CreateProfileForIdentityTestEnvironment(profile_builder); + + identity_test_environment_adaptor_ = + std::make_unique<IdentityTestEnvironmentProfileAdaptor>(profile_.get()); // Seed account info properly. - const std::string account_id_str = - AccountTrackerServiceFactory::GetForProfile(profile_.get()) - ->SeedAccountInfo(kFakeGaiaId, kFakeUserName); - token_service_ = static_cast<FakeProfileOAuth2TokenService*>( - ProfileOAuth2TokenServiceFactory::GetForProfile(profile())); - FakeSigninManagerForTesting* fake_signin_manager = - static_cast<FakeSigninManagerForTesting*>( - SigninManagerFactory::GetForProfile(profile())); - fake_signin_manager->SignIn(account_id_str); - token_service_->UpdateCredentials(account_id_str, kRefreshToken); + identity_test_env()->MakePrimaryAccountAvailable(kFakeUserName); profile()->GetPrefs()->SetBoolean(prefs::kArcSignedIn, true); profile()->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true); @@ -195,6 +179,7 @@ // instance in fixture, once), but it should be no op. // TODO(hidehiko): Think about a way to test the code cleanly. ArcServiceLauncher::Get()->Shutdown(); + identity_test_environment_adaptor_.reset(); profile_.reset(); base::RunLoop().RunUntilIdle(); user_manager_enabler_.reset(); @@ -219,22 +204,25 @@ Profile* profile() { return profile_.get(); } - FakeProfileOAuth2TokenService* token_service() { return token_service_; } + identity::IdentityTestEnvironment* identity_test_env() { + return identity_test_environment_adaptor_->identity_test_env(); + } private: std::unique_ptr<policy::LocalPolicyTestServer> test_server_; std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_; + std::unique_ptr<IdentityTestEnvironmentProfileAdaptor> + identity_test_environment_adaptor_; base::ScopedTempDir temp_dir_; std::unique_ptr<TestingProfile> profile_; - FakeProfileOAuth2TokenService* token_service_; DISALLOW_COPY_AND_ASSIGN(ArcSessionManagerTest); }; IN_PROC_BROWSER_TEST_F(ArcSessionManagerTest, ConsumerAccount) { EnableArc(); - token_service()->IssueTokenForAllPendingRequests(kUnmanagedAuthToken, - base::Time::Max()); + identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( + kUnmanagedAuthToken, base::Time::Max()); ASSERT_EQ(ArcSessionManager::State::ACTIVE, ArcSessionManager::Get()->state()); } @@ -258,8 +246,8 @@ IN_PROC_BROWSER_TEST_F(ArcSessionManagerTest, ManagedAndroidAccount) { EnableArc(); - token_service()->IssueTokenForAllPendingRequests(kManagedAuthToken, - base::Time::Max()); + identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( + kManagedAuthToken, base::Time::Max()); ArcPlayStoreDisabledWaiter().Wait(); EXPECT_FALSE(IsArcPlayStoreEnabledForProfile(profile())); }
diff --git a/chrome/browser/chromeos/arc/arc_util_unittest.cc b/chrome/browser/chromeos/arc/arc_util_unittest.cc index 7813825..50da92c 100644 --- a/chrome/browser/chromeos/arc/arc_util_unittest.cc +++ b/chrome/browser/chromeos/arc/arc_util_unittest.cc
@@ -11,6 +11,7 @@ #include "base/system/sys_info.h" #include "base/test/icu_test_util.h" #include "base/test/scoped_command_line.h" +#include "base/test/scoped_feature_list.h" #include "base/values.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/arc/arc_session_manager.h" @@ -837,9 +838,11 @@ } TEST_F(ChromeArcUtilTest, ArcStartModeDefaultDemoModeWithPlayStore) { + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeatureState(chromeos::switches::kShowPlayInDemoMode, + true /* enabled */); auto* command_line = base::CommandLine::ForCurrentProcess(); - command_line->InitFromArgv( - {"", "--arc-availability=installed", "--show-play-in-demo-mode"}); + command_line->InitFromArgv({"", "--arc-availability=installed"}); chromeos::DemoSession::SetDemoConfigForTesting( chromeos::DemoSession::DemoModeConfig::kOnline); ScopedLogIn login(GetFakeUserManager(),
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc index 808f6d1..4a9099f 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
@@ -809,9 +809,13 @@ base::OnceCallback<void(std::unique_ptr<base::ListValue>)> callback) { drive::DriveIntegrationService* const integration_service = drive::util::GetIntegrationServiceByProfile(function->GetProfile()); + auto on_response = base::BindOnce(&OnSearchDriveFs, std::move(function), + filter_dirs, std::move(callback)); return integration_service->GetDriveFsHost()->PerformSearch( - std::move(query), base::BindOnce(&OnSearchDriveFs, std::move(function), - filter_dirs, std::move(callback))); + std::move(query), + mojo::WrapCallbackWithDefaultInvokeIfNotRun( + std::move(on_response), drive::FileError::FILE_ERROR_ABORT, + base::Optional<std::vector<drivefs::mojom::QueryItemPtr>>())); } void UmaEmitSearchOutcome(
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc index f51991b..f342a8a 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
@@ -8,7 +8,6 @@ #include <utility> #include "base/strings/stringprintf.h" -#include "base/system/sys_info.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/file_manager/open_with_browser.h" #include "chrome/browser/chromeos/login/demo_mode/demo_session.h" @@ -166,8 +165,6 @@ SET_STRING("DRIVE_WELCOME_TITLE", IDS_FILE_BROWSER_DRIVE_WELCOME_TITLE); SET_STRING("DRIVE_WELCOME_TITLE_ALTERNATIVE", IDS_FILE_BROWSER_DRIVE_WELCOME_TITLE_ALTERNATIVE); - SET_STRING("DRIVE_WELCOME_TITLE_ALTERNATIVE_1TB", - IDS_FILE_BROWSER_DRIVE_WELCOME_TITLE_ALTERNATIVE_1TB); SET_STRING("SYNC_DELETE_WITHOUT_PERMISSION_ERROR", IDS_FILE_BROWSER_SYNC_DELETE_WITHOUT_PERMISSION_ERROR); SET_STRING("SYNC_FILE_NAME", IDS_FILE_BROWSER_SYNC_FILE_NAME); @@ -852,8 +849,6 @@ dict->SetBoolean( "MY_FILES_VOLUME_ENABLED", base::FeatureList::IsEnabled(chromeos::features::kMyFilesVolume)); - dict->SetString("CHROMEOS_RELEASE_BOARD", - base::SysInfo::GetLsbReleaseBoard()); dict->SetString( "DOWNLOADS_LOW_SPACE_WARNING_HELP_URL", base::StringPrintf(kHelpURLFormat, kDownloadsLowSpaceWarningHelpNumber));
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index e34a1e1..d9c9878 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -556,7 +556,8 @@ TestCase("shareHostedFileTeamDrive"), TestCase("manageHostedFileTeamDrive"), TestCase("manageFileTeamDrive"), - TestCase("manageDirectoryTeamDrive"))); + TestCase("manageDirectoryTeamDrive"), + TestCase("manageTeamDrive"))); WRAPPED_INSTANTIATE_TEST_CASE_P( SuggestAppDialog, /* suggest_app_dialog.js */ @@ -697,7 +698,8 @@ TestCase("showSelectAllInCurrentFolder"), TestCase("showToggleHiddenAndroidFoldersGearMenuItemsInMyFiles"), TestCase("enableToggleHiddenAndroidFoldersShowsHiddenFiles"), - TestCase("hideCurrentDirectoryByTogglingHiddenAndroidFolders"))); + TestCase("hideCurrentDirectoryByTogglingHiddenAndroidFolders"), + TestCase("newFolderInDownloads"))); WRAPPED_INSTANTIATE_TEST_CASE_P( Crostini, /* crostini.js */ @@ -709,8 +711,10 @@ MyFiles, /* my_files.js */ FilesAppBrowserTest, ::testing::Values( + // search should only be disabled if MyFiles isn't a volume. TestCase("hideSearchButton"), TestCase("directoryTreeRefresh"), + TestCase("directoryTreeRefresh").EnableMyFilesVolume(), TestCase("showMyFiles"), TestCase("showMyFiles").EnableMyFilesVolume(), TestCase("myFilesDisplaysAndOpensEntries"),
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc index 0a424551..681c27a88 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -983,21 +983,11 @@ const base::FilePath target_path = GetTargetPathForTestEntry(entry); entries_.insert(std::make_pair(target_path, entry)); - fake_drivefs_helper_->fake_drivefs().SetMetadata( - GetRelativeDrivePathForTestEntry(entry), entry.mime_type, - base::FilePath(entry.target_path).BaseName().value(), entry.pinned, - entry.shared_option == AddEntriesMessage::SharedOption::SHARED || - entry.shared_option == - AddEntriesMessage::SharedOption::SHARED_WITH_ME, - {entry.capabilities.can_share, entry.capabilities.can_copy, - entry.capabilities.can_delete, entry.capabilities.can_rename, - entry.capabilities.can_add_children}, - {entry.folder_feature.is_machine_root, - entry.folder_feature.is_arbitrary_sync_folder, - entry.folder_feature.is_external_media}); - + auto relative_path = GetRelativeDrivePathForTestEntry(entry); + auto original_name = relative_path.BaseName(); switch (entry.type) { case AddEntriesMessage::FILE: { + original_name = base::FilePath(entry.target_path).BaseName(); if (entry.source_file_name.empty()) { ASSERT_EQ(0, base::WriteFile(target_path, "", 0)); break; @@ -1023,6 +1013,17 @@ << "Failed to create a computer: " << target_path.value(); break; } + fake_drivefs_helper_->fake_drivefs().SetMetadata( + relative_path, entry.mime_type, original_name.value(), entry.pinned, + entry.shared_option == AddEntriesMessage::SharedOption::SHARED || + entry.shared_option == + AddEntriesMessage::SharedOption::SHARED_WITH_ME, + {entry.capabilities.can_share, entry.capabilities.can_copy, + entry.capabilities.can_delete, entry.capabilities.can_rename, + entry.capabilities.can_add_children}, + {entry.folder_feature.is_machine_root, + entry.folder_feature.is_arbitrary_sync_folder, + entry.folder_feature.is_external_media}); ASSERT_TRUE(UpdateModifiedTime(entry)); }
diff --git a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc index 46d18d05..8663700 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc
@@ -124,8 +124,7 @@ } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, MetadataCacheItem) { - RunTest(base::FilePath(FILE_PATH_LITERAL( - "foreground/js/metadata/metadata_cache_item_unittest.html"))); + RunGeneratedTest("/foreground/js/metadata/metadata_cache_item_unittest.html"); } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, MetadataCacheSet) { @@ -164,8 +163,7 @@ } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ThumbnailModel) { - RunTest(base::FilePath(FILE_PATH_LITERAL( - "foreground/js/metadata/thumbnail_model_unittest.html"))); + RunGeneratedTest("/foreground/js/metadata/thumbnail_model_unittest.html"); } IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ExifParser) {
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader_unittest.cc b/chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader_unittest.cc index fe6256b..45b4750c 100644 --- a/chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader_unittest.cc +++ b/chrome/browser/chromeos/login/demo_mode/demo_extensions_external_loader_unittest.cc
@@ -22,6 +22,7 @@ #include "base/run_loop.h" #include "base/values.h" #include "base/version.h" +#include "build/build_config.h" #include "chrome/browser/chromeos/login/demo_mode/demo_mode_test_helper.h" #include "chrome/browser/chromeos/login/demo_mode/demo_session.h" #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" @@ -440,6 +441,11 @@ EXPECT_TRUE(external_provider_visitor_.loaded_crx_files().empty()); } +#if defined(OS_LINUX) +#define MAYBE_LoadApp DISABLED_LoadApp +#else +#define MAYBE_LoadApp LoadApp +#endif TEST_F(DemoExtensionsExternalLoaderTest, LoadApp) { demo_mode_test_helper_->InitializeSession();
diff --git a/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc b/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc index 05cf5b9..b7a9ce15c 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc +++ b/chrome/browser/chromeos/login/lock/screen_locker_browsertest.cc
@@ -6,42 +6,30 @@ #include <memory> -#include "ash/public/cpp/ash_switches.h" #include "ash/wm/window_state.h" #include "base/command_line.h" #include "base/macros.h" #include "base/run_loop.h" #include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/chromeos/login/lock/screen_locker.h" #include "chrome/browser/chromeos/login/lock/screen_locker_tester.h" #include "chrome/browser/chromeos/login/ui/user_adding_screen.h" -#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "chromeos/chromeos_switches.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/fake_session_manager_client.h" #include "chromeos/login/auth/key.h" -#include "chromeos/login/auth/stub_authenticator.h" #include "chromeos/login/auth/user_context.h" #include "components/session_manager/core/session_manager.h" #include "components/user_manager/user_names.h" #include "content/public/browser/notification_service.h" #include "content/public/test/test_utils.h" -#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/test/ui_controls.h" #include "ui/base/ui_base_features.h" -#include "ui/compositor/layer_animator.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" -#include "ui/views/widget/widget.h" - -using testing::_; -using testing::AnyNumber; -using testing::Return; namespace chromeos { namespace { @@ -77,7 +65,7 @@ run_loop.Run(); } // Make sure all pending tasks are executed. - content::RunAllPendingInMessageLoop(); + base::RunLoop().RunUntilIdle(); } private: @@ -93,10 +81,8 @@ class ScreenLockerTest : public InProcessBrowserTest { public: - ScreenLockerTest() : fake_session_manager_client_(NULL) {} - - protected: - FakeSessionManagerClient* fake_session_manager_client_; + ScreenLockerTest() = default; + ~ScreenLockerTest() override = default; void LockScreen(ScreenLockerTester* tester) { ScreenLocker::Show(); @@ -106,19 +92,19 @@ if (!tester->IsLocked()) lock_state_observer.Wait(); EXPECT_TRUE(tester->IsLocked()); + EXPECT_EQ(session_manager::SessionState::LOCKED, + session_manager::SessionManager::Get()->session_state()); } - // Verifies if LockScreenDismissed() was called once. - bool VerifyLockScreenDismissed() { - return 1 == fake_session_manager_client_ - ->notify_lock_screen_dismissed_call_count(); + FakeSessionManagerClient* session_manager_client() { + return fake_session_manager_client_; } + // InProcessBrowserTest: void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitchASCII(switches::kLoginProfile, "user"); } - private: void SetUpInProcessBrowserTestFixture() override { fake_session_manager_client_ = new FakeSessionManagerClient; DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( @@ -128,36 +114,17 @@ ui::ScopedAnimationDurationScaleMode::ZERO_DURATION)); } + private: + FakeSessionManagerClient* fake_session_manager_client_ = nullptr; std::unique_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_mode_; DISALLOW_COPY_AND_ASSIGN(ScreenLockerTest); }; -class WebUiScreenLockerTest : public ScreenLockerTest { - public: - WebUiScreenLockerTest() = default; - ~WebUiScreenLockerTest() override = default; - - void SetUpCommandLine(base::CommandLine* command_line) override { - ScreenLockerTest::SetUpCommandLine(command_line); - command_line->AppendSwitch(ash::switches::kShowWebUiLock); - } - - private: - DISALLOW_COPY_AND_ASSIGN(WebUiScreenLockerTest); -}; - -IN_PROC_BROWSER_TEST_F(ScreenLockerTest, TestBasic) { +IN_PROC_BROWSER_TEST_F(ScreenLockerTest, TestBadThenGoodPassword) { // Show lock screen and wait until it is shown. std::unique_ptr<ScreenLockerTester> tester = ScreenLockerTester::Create(); - content::WindowedNotificationObserver lock_state_observer( - chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, - content::NotificationService::AllSources()); - ScreenLocker::Show(); - if (!tester->IsLocked()) - lock_state_observer.Wait(); - EXPECT_EQ(session_manager::SessionState::LOCKED, - session_manager::SessionManager::Get()->session_state()); + LockScreen(tester.get()); // Inject fake authentication credentials. UserContext user_context(user_manager::UserType::USER_TYPE_REGULAR, @@ -176,66 +143,23 @@ tester->EnterPassword(user_manager::StubAccountId(), "pass"); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(tester->IsLocked()); - EXPECT_EQ( - 1, fake_session_manager_client_->notify_lock_screen_shown_call_count()); + EXPECT_EQ(1, session_manager_client()->notify_lock_screen_shown_call_count()); EXPECT_EQ(session_manager::SessionState::ACTIVE, session_manager::SessionManager::Get()->session_state()); - EXPECT_TRUE(VerifyLockScreenDismissed()); -} - -IN_PROC_BROWSER_TEST_F(WebUiScreenLockerTest, TestBasic) { - // WebUiScreenLockerTest fails with Mash because of unexpected window - // structure. Fortunately we will deprecate the WebUI-based screen locker - // soon, so it is okay to skip it. See https://crbug.com/888779 - if (features::IsUsingWindowService()) - return; - ScreenLocker::Show(); - std::unique_ptr<ScreenLockerTester> tester = ScreenLockerTester::Create(); - content::WindowedNotificationObserver lock_state_observer( - chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, - content::NotificationService::AllSources()); - if (!tester->IsLocked()) - lock_state_observer.Wait(); - EXPECT_EQ(session_manager::SessionState::LOCKED, - session_manager::SessionManager::Get()->session_state()); - - UserContext user_context(user_manager::UserType::USER_TYPE_REGULAR, - user_manager::StubAccountId()); - user_context.SetKey(Key("pass")); - tester->InjectStubUserContext(user_context); - EXPECT_TRUE(tester->IsLocked()); - tester->EnterPassword(user_manager::StubAccountId(), "fail"); - content::RunAllPendingInMessageLoop(); - EXPECT_TRUE(tester->IsLocked()); - tester->EnterPassword(user_manager::StubAccountId(), "pass"); - content::RunAllPendingInMessageLoop(); - // Successful authentication clears the lock screen and tells the - // SessionManager to announce this over DBus. - EXPECT_FALSE(tester->IsLocked()); EXPECT_EQ( - 1, fake_session_manager_client_->notify_lock_screen_shown_call_count()); - EXPECT_EQ(session_manager::SessionState::ACTIVE, - session_manager::SessionManager::Get()->session_state()); - - EXPECT_TRUE(VerifyLockScreenDismissed()); + 1, session_manager_client()->notify_lock_screen_dismissed_call_count()); } // Makes sure Chrome doesn't crash if we lock the screen during an add-user // flow. Regression test for crbug.com/467111. IN_PROC_BROWSER_TEST_F(ScreenLockerTest, LockScreenWhileAddingUser) { UserAddingScreen::Get()->Start(); - content::RunAllPendingInMessageLoop(); + base::RunLoop().RunUntilIdle(); ScreenLocker::HandleShowLockScreenRequest(); } -// Flaky on Linux Chromium OS ASan LSan (https://crbug.com/889782) -#if defined(ADDRESS_SANITIZER) -#define MAYBE_TestFullscreenExit DISABLED_TestFullscreenExit -#else -#define MAYBE_TestFullscreenExit TestFullscreenExit -#endif // Test how locking the screen affects an active fullscreen window. -IN_PROC_BROWSER_TEST_F(WebUiScreenLockerTest, MAYBE_TestFullscreenExit) { +IN_PROC_BROWSER_TEST_F(ScreenLockerTest, TestFullscreenExit) { // WebUiScreenLockerTest fails with Mash because of unexpected window // structure. Fortunately we will deprecate the WebUI-based screen locker // soon, so it is okay to skip it. See https://crbug.com/888779 @@ -273,7 +197,7 @@ user_context.SetKey(Key("pass")); tester->InjectStubUserContext(user_context); tester->EnterPassword(user_manager::StubAccountId(), "pass"); - content::RunAllPendingInMessageLoop(); + base::RunLoop().RunUntilIdle(); EXPECT_FALSE(tester->IsLocked()); { Waiter waiter(browser()); @@ -314,14 +238,12 @@ } tester->EnterPassword(user_manager::StubAccountId(), "pass"); - content::RunAllPendingInMessageLoop(); + base::RunLoop().RunUntilIdle(); EXPECT_FALSE(tester->IsLocked()); + EXPECT_EQ(2, session_manager_client()->notify_lock_screen_shown_call_count()); EXPECT_EQ( - 2, fake_session_manager_client_->notify_lock_screen_shown_call_count()); - EXPECT_EQ( - 2, - fake_session_manager_client_->notify_lock_screen_dismissed_call_count()); + 2, session_manager_client()->notify_lock_screen_dismissed_call_count()); } IN_PROC_BROWSER_TEST_F(ScreenLockerTest, TestShowTwice) { @@ -331,14 +253,14 @@ // Calling Show again simply send LockCompleted signal. ScreenLocker::Show(); EXPECT_TRUE(tester->IsLocked()); - EXPECT_EQ( - 2, fake_session_manager_client_->notify_lock_screen_shown_call_count()); + EXPECT_EQ(2, session_manager_client()->notify_lock_screen_shown_call_count()); // Close the locker to match expectations. ScreenLocker::Hide(); - content::RunAllPendingInMessageLoop(); + base::RunLoop().RunUntilIdle(); EXPECT_FALSE(tester->IsLocked()); - EXPECT_TRUE(VerifyLockScreenDismissed()); + EXPECT_EQ( + 1, session_manager_client()->notify_lock_screen_dismissed_call_count()); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc index 8f26b526..200db3f 100644 --- a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc +++ b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
@@ -849,10 +849,21 @@ if (policy.has_display_rotation_default()) { const em::DisplayRotationDefaultProto& container( policy.display_rotation_default()); - policies->Set(key::kDisplayRotationDefault, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, - DecodeIntegerValue(container.display_rotation_default()), - nullptr); + if (container.has_display_rotation_default()) { + policies->Set(key::kDisplayRotationDefault, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, + DecodeIntegerValue(container.display_rotation_default()), + nullptr); + } + } + + if (policy.has_device_display_resolution()) { + const em::DeviceDisplayResolutionProto& container( + policy.device_display_resolution()); + if (container.has_device_display_resolution()) { + SetJsonDevicePolicy(key::kDeviceDisplayResolution, + container.device_display_resolution(), policies); + } } if (policy.has_usb_detachable_whitelist()) {
diff --git a/chrome/browser/chromeos/policy/display_resolution_handler.cc b/chrome/browser/chromeos/policy/display_resolution_handler.cc new file mode 100644 index 0000000..0fd78c3b --- /dev/null +++ b/chrome/browser/chromeos/policy/display_resolution_handler.cc
@@ -0,0 +1,244 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/policy/display_resolution_handler.h" + +#include <utility> +#include <vector> + +#include "base/optional.h" +#include "base/values.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" +#include "chromeos/settings/cros_settings_names.h" +#include "mojo/public/cpp/bindings/struct_traits.h" + +namespace policy { + +using DisplayUnitTraits = + mojo::StructTraits<::ash::mojom::DisplayUnitInfo::DataView, + ::ash::mojom::DisplayUnitInfoPtr>; + +struct DisplayResolutionHandler::InternalDisplaySettings { + int scale_percentage = 0; + + explicit InternalDisplaySettings(int scale_percentage) + : scale_percentage(scale_percentage) {} + + bool operator==(const InternalDisplaySettings& rhs) const { + return scale_percentage == rhs.scale_percentage; + } + + bool operator!=(const InternalDisplaySettings& rhs) const { + return !(*this == rhs); + } + + // Create display config for the internal display using policy settings from + // |internal_display_settings_|. + ash::mojom::DisplayConfigPropertiesPtr ToDisplayConfigProperties() { + auto new_config = ash::mojom::DisplayConfigProperties::New(); + // Converting percentage to factor. + new_config->display_zoom_factor = scale_percentage / 100.0; + return new_config; + } + + // Get settings for the internal display from + // |chromeos::kDeviceDisplayResolution| setting value. + static std::unique_ptr<InternalDisplaySettings> FromPolicySetting( + const base::DictionaryValue* pref) { + const base::Value* scale_value = + pref->FindKeyOfType(chromeos::kDeviceDisplayResolutionKeyInternalScale, + base::Value::Type::INTEGER); + return scale_value ? std::make_unique<InternalDisplaySettings>( + scale_value->GetInt()) + : nullptr; + } +}; + +struct DisplayResolutionHandler::ExternalDisplaySettings { + bool use_native = false; + int width = 0; + int height = 0; + base::Optional<int> scale_percentage = base::nullopt; + + bool operator==(const ExternalDisplaySettings& rhs) const { + return use_native == rhs.use_native && width == rhs.width && + height == rhs.height && scale_percentage == rhs.scale_percentage; + } + + bool operator!=(const ExternalDisplaySettings& rhs) const { + return !(*this == rhs); + } + + // Check if either |use_native| flag is set and mode is native or the mode + // has required resolution. + bool IsSuitableDisplayMode(const ash::mojom::DisplayModePtr& mode) { + return (use_native && mode->is_native) || + (!use_native && width == mode->size.width() && + height == mode->size.height()); + } + + // Create display config for the external display using policy settings from + // |external_display_settings_|. + ash::mojom::DisplayConfigPropertiesPtr ToDisplayConfigProperties( + const std::vector<ash::mojom::DisplayModePtr>& display_modes) { + bool found_suitable_mode = false; + auto new_config = ash::mojom::DisplayConfigProperties::New(); + for (const ash::mojom::DisplayModePtr& mode : display_modes) { + // Check if the current display mode has required resolution and its + // refresh rate is higher than refresh rate of the already found mode. + if (IsSuitableDisplayMode(mode) && + (!found_suitable_mode || + mode->refresh_rate > new_config->display_mode->refresh_rate)) { + new_config->display_mode = mode->Clone(); + found_suitable_mode = true; + } + } + // If we couldn't find the required mode and and scale percentage doesn't + // need to be changed, we have nothing to do. + if (!found_suitable_mode && !scale_percentage) { + return ash::mojom::DisplayConfigPropertiesPtr(); + } + + if (scale_percentage) { + // Converting percentage to the factor. + new_config->display_zoom_factor = *scale_percentage / 100.0; + } + + return new_config; + } + + // Get settings for the external displays from + // |chromeos::kDeviceDisplayResolution| setting value; + static std::unique_ptr<ExternalDisplaySettings> FromPolicySetting( + const base::DictionaryValue* pref) { + const base::Value* width_value = + pref->FindKeyOfType(chromeos::kDeviceDisplayResolutionKeyExternalWidth, + base::Value::Type::INTEGER); + const base::Value* height_value = + pref->FindKeyOfType(chromeos::kDeviceDisplayResolutionKeyExternalHeight, + base::Value::Type::INTEGER); + const base::Value* scale_value = + pref->FindKeyOfType(chromeos::kDeviceDisplayResolutionKeyExternalScale, + base::Value::Type::INTEGER); + const base::Value* use_native_value = pref->FindKeyOfType( + chromeos::kDeviceDisplayResolutionKeyExternalUseNative, + base::Value::Type::BOOLEAN); + + auto result = std::make_unique<ExternalDisplaySettings>(); + + // Scale can be used for both native and non-native modes + if (scale_value) + result->scale_percentage = scale_value->GetInt(); + + if (use_native_value && use_native_value->GetBool()) { + result->use_native = true; + return result; + } + + if (width_value && height_value) { + result->width = width_value->GetInt(); + result->height = height_value->GetInt(); + return result; + } + + return nullptr; + } +}; + +DisplayResolutionHandler::DisplayResolutionHandler() = default; + +DisplayResolutionHandler::~DisplayResolutionHandler() = default; + +const char* DisplayResolutionHandler::SettingName() { + return chromeos::kDeviceDisplayResolution; +} + +// Reads |chromeos::kDeviceDisplayResolution| from CrosSettings and stores +// the settings in |recommended_|, |external_display_settings_| and +// |internal_display_settings_|. Also updates |policy_enabled_| flag. +void DisplayResolutionHandler::OnSettingUpdate() { + policy_enabled_ = false; + const base::DictionaryValue* resolution_pref = nullptr; + chromeos::CrosSettings::Get()->GetDictionary( + chromeos::kDeviceDisplayResolution, &resolution_pref); + if (!resolution_pref) + return; + + std::unique_ptr<ExternalDisplaySettings> new_external_config = + ExternalDisplaySettings::FromPolicySetting(resolution_pref); + std::unique_ptr<InternalDisplaySettings> new_internal_config = + InternalDisplaySettings::FromPolicySetting(resolution_pref); + + bool new_recommended = false; + policy_enabled_ = new_external_config || new_internal_config; + const base::Value* recommended_value = resolution_pref->FindKeyOfType( + chromeos::kDeviceDisplayResolutionKeyRecommended, + base::Value::Type::BOOLEAN); + + if (recommended_value) + new_recommended = recommended_value->GetBool(); + + // We should reset locally stored settings and clear list of already updated + // displays if any of the policy values were updated. + bool should_reset_settings = false; + should_reset_settings |= !new_external_config || + !external_display_settings_ || + *new_external_config != *external_display_settings_; + should_reset_settings |= !new_internal_config || + !internal_display_settings_ || + *new_internal_config != *internal_display_settings_; + should_reset_settings |= recommended_ != new_recommended; + + if (!should_reset_settings) + return; + + resized_display_ids_.clear(); + external_display_settings_ = std::move(new_external_config); + internal_display_settings_ = std::move(new_internal_config); + recommended_ = new_recommended; +} + +// Applies settings received with |OnSettingUpdate| to each supported display +// from |info_list| if |policy_enabled_| is true. +void DisplayResolutionHandler::ApplyChanges( + ash::mojom::CrosDisplayConfigController* cros_display_config, + const std::vector<ash::mojom::DisplayUnitInfoPtr>& info_list) { + if (!policy_enabled_) + return; + for (const ash::mojom::DisplayUnitInfoPtr& display_unit_info : info_list) { + std::string display_id = display_unit_info->id; + // If policy value is marked as "recommended" we need to change the + // resolution just once for each display. So we're just skipping the display + // if it was resized since last settings update. + if (recommended_ && + resized_display_ids_.find(display_id) != resized_display_ids_.end()) { + continue; + } + + ash::mojom::DisplayConfigPropertiesPtr new_config; + if (display_unit_info->is_internal && internal_display_settings_) { + new_config = internal_display_settings_->ToDisplayConfigProperties(); + } else if (!display_unit_info->is_internal && external_display_settings_) { + new_config = external_display_settings_->ToDisplayConfigProperties( + DisplayUnitTraits::available_display_modes(display_unit_info)); + } + + if (!new_config) + continue; + + resized_display_ids_.insert(display_id); + cros_display_config->SetDisplayProperties( + display_unit_info->id, std::move(new_config), + base::BindOnce([](ash::mojom::DisplayConfigResult result) { + if (result == ash::mojom::DisplayConfigResult::kSuccess) { + VLOG(1) << "Successfully changed display mode."; + } else { + LOG(ERROR) << "Couldn't change display mode. Error code: " + << result; + } + })); + } +} + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/display_resolution_handler.h b/chrome/browser/chromeos/policy/display_resolution_handler.h new file mode 100644 index 0000000..d212f38 --- /dev/null +++ b/chrome/browser/chromeos/policy/display_resolution_handler.h
@@ -0,0 +1,61 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DISPLAY_RESOLUTION_HANDLER_H_ +#define CHROME_BROWSER_CHROMEOS_POLICY_DISPLAY_RESOLUTION_HANDLER_H_ + +#include <memory> +#include <set> +#include <string> +#include <vector> + +#include "ash/public/interfaces/cros_display_config.mojom.h" +#include "chrome/browser/chromeos/policy/display_settings_handler.h" + +namespace policy { + +// Implements DeviceDisplayResolution device policy. +// +// Whenever there is a change in the display configration, any new display will +// be resized according to the policy (only if the policy is enabled and the +// display supports specified resolution and scale factor). +// +// Whenever there is a change in |kDeviceDisplayResolution| setting from +// CrosSettings, the new policy is reapplied to all displays. +// +// If the specified resolution or scale factor is not supported by some display, +// the resolution won't change. +// +// Once resolution or scale factor for some display was set by this policy it +// won't be reapplied until next reboot or policy change (i.e. user can manually +// override the settings for that display via settings page). +class DisplayResolutionHandler : public DisplaySettingsPolicyHandler { + public: + DisplayResolutionHandler(); + + ~DisplayResolutionHandler() override; + + // DisplaySettingsPolicyHandler + const char* SettingName() override; + void OnSettingUpdate() override; + void ApplyChanges( + ash::mojom::CrosDisplayConfigController* cros_display_config, + const std::vector<ash::mojom::DisplayUnitInfoPtr>& info_list) override; + + private: + struct InternalDisplaySettings; + struct ExternalDisplaySettings; + + bool policy_enabled_ = false; + bool recommended_ = false; + std::unique_ptr<ExternalDisplaySettings> external_display_settings_; + std::unique_ptr<InternalDisplaySettings> internal_display_settings_; + std::set<std::string> resized_display_ids_; + + DISALLOW_COPY_AND_ASSIGN(DisplayResolutionHandler); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_CHROMEOS_POLICY_DISPLAY_RESOLUTION_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/display_resolution_handler_browsertest.cc b/chrome/browser/chromeos/policy/display_resolution_handler_browsertest.cc new file mode 100644 index 0000000..2525b0d --- /dev/null +++ b/chrome/browser/chromeos/policy/display_resolution_handler_browsertest.cc
@@ -0,0 +1,578 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> + +#include "ash/display/display_configuration_controller.h" +#include "ash/shell.h" +#include "base/bind.h" +#include "base/command_line.h" +#include "base/location.h" +#include "base/macros.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "chrome/browser/chromeos/login/ui/login_display_host.h" +#include "chrome/browser/chromeos/policy/device_policy_builder.h" +#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" +#include "chrome/browser/lifetime/application_lifetime.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chromeos/chromeos_switches.h" +#include "chromeos/dbus/cryptohome_client.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/fake_cryptohome_client.h" +#include "chromeos/dbus/fake_session_manager_client.h" +#include "chromeos/dbus/session_manager_client.h" +#include "chromeos/settings/cros_settings_names.h" +#include "components/policy/proto/chrome_device_policy.pb.h" +#include "extensions/browser/api/system_display/display_info_provider.h" +#include "extensions/common/api/system_display.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/display/display.h" +#include "ui/display/display_layout.h" +#include "ui/display/display_switches.h" +#include "ui/display/manager/display_manager.h" + +namespace em = enterprise_management; + +namespace { + +struct PolicyValue { + base::Optional<int> external_width; + base::Optional<int> external_height; + base::Optional<int> external_scale_percentage; + bool use_native = false; + base::Optional<int> internal_scale_percentage; + + bool operator==(const PolicyValue& rhs) const { + return external_width == rhs.external_width && + external_height == rhs.external_height && + external_scale_percentage == rhs.external_scale_percentage && + use_native == rhs.use_native && + internal_scale_percentage == rhs.internal_scale_percentage; + } + + gfx::Size external_display_size() const { + return gfx::Size(external_width.value_or(0), external_height.value_or(0)); + } +}; + +const gfx::Size kDefaultDisplayResolution(1280, 800); +const gfx::Size kDefaultExternalDisplayResolution(1920, 1080); +const int kDefaultDisplayScale = 100; + +display::DisplayManager* GetDisplayManager() { + return ash::Shell::Get()->display_manager(); +} + +int64_t GetInternalDisplayId() { + const display::DisplayManager* const display_manager = GetDisplayManager(); + return display_manager->first_display_id(); +} + +gfx::Size GetResolution(int64_t display_id) { + const display::DisplayManager* const display_manager = GetDisplayManager(); + display::ManagedDisplayMode display_mode; + if (display_manager->GetSelectedModeForDisplayId(display_id, &display_mode)) { + return display_mode.size(); + } + const display::Display& display = + display_manager->GetDisplayForId(display_id); + return display.GetSizeInPixel(); +} + +double GetScale(int64_t display_id) { + const display::DisplayManager* const display_manager = GetDisplayManager(); + display::ManagedDisplayMode display_mode; + const display::Display& display = + display_manager->GetDisplayForId(display_id); + return display.device_scale_factor(); +} + +int GetScaleOfInternalDisplay() { + // Converting scale to percents. + return floor(GetScale(GetInternalDisplayId()) * 100.0 + 0.5); +} + +gfx::Size GetResolutionOfInternalDisplay() { + return GetResolution(GetInternalDisplayId()); +} + +int64_t GetExternalDisplayId() { + const display::DisplayManager* const display_manager = GetDisplayManager(); + if (display_manager->GetNumDisplays() < 2) { + ADD_FAILURE() << "The external display is not connected."; + return 0; + } + return display_manager->GetCurrentDisplayIdList()[1]; +} + +int GetScaleOfExternalDisplay() { + // Converting scale to percents. + return floor(GetScale(GetExternalDisplayId()) * 100.0 + 0.5); +} + +gfx::Size GetResolutionOfExternalDisplay() { + return GetResolution(GetExternalDisplayId()); +} + +PolicyValue GetPolicySetting() { + const base::DictionaryValue* resolution_pref = nullptr; + chromeos::CrosSettings::Get()->GetDictionary( + chromeos::kDeviceDisplayResolution, &resolution_pref); + EXPECT_TRUE(resolution_pref) << "DeviceDisplayResolution setting is not set"; + const base::Value* width = resolution_pref->FindKeyOfType( + {chromeos::kDeviceDisplayResolutionKeyExternalWidth}, + base::Value::Type::INTEGER); + const base::Value* height = resolution_pref->FindKeyOfType( + {chromeos::kDeviceDisplayResolutionKeyExternalHeight}, + base::Value::Type::INTEGER); + const base::Value* external_scale = resolution_pref->FindKeyOfType( + {chromeos::kDeviceDisplayResolutionKeyExternalScale}, + base::Value::Type::INTEGER); + const base::Value* use_native = resolution_pref->FindKeyOfType( + {chromeos::kDeviceDisplayResolutionKeyExternalUseNative}, + base::Value::Type::BOOLEAN); + const base::Value* internal_scale = resolution_pref->FindKeyOfType( + {chromeos::kDeviceDisplayResolutionKeyInternalScale}, + base::Value::Type::INTEGER); + PolicyValue result; + if (width) + result.external_width = width->GetInt(); + if (height) + result.external_height = height->GetInt(); + if (external_scale) + result.external_scale_percentage = external_scale->GetInt(); + if (internal_scale) + result.internal_scale_percentage = internal_scale->GetInt(); + if (use_native && use_native->GetBool()) + result.use_native = true; + return result; +} + +void AddExternalDisplay() { + GetDisplayManager()->AddRemoveDisplay( + {display::ManagedDisplayMode(gfx::Size(800, 600), 30.0, false, false), + display::ManagedDisplayMode(gfx::Size(800, 600), 60.0, false, false), + display::ManagedDisplayMode(gfx::Size(1280, 800), 60.0, false, false), + display::ManagedDisplayMode(gfx::Size(1920, 1080), 30.0, false, false), + display::ManagedDisplayMode(gfx::Size(1920, 1080), 60.0, false, true)}); + base::RunLoop().RunUntilIdle(); +} + +void SetPolicyValue(em::ChromeDeviceSettingsProto* proto, + PolicyValue policy, + bool recommended) { + std::vector<std::string> json_entries; + std::string json = ""; + if (policy.external_width) { + json_entries.push_back("\"external_width\": " + + std::to_string(*policy.external_width)); + } + if (policy.external_height) { + json_entries.push_back("\"external_height\": " + + std::to_string(*policy.external_height)); + } + if (policy.external_scale_percentage) { + json_entries.push_back("\"external_scale_percentage\": " + + std::to_string(*policy.external_scale_percentage)); + } + if (policy.internal_scale_percentage) { + json_entries.push_back("\"internal_scale_percentage\": " + + std::to_string(*policy.internal_scale_percentage)); + } + + json_entries.push_back(std::string("\"recommended\": ") + + (recommended ? "true" : "false")); + proto->mutable_device_display_resolution()->set_device_display_resolution( + "{" + base::JoinString(json_entries, ",") + "}"); +} + +std::unique_ptr<extensions::api::system_display::DisplayMode> +CreateDisplayMode(int64_t display_id, int width, int height) { + auto result = + std::make_unique<extensions::api::system_display::DisplayMode>(); + const display::ManagedDisplayInfo& info = + GetDisplayManager()->GetDisplayInfo(display_id); + for (const display::ManagedDisplayMode& mode : info.display_modes()) { + if (mode.size().width() == width && mode.size().height() == height) { + result->width = mode.size().width(); + result->height = mode.size().height(); + result->width_in_native_pixels = mode.size().width(); + result->height_in_native_pixels = mode.size().height(); + result->refresh_rate = mode.refresh_rate(); + result->is_native = mode.native(); + result->device_scale_factor = mode.device_scale_factor(); + return result; + } + } + result->width = width; + result->height = height; + return result; +} + +} // anonymous namespace + +namespace policy { + +class DeviceDisplayResolutionTestBase + : public policy::DevicePolicyCrosBrowserTest, + public testing::WithParamInterface<PolicyValue> { + public: + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitch(chromeos::switches::kLoginManager); + command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); + command_line->AppendSwitch(switches::kUseFirstDisplayAsInternal); + } + + void SetUpInProcessBrowserTestFixture() override { + InstallOwnerKey(); + MarkAsEnterpriseOwned(); + ash::DisplayConfigurationController::DisableAnimatorForTest(); + DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture(); + } + + void TearDownOnMainThread() override { + // If the login display is still showing, exit gracefully. + if (chromeos::LoginDisplayHost::default_host()) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&chrome::AttemptExit)); + RunUntilBrowserProcessQuits(); + } + } + + protected: + DeviceDisplayResolutionTestBase() {} + + void SetPolicy(PolicyValue policy, bool recommended) { + em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); + SetPolicyValue(&proto, policy, recommended); + RefreshPolicyAndWaitUntilDeviceSettingsUpdated(); + } + + void UnsetPolicy() { + em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); + proto.clear_device_display_resolution(); + RefreshPolicyAndWaitUntilDeviceSettingsUpdated(); + } + + void RefreshPolicyAndWaitUntilDeviceSettingsUpdated() { + base::RunLoop run_loop; + // For calls from SetPolicy(). + std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> observer = + chromeos::CrosSettings::Get()->AddSettingsObserver( + chromeos::kDeviceDisplayResolution, run_loop.QuitClosure()); + RefreshDevicePolicy(); + run_loop.Run(); + // Allow tasks posted by CrosSettings observers to complete: + base::RunLoop().RunUntilIdle(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(DeviceDisplayResolutionTestBase); +}; + +class DeviceDisplayResolutionTest : public DeviceDisplayResolutionTestBase { + public: + DeviceDisplayResolutionTest() {} + + protected: + void SetPolicy(PolicyValue value) { + DeviceDisplayResolutionTestBase::SetPolicy(value, false); + } + + private: + DISALLOW_COPY_AND_ASSIGN(DeviceDisplayResolutionTest); +}; + +IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionTest, Internal) { + const PolicyValue policy_value = GetParam(); + + EXPECT_EQ(kDefaultDisplayScale, GetScaleOfInternalDisplay()) + << "Initial primary display scale before policy"; + EXPECT_EQ(kDefaultDisplayResolution, GetResolutionOfInternalDisplay()) + << "Initial primary display resolution before policy"; + + SetPolicy(policy_value); + PolicyValue setting_resolution = GetPolicySetting(); + EXPECT_EQ(policy_value, setting_resolution) + << "Value of CrosSettings after policy value changed"; + EXPECT_EQ(policy_value.internal_scale_percentage.value_or(0), + GetScaleOfInternalDisplay()) + << "Scale of primary display after policy"; +} + +IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionTest, ResizeExternalDisplay) { + const PolicyValue policy_value = GetParam(); + + AddExternalDisplay(); + + EXPECT_EQ(kDefaultDisplayScale, GetScaleOfInternalDisplay()) + << "Initial primary display scale after connecting external"; + EXPECT_EQ(kDefaultDisplayResolution, GetResolutionOfInternalDisplay()) + << "Initial primary display resolution after connecting external"; + + EXPECT_EQ(kDefaultDisplayScale, GetScaleOfExternalDisplay()) + << "Scale of external display before policy"; + EXPECT_EQ(kDefaultExternalDisplayResolution, GetResolutionOfExternalDisplay()) + << "Resolution of external display before policy"; + + SetPolicy(policy_value); + EXPECT_EQ(policy_value.external_scale_percentage.value_or(0), + GetScaleOfExternalDisplay()) + << "Scale of already connected external display after policy"; + EXPECT_EQ(policy_value.external_display_size(), + GetResolutionOfExternalDisplay()) + << "Resolution of already connected external display after policy"; + + EXPECT_EQ(policy_value.internal_scale_percentage.value_or(0), + GetScaleOfInternalDisplay()) + << "Primary display scale after resizing external"; +} + +IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionTest, ConnectExternalDisplay) { + const PolicyValue policy_value = GetParam(); + + SetPolicy(policy_value); + EXPECT_EQ(policy_value.internal_scale_percentage.value_or(0), + GetScaleOfInternalDisplay()) + << "Initial primary display scale after applying policy"; + + AddExternalDisplay(); + EXPECT_EQ(policy_value.external_scale_percentage.value_or(0), + GetScaleOfExternalDisplay()) + << "Scale of newly connected external display after policy"; + EXPECT_EQ(policy_value.external_display_size(), + GetResolutionOfExternalDisplay()) + << "Resolution of newly connected external display after policy"; + EXPECT_EQ(policy_value.internal_scale_percentage.value_or(0), + GetScaleOfInternalDisplay()) + << "Primary display scale after connecting external"; +} + +IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionTest, SetAndUnsetPolicy) { + const PolicyValue policy_value = GetParam(); + AddExternalDisplay(); + SetPolicy(policy_value); + UnsetPolicy(); + EXPECT_EQ(policy_value.external_scale_percentage.value_or(0), + GetScaleOfExternalDisplay()) + << "Scale of the external display after policy was set and unset"; + EXPECT_EQ(policy_value.external_display_size(), + GetResolutionOfExternalDisplay()) + << "Resolution of the external display after policy was set and unset."; + EXPECT_EQ(policy_value.internal_scale_percentage.value_or(0), + GetScaleOfInternalDisplay()) + << "Initial primary display scale after policy was set and unset"; +} + +INSTANTIATE_TEST_CASE_P( + PolicyDeviceDisplayResolution, + DeviceDisplayResolutionTest, + testing::Values(PolicyValue{1920, 1080, 200, false, 200}, + PolicyValue{800, 600, 50, false, 100}, + PolicyValue{1280, 800, 100, false, 150})); + +// This class tests that the policy is reapplied after a reboot. To persist from +// PRE_Reboot to Reboot, the policy is inserted into a FakeSessionManagerClient. +// From there, it travels to DeviceSettingsProvider, whose UpdateFromService() +// method caches the policy (using device_settings_cache::Store()). +// In the main test, the FakeSessionManagerClient is not fully initialized. +// Thus, DeviceSettingsProvider falls back on the cached values (using +// device_settings_cache::Retrieve()). +class DisplayResolutionBootTest + : public InProcessBrowserTest, + public testing::WithParamInterface<PolicyValue> { + protected: + DisplayResolutionBootTest() + : fake_session_manager_client_(new chromeos::FakeSessionManagerClient) {} + ~DisplayResolutionBootTest() override {} + + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitch(switches::kUseFirstDisplayAsInternal); + } + + void SetUpInProcessBrowserTestFixture() override { + chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( + std::unique_ptr<chromeos::SessionManagerClient>( + fake_session_manager_client_)); + chromeos::DBusThreadManager::GetSetterForTesting()->SetCryptohomeClient( + std::unique_ptr<chromeos::CryptohomeClient>( + new chromeos::FakeCryptohomeClient)); + + test_helper_.InstallOwnerKey(); + test_helper_.MarkAsEnterpriseOwned(); + ash::DisplayConfigurationController::DisableAnimatorForTest(); + } + + chromeos::FakeSessionManagerClient* fake_session_manager_client_; + policy::DevicePolicyCrosTestHelper test_helper_; +}; + +IN_PROC_BROWSER_TEST_P(DisplayResolutionBootTest, PRE_Reboot) { + const PolicyValue policy_value = GetParam(); + + // Set policy. + policy::DevicePolicyBuilder* const device_policy( + test_helper_.device_policy()); + em::ChromeDeviceSettingsProto& proto(device_policy->payload()); + SetPolicyValue(&proto, policy_value, true); + base::RunLoop run_loop; + std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> observer = + chromeos::CrosSettings::Get()->AddSettingsObserver( + chromeos::kDeviceDisplayResolution, run_loop.QuitClosure()); + device_policy->SetDefaultSigningKey(); + device_policy->Build(); + fake_session_manager_client_->set_device_policy(device_policy->GetBlob()); + fake_session_manager_client_->OnPropertyChangeComplete(true); + run_loop.Run(); + // Allow tasks posted by CrosSettings observers to complete: + base::RunLoop().RunUntilIdle(); + AddExternalDisplay(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(policy_value.external_scale_percentage.value_or(0), + GetScaleOfExternalDisplay()) + << "Scale of the external display after policy set"; + EXPECT_EQ(policy_value.external_display_size(), + GetResolutionOfExternalDisplay()) + << "Resolution of the external display after policy set"; + EXPECT_EQ(policy_value.internal_scale_percentage.value_or(0), + GetScaleOfInternalDisplay()) + << "Initial primary display scale after policy set"; +} + +IN_PROC_BROWSER_TEST_P(DisplayResolutionBootTest, Reboot) { + const PolicyValue policy_value = GetParam(); + + AddExternalDisplay(); + base::RunLoop().RunUntilIdle(); + // Check that the policy resolution is restored. + EXPECT_EQ(policy_value.external_scale_percentage.value_or(0), + GetScaleOfExternalDisplay()) + << "Scale of the external display after reboot"; + EXPECT_EQ(policy_value.external_display_size(), + GetResolutionOfExternalDisplay()) + << "Resolution of the external display after reboot"; + EXPECT_EQ(policy_value.internal_scale_percentage.value_or(0), + GetScaleOfInternalDisplay()) + << "Initial primary display scale after reboot"; +} + +INSTANTIATE_TEST_CASE_P(PolicyDeviceDisplayResolution, + DisplayResolutionBootTest, + testing::Values(PolicyValue{1920, 1080, 200, false, + 200}, + PolicyValue{800, 600, 50, false, 50})); + +class DeviceDisplayResolutionRecommendedTest + : public DeviceDisplayResolutionTestBase { + public: + DeviceDisplayResolutionRecommendedTest() {} + + protected: + void SetPolicy(PolicyValue value) { + DeviceDisplayResolutionTestBase::SetPolicy(value, true); + } + + void SetUserProperties( + int64_t display_id, + extensions::api::system_display::DisplayProperties props) { + base::RunLoop run_loop; + base::OnceClosure quit_closure(run_loop.QuitClosure()); + base::Optional<std::string> operation_error; + extensions::DisplayInfoProvider::Get()->SetDisplayProperties( + std::to_string(display_id), std::move(props), + base::BindOnce( + [](base::OnceClosure quit_closure, base::Optional<std::string>) { + std::move(quit_closure).Run(); + }, + std::move(quit_closure))); + run_loop.Run(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(DeviceDisplayResolutionRecommendedTest); +}; + +IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionRecommendedTest, Internal) { + const PolicyValue policy_value = GetParam(); + EXPECT_EQ(kDefaultDisplayResolution, GetResolutionOfInternalDisplay()) + << "Initial primary display resolution before policy"; + EXPECT_EQ(kDefaultDisplayScale, GetScaleOfInternalDisplay()) + << "Initial primary display scale before policy"; + + SetPolicy(policy_value); + PolicyValue setting_resolution = GetPolicySetting(); + EXPECT_EQ(policy_value, setting_resolution) + << "Value of CrosSettings after policy value changed"; + EXPECT_EQ(setting_resolution.internal_scale_percentage.value_or(0), + GetScaleOfInternalDisplay()) + << "Scale of primary display after policy"; + + extensions::api::system_display::DisplayProperties props; + double user_scale = 50; + props.display_zoom_factor = std::make_unique<double>(user_scale / 100.0); + SetUserProperties(GetInternalDisplayId(), std::move(props)); + + EXPECT_EQ(user_scale, GetScaleOfInternalDisplay()) + << "Scale of internal display after user operation"; +} + +IN_PROC_BROWSER_TEST_P(DeviceDisplayResolutionRecommendedTest, + ResizeExternalDisplay) { + const PolicyValue policy_value = GetParam(); + AddExternalDisplay(); + + EXPECT_EQ(kDefaultDisplayScale, GetScaleOfInternalDisplay()) + << "Initial primary display scale after connecting external"; + EXPECT_EQ(kDefaultDisplayResolution, GetResolutionOfInternalDisplay()) + << "Initial primary display resolution after connecting external"; + + EXPECT_EQ(kDefaultDisplayScale, GetScaleOfExternalDisplay()) + << "Scale of external display before policy"; + EXPECT_EQ(kDefaultExternalDisplayResolution, GetResolutionOfExternalDisplay()) + << "Resolution of external display before policy"; + + SetPolicy(policy_value); + + EXPECT_EQ(policy_value.external_scale_percentage.value_or(0), + GetScaleOfExternalDisplay()) + << "Scale of the external display after policy"; + EXPECT_EQ(policy_value.external_display_size(), + GetResolutionOfExternalDisplay()) + << "Resolution the external display after policy"; + + EXPECT_EQ(policy_value.internal_scale_percentage.value_or(0), + GetScaleOfInternalDisplay()) + << "Internal display scale after resizing external"; + + extensions::api::system_display::DisplayProperties props; + double user_scale = 50; + double user_width = 1920; + double user_height = 1080; + props.display_zoom_factor = std::make_unique<double>(user_scale / 100.0); + props.display_mode = + CreateDisplayMode(GetExternalDisplayId(), user_width, user_height); + SetUserProperties(GetExternalDisplayId(), std::move(props)); + + EXPECT_EQ(user_scale, GetScaleOfExternalDisplay()) + << "Scale of the external display after user operation"; + EXPECT_EQ(gfx::Size(user_width, user_height), + GetResolutionOfExternalDisplay()) + << "Resolution of the external display after user operation"; + + EXPECT_EQ(policy_value.internal_scale_percentage.value_or(0), + GetScaleOfInternalDisplay()) + << "Internal display scale after user operation"; +} + +INSTANTIATE_TEST_CASE_P( + PolicyDeviceDisplayResolution, + DeviceDisplayResolutionRecommendedTest, + testing::Values(PolicyValue{1920, 1080, 200, false, 200}, + PolicyValue{800, 600, 50, false, 100}, + PolicyValue{1280, 800, 100, false, 150})); + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/display_rotation_default_handler.cc b/chrome/browser/chromeos/policy/display_rotation_default_handler.cc index 34277ba..ba45d0d 100644 --- a/chrome/browser/chromeos/policy/display_rotation_default_handler.cc +++ b/chrome/browser/chromeos/policy/display_rotation_default_handler.cc
@@ -4,102 +4,22 @@ #include "chrome/browser/chromeos/policy/display_rotation_default_handler.h" -#include <stddef.h> - -#include "ash/public/interfaces/constants.mojom.h" -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/memory/ref_counted.h" -#include "base/single_thread_task_runner.h" -#include "base/strings/string_number_conversions.h" -#include "base/threading/thread_task_runner_handle.h" -#include "chromeos/settings/cros_settings_names.h" -#include "content/public/common/service_manager_connection.h" -#include "services/service_manager/public/cpp/connector.h" +#include <utility> namespace policy { -DisplayRotationDefaultHandler::DisplayRotationDefaultHandler() { - settings_observer_ = chromeos::CrosSettings::Get()->AddSettingsObserver( - chromeos::kDisplayRotationDefault, - base::Bind(&DisplayRotationDefaultHandler::OnCrosSettingsChanged, - base::Unretained(this))); - - content::ServiceManagerConnection::GetForProcess() - ->GetConnector() - ->BindInterface(ash::mojom::kServiceName, &cros_display_config_); - - // Make the initial display unit info request. This will be queued until the - // Ash service is ready. - cros_display_config_->GetDisplayUnitInfoList( - false /* single_unified */, - base::BindOnce(&DisplayRotationDefaultHandler::OnGetInitialDisplayInfo, - weak_ptr_factory_.GetWeakPtr())); -} +DisplayRotationDefaultHandler::DisplayRotationDefaultHandler() = default; DisplayRotationDefaultHandler::~DisplayRotationDefaultHandler() = default; -void DisplayRotationDefaultHandler::OnDisplayConfigChanged() { - RequestAndRotateDisplays(); +const char* DisplayRotationDefaultHandler::SettingName() { + return chromeos::kDisplayRotationDefault; } -void DisplayRotationDefaultHandler::OnGetInitialDisplayInfo( - std::vector<ash::mojom::DisplayUnitInfoPtr> info_list) { - // Add this as an observer to the mojo service now that it is ready. - // (We only care about changes that occur after we set any policy - // rotation below). - ash::mojom::CrosDisplayConfigObserverAssociatedPtrInfo ptr_info; - cros_display_config_observer_binding_.Bind(mojo::MakeRequest(&ptr_info)); - cros_display_config_->AddObserver(std::move(ptr_info)); - - // Get the initial policy values from CrosSettings and apply any rotation. - UpdateFromCrosSettings(); - RotateDisplays(std::move(info_list)); -} - -void DisplayRotationDefaultHandler::RequestAndRotateDisplays() { - cros_display_config_->GetDisplayUnitInfoList( - false /* single_unified */, - base::BindOnce(&DisplayRotationDefaultHandler::RotateDisplays, - weak_ptr_factory_.GetWeakPtr())); -} - -void DisplayRotationDefaultHandler::OnCrosSettingsChanged() { - if (!UpdateFromCrosSettings()) - return; - // Policy changed, so reset all displays. - rotated_display_ids_.clear(); - RequestAndRotateDisplays(); -} - -void DisplayRotationDefaultHandler::RotateDisplays( - std::vector<ash::mojom::DisplayUnitInfoPtr> info_list) { - if (!policy_enabled_) - return; - - for (const ash::mojom::DisplayUnitInfoPtr& display_unit_info : info_list) { - std::string display_id = display_unit_info->id; - if (rotated_display_ids_.find(display_id) != rotated_display_ids_.end()) - continue; - - rotated_display_ids_.insert(display_id); - display::Display::Rotation rotation(display_unit_info->rotation); - if (rotation == display_rotation_default_) - continue; - - // The following sets only the |rotation| property of the display - // configuration; no other properties will be affected. - auto config_properties = ash::mojom::DisplayConfigProperties::New(); - config_properties->rotation = - ash::mojom::DisplayRotation::New(display_rotation_default_); - cros_display_config_->SetDisplayProperties( - display_unit_info->id, std::move(config_properties), base::DoNothing()); - } -} - -bool DisplayRotationDefaultHandler::UpdateFromCrosSettings() { +// Reads |chromeos::kDisplayRotationDefault| from CrosSettings and stores +// its value, and whether it has a value, in member variables +// |display_rotation_default_| and |policy_enabled_|. +void DisplayRotationDefaultHandler::OnSettingUpdate() { int new_rotation; bool new_policy_enabled = chromeos::CrosSettings::Get()->GetInteger( chromeos::kDisplayRotationDefault, &new_rotation); @@ -121,9 +41,34 @@ new_display_rotation_default != display_rotation_default_)) { policy_enabled_ = new_policy_enabled; display_rotation_default_ = new_display_rotation_default; - return true; + rotated_display_ids_.clear(); } - return false; +} + +void DisplayRotationDefaultHandler::ApplyChanges( + ash::mojom::CrosDisplayConfigController* cros_display_config, + const std::vector<ash::mojom::DisplayUnitInfoPtr>& info_list) { + if (!policy_enabled_) + return; + for (const ash::mojom::DisplayUnitInfoPtr& display_unit_info : info_list) { + std::string display_id = display_unit_info->id; + + if (rotated_display_ids_.find(display_id) != rotated_display_ids_.end()) + continue; + + rotated_display_ids_.insert(display_id); + display::Display::Rotation rotation(display_unit_info->rotation); + if (rotation == display_rotation_default_) + continue; + + // The following sets only the |rotation| property of the display + // configuration; no other properties will be affected. + auto config_properties = ash::mojom::DisplayConfigProperties::New(); + config_properties->rotation = + ash::mojom::DisplayRotation::New(display_rotation_default_); + cros_display_config->SetDisplayProperties( + display_unit_info->id, std::move(config_properties), base::DoNothing()); + } } } // namespace policy
diff --git a/chrome/browser/chromeos/policy/display_rotation_default_handler.h b/chrome/browser/chromeos/policy/display_rotation_default_handler.h index a02fb2d..ba0914e 100644 --- a/chrome/browser/chromeos/policy/display_rotation_default_handler.h +++ b/chrome/browser/chromeos/policy/display_rotation_default_handler.h
@@ -5,72 +5,46 @@ #ifndef CHROME_BROWSER_CHROMEOS_POLICY_DISPLAY_ROTATION_DEFAULT_HANDLER_H_ #define CHROME_BROWSER_CHROMEOS_POLICY_DISPLAY_ROTATION_DEFAULT_HANDLER_H_ -#include <stdint.h> -#include <memory> #include <set> #include <string> #include <vector> #include "ash/public/interfaces/cros_display_config.mojom.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" -#include "mojo/public/cpp/bindings/associated_binding.h" +#include "chrome/browser/chromeos/policy/display_settings_handler.h" #include "ui/display/display.h" namespace policy { -// Enforces the device policy DisplayRotationDefault. -// This class must be constructed after CrosSettings is initialized. -// On construction this class registers itself with -// ash::mojom::CrosDisplayConfigObserver for display changes and with -// CrosSettings for settings changes. Whenever there is a change in the display -// configuration, any new display with an id that is not already in -// |rotated_display_ids_| will be rotated according to the policy. When there is -// a change to CrosSettings, the new policy is applied to all displays. -// NOTE: This only rotates displays on startup and when the policy changes. -// i.e. this will not override subsequent rotations (e.g. via Settings or an -// extension with display configuration permissions). -class DisplayRotationDefaultHandler - : public ash::mojom::CrosDisplayConfigObserver { +// Implements DisplayRotationDefault device policy. +// +// Whenever there is a change in the display configuration, any new display will +// be rotated according to the policy. +// +// Whenever there is a change in |kDisplayResolutionDefault| setting from +// CrosSettings, the new policy is applied to all displays. +// +// Once rotation for some display was set by this policy it won't be reapplied +// until next reboot or policy change (i.e. user can manually override the +// rotation for that display via settings page). +class DisplayRotationDefaultHandler : public DisplaySettingsPolicyHandler { public: DisplayRotationDefaultHandler(); + ~DisplayRotationDefaultHandler() override; - // ash::mojom::CrosDisplayConfigObserver - void OnDisplayConfigChanged() override; + // DisplaySettingsPolicyHandler + const char* SettingName() override; + void OnSettingUpdate() override; + void ApplyChanges( + ash::mojom::CrosDisplayConfigController* cros_display_config, + const std::vector<ash::mojom::DisplayUnitInfoPtr>& info_list) override; private: - // Receives the initial display info list and initializes the class. - void OnGetInitialDisplayInfo( - std::vector<ash::mojom::DisplayUnitInfoPtr> info_list); - - // Requests the list of displays and calls RotateDisplays. - void RequestAndRotateDisplays(); - - // Callback function for settings_observer_. - void OnCrosSettingsChanged(); - - // Applies the policy to all connected displays as necessary. - void RotateDisplays(std::vector<ash::mojom::DisplayUnitInfoPtr> info_list); - - // Reads |chromeos::kDisplayRotationDefault| from CrosSettings and stores - // its value, and whether it has a value, in member variables - // |display_rotation_default_| and |policy_enabled_|. Returns true if the - // setting changed. - bool UpdateFromCrosSettings(); - bool policy_enabled_ = false; display::Display::Rotation display_rotation_default_ = display::Display::ROTATE_0; std::set<std::string> rotated_display_ids_; - ash::mojom::CrosDisplayConfigControllerPtr cros_display_config_; - mojo::AssociatedBinding<ash::mojom::CrosDisplayConfigObserver> - cros_display_config_observer_binding_{this}; - std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> - settings_observer_; - base::WeakPtrFactory<DisplayRotationDefaultHandler> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(DisplayRotationDefaultHandler); };
diff --git a/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc b/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc index a0a7445..1822172 100644 --- a/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc +++ b/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc
@@ -4,8 +4,6 @@ #include "chrome/browser/chromeos/policy/display_rotation_default_handler.h" -#include <stdint.h> - #include <memory> #include "ash/display/display_configuration_controller.h"
diff --git a/chrome/browser/chromeos/policy/display_settings_handler.cc b/chrome/browser/chromeos/policy/display_settings_handler.cc new file mode 100644 index 0000000..04ed0b4 --- /dev/null +++ b/chrome/browser/chromeos/policy/display_settings_handler.cc
@@ -0,0 +1,109 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/policy/display_settings_handler.h" + +#include <utility> +#include "ash/public/interfaces/constants.mojom.h" +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/single_thread_task_runner.h" +#include "base/strings/string_number_conversions.h" +#include "base/threading/thread_task_runner_handle.h" +#include "chromeos/settings/cros_settings_names.h" +#include "content/public/common/service_manager_connection.h" +#include "services/service_manager/public/cpp/connector.h" + +namespace policy { + +DisplaySettingsHandler::DisplaySettingsHandler() { + content::ServiceManagerConnection::GetForProcess() + ->GetConnector() + ->BindInterface(ash::mojom::kServiceName, &cros_display_config_); +} + +DisplaySettingsHandler::~DisplaySettingsHandler() = default; + +void DisplaySettingsHandler::OnDisplayConfigChanged() { + RequestDisplaysAndApplyChanges(); +} + +void DisplaySettingsHandler::RegisterHandler( + std::unique_ptr<DisplaySettingsPolicyHandler> handler) { + if (!started_) + handlers_.push_back(std::move(handler)); +} + +void DisplaySettingsHandler::Start() { + if (started_) + return; + started_ = true; + + // Register observers for all settings + for (const auto& handler : handlers_) { + settings_observers_.push_back( + chromeos::CrosSettings::Get()->AddSettingsObserver( + handler->SettingName(), + base::BindRepeating(&DisplaySettingsHandler::OnSettingUpdate, + base::Unretained(this), + base::Unretained(handler.get())))); + } + + // Make the initial display unit info request. This will be queued until the + // Ash service is ready. + cros_display_config_->GetDisplayUnitInfoList( + false /* single_unified */, + base::BindOnce(&DisplaySettingsHandler::OnGetInitialDisplayInfo, + weak_ptr_factory_.GetWeakPtr())); +} + +void DisplaySettingsHandler::OnGetInitialDisplayInfo( + std::vector<ash::mojom::DisplayUnitInfoPtr> info_list) { + // Add this as an observer to the mojo service now that it is ready. + // (We only care about changes that occur after we apply any changes below). + ash::mojom::CrosDisplayConfigObserverAssociatedPtrInfo ptr_info; + cros_display_config_observer_binding_.Bind(mojo::MakeRequest(&ptr_info)); + cros_display_config_->AddObserver(std::move(ptr_info)); + + ApplyChanges(std::move(info_list)); +} + +void DisplaySettingsHandler::RequestDisplaysAndApplyChanges() { + cros_display_config_->GetDisplayUnitInfoList( + false /* single_unified */, + base::BindOnce(&DisplaySettingsHandler::ApplyChanges, + weak_ptr_factory_.GetWeakPtr())); +} + +void DisplaySettingsHandler::ApplyChanges( + std::vector<ash::mojom::DisplayUnitInfoPtr> info_list) { + for (std::unique_ptr<DisplaySettingsPolicyHandler>& handler : handlers_) + UpdateSettingAndApplyChanges(handler.get(), info_list); +} + +void DisplaySettingsHandler::OnSettingUpdate( + DisplaySettingsPolicyHandler* handler) { + cros_display_config_->GetDisplayUnitInfoList( + false /* single_unified */, + base::BindOnce(&DisplaySettingsHandler::OnConfigurationChangeForHandler, + weak_ptr_factory_.GetWeakPtr(), handler)); +} + +void DisplaySettingsHandler::UpdateSettingAndApplyChanges( + DisplaySettingsPolicyHandler* handler, + const std::vector<ash::mojom::DisplayUnitInfoPtr>& info_list) { + handler->OnSettingUpdate(); + handler->ApplyChanges(cros_display_config_.get(), info_list); +} + +void DisplaySettingsHandler::OnConfigurationChangeForHandler( + DisplaySettingsPolicyHandler* handler, + std::vector<ash::mojom::DisplayUnitInfoPtr> info_list) { + UpdateSettingAndApplyChanges(handler, info_list); +} + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/display_settings_handler.h b/chrome/browser/chromeos/policy/display_settings_handler.h new file mode 100644 index 0000000..154fbd9 --- /dev/null +++ b/chrome/browser/chromeos/policy/display_settings_handler.h
@@ -0,0 +1,113 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DISPLAY_SETTINGS_HANDLER_H_ +#define CHROME_BROWSER_CHROMEOS_POLICY_DISPLAY_SETTINGS_HANDLER_H_ + +#include <memory> +#include <vector> + +#include "ash/public/interfaces/cros_display_config.mojom.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" +#include "mojo/public/cpp/bindings/associated_binding.h" + +namespace policy { + +// Provides an interface for display configuration policies. Each policy should +// provide a handler that implements this interface and register it in +// the |DisplaySettingsHandler| instance. +class DisplaySettingsPolicyHandler { + public: + virtual ~DisplaySettingsPolicyHandler() = default; + + // Returns a name of setting stored in CrosSettings that should be used to + // subscribe to setting changes for this policy. + virtual const char* SettingName() = 0; + + // Is called on each setting update before |ApplyChanges| to provide + // updated settings for the handler. + virtual void OnSettingUpdate() = 0; + + // Applies settings enforced by the policy to each display from |info_list|. + // Is called on each configuration change or settings update. + virtual void ApplyChanges( + ash::mojom::CrosDisplayConfigController* cros_display_config, + const std::vector<ash::mojom::DisplayUnitInfoPtr>& info_list) = 0; +}; + +// Enforces the settings controlled by device policies related to display +// configuration (i.e. DisplayRotationDefault, DeviceDisplayResolution) +// On construction this class registers itself with +// ash::mojom::CrosDisplayConfigObserver for display changes and with +// CrosSettings for settings changes. Every display configuration policy +// provides a handler class inherited from |DisplaySettingsPolicyHandler| +// and is registered in |DisplaySettingsHandler| instance. +// see |DisplayResolutionHandler| and |DisplayRotationDefaultHandler| +class DisplaySettingsHandler : public ash::mojom::CrosDisplayConfigObserver { + public: + // This class must be constructed after CrosSettings is initialized. + DisplaySettingsHandler(); + + ~DisplaySettingsHandler() override; + + // ash::mojom::CrosDisplayConfigObserver + void OnDisplayConfigChanged() override; + + // Registers handler for some policy-controlled setting. All handlers must be + // registered before calling |Start|. + void RegisterHandler(std::unique_ptr<DisplaySettingsPolicyHandler> handler); + + // Subscribes to all needed events and initiates initial display configuration + // fetching to apply the settings controlled by registered handlers. + void Start(); + + private: + // Receives the initial display info list and initializes the class. + void OnGetInitialDisplayInfo( + std::vector<ash::mojom::DisplayUnitInfoPtr> info_list); + + // Requests the list of displays and applies each setting. + void RequestDisplaysAndApplyChanges(); + + // Callback function for settings_observer_. + void OnCrosSettingsChanged(); + + // Apply all default settings defined by policies to all conencted displays. + void ApplyChanges(std::vector<ash::mojom::DisplayUnitInfoPtr> info_list); + + // Called on each update of the setting provided by |handler|. Requests the + // list of displays and applies |handler| to each display. + void OnSettingUpdate(DisplaySettingsPolicyHandler* handler); + + // Applies |handler| to each display from |info_list|. + void UpdateSettingAndApplyChanges( + DisplaySettingsPolicyHandler* handler, + const std::vector<ash::mojom::DisplayUnitInfoPtr>& info_list); + + // Called on display configuration changes for each handler. + void OnConfigurationChangeForHandler( + DisplaySettingsPolicyHandler* handler, + std::vector<ash::mojom::DisplayUnitInfoPtr> info_list); + + // Provides access to the current display configurations, both for reading and + // updating. + ash::mojom::CrosDisplayConfigControllerPtr cros_display_config_; + std::vector<std::unique_ptr<DisplaySettingsPolicyHandler>> handlers_; + mojo::AssociatedBinding<ash::mojom::CrosDisplayConfigObserver> + cros_display_config_observer_binding_{this}; + std::vector<std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>> + settings_observers_; + bool started_ = false; + + // Must be the last member. + base::WeakPtrFactory<DisplaySettingsHandler> weak_ptr_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(DisplaySettingsHandler); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_CHROMEOS_POLICY_DISPLAY_SETTINGS_HANDLER_H_
diff --git a/chrome/browser/chromeos/preferences_unittest.cc b/chrome/browser/chromeos/preferences_unittest.cc index a0c61b2a..f69bbc4 100644 --- a/chrome/browser/chromeos/preferences_unittest.cc +++ b/chrome/browser/chromeos/preferences_unittest.cc
@@ -60,7 +60,7 @@ sync_pb::PreferenceSpecifics* pref = specifics.mutable_preference(); pref->set_name(name); pref->set_value(serialized); - return syncer::SyncData::CreateRemoteData(1, specifics, base::Time()); + return syncer::SyncData::CreateRemoteData(1, specifics); } } // anonymous namespace
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.cc b/chrome/browser/chromeos/settings/device_settings_provider.cc index 2546296..7d088ec 100644 --- a/chrome/browser/chromeos/settings/device_settings_provider.cc +++ b/chrome/browser/chromeos/settings/device_settings_provider.cc
@@ -83,6 +83,7 @@ kDeviceQuirksDownloadEnabled, kDeviceUnaffiliatedCrostiniAllowed, kDeviceWallpaperImage, + kDeviceDisplayResolution, kDisplayRotationDefault, kExtensionCacheSize, kHeartbeatEnabled, @@ -584,6 +585,19 @@ policy.display_rotation_default().display_rotation_default()); } + if (policy.has_device_display_resolution() && + policy.device_display_resolution().has_device_display_resolution()) { + SetJsonDeviceSetting( + kDeviceDisplayResolution, policy::key::kDeviceDisplayResolution, + policy.device_display_resolution().device_display_resolution(), + new_values_cache); + } else { + // Set empty value if policy is missing, to make sure that webui + // will receive setting update. + new_values_cache->SetValue(kDeviceDisplayResolution, + std::make_unique<base::DictionaryValue>()); + } + if (policy.has_allow_bluetooth() && policy.allow_bluetooth().has_allow_bluetooth()) { new_values_cache->SetBoolean(kAllowBluetooth,
diff --git a/chrome/browser/data_use_measurement/chrome_data_use_measurement.cc b/chrome/browser/data_use_measurement/chrome_data_use_measurement.cc index 6d6a737..3ea4e4c 100644 --- a/chrome/browser/data_use_measurement/chrome_data_use_measurement.cc +++ b/chrome/browser/data_use_measurement/chrome_data_use_measurement.cc
@@ -15,7 +15,7 @@ #include "chrome/browser/browser_process.h" #include "components/data_use_measurement/core/data_use_ascriber.h" #include "components/data_use_measurement/core/url_request_classifier.h" -#include "components/metrics/data_use_tracker.h" +#include "components/metrics/metrics_service.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/network_service_instance.h" @@ -34,9 +34,14 @@ bool is_cellular, bool is_metrics_service_usage) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - metrics::DataUseTracker::UpdateMetricsUsagePrefs( - base::saturated_cast<int>(total_bytes), is_cellular, - is_metrics_service_usage, g_browser_process->local_state()); + // Some unit tests use IOThread but do not initialize MetricsService. In that + // case it's fine to skip the update. + auto* metrics_service = g_browser_process->metrics_service(); + if (metrics_service) { + metrics_service->UpdateMetricsUsagePrefs( + base::saturated_cast<int>(total_bytes), is_cellular, + is_metrics_service_usage); + } } // This function is for forwarding metrics usage pref changes to the metrics
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 858078c..27a3735 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -846,6 +846,7 @@ "//content/public/common", "//crypto", "//device/bluetooth", + "//device/fido", "//extensions:extensions_resources", "//extensions/browser", "//extensions/browser:core_api_provider",
diff --git a/chrome/browser/extensions/api/automation_internal/automation_event_router.cc b/chrome/browser/extensions/api/automation_internal/automation_event_router.cc index ee0b792..dd1284b5d 100644 --- a/chrome/browser/extensions/api/automation_internal/automation_event_router.cc +++ b/chrome/browser/extensions/api/automation_internal/automation_event_router.cc
@@ -139,6 +139,36 @@ tree_destroyed_callback_for_test_ = cb; } +void AutomationEventRouter::DispatchGetTextLocationDataResult( + const ui::AXActionData& data, + const base::Optional<gfx::Rect>& rect) { + CHECK(!data.source_extension_id.empty()); + + if (listeners_.empty()) + return; + extensions::api::automation_internal::AXTextLocationParams params; + params.tree_id = data.target_tree_id; + params.node_id = data.target_node_id; + params.result = false; + if (rect) { + params.left = rect.value().x(); + params.top = rect.value().y(); + params.width = rect.value().width(); + params.height = rect.value().height(); + params.result = true; + } + params.request_id = data.request_id; + + std::unique_ptr<base::ListValue> args( + api::automation_internal::OnGetTextLocationResult::Create(params)); + auto event = std::make_unique<Event>( + events::AUTOMATION_INTERNAL_ON_GET_TEXT_LOCATION_RESULT, + api::automation_internal::OnGetTextLocationResult::kEventName, + std::move(args), active_profile_); + EventRouter::Get(active_profile_) + ->DispatchEventToExtension(data.source_extension_id, std::move(event)); +} + AutomationEventRouter::AutomationListener::AutomationListener() { }
diff --git a/chrome/browser/extensions/api/automation_internal/automation_event_router.h b/chrome/browser/extensions/api/automation_internal/automation_event_router.h index e2e7612..291d721 100644 --- a/chrome/browser/extensions/api/automation_internal/automation_event_router.h +++ b/chrome/browser/extensions/api/automation_internal/automation_event_router.h
@@ -69,6 +69,10 @@ void SetTreeDestroyedCallbackForTest( base::RepeatingCallback<void(ui::AXTreeID)> cb); + // Notify the source extension of the result to getTextLocation. + void DispatchGetTextLocationDataResult(const ui::AXActionData& data, + const base::Optional<gfx::Rect>& rect); + private: struct AutomationListener { AutomationListener();
diff --git a/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc b/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc index 08c2626a..656deed4 100644 --- a/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc +++ b/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc
@@ -461,6 +461,18 @@ case api::automation::ACTION_TYPE_SETSCROLLOFFSET: return RespondNow( Error("Unsupported action: " + params->args.action_type)); + case api::automation::ACTION_TYPE_GETTEXTLOCATION: { + api::automation_internal::GetTextLocationDataParams + get_text_location_params; + EXTENSION_FUNCTION_VALIDATE( + api::automation_internal::GetTextLocationDataParams::Populate( + params->opt_args.additional_properties, + &get_text_location_params)); + action->action = ax::mojom::Action::kGetTextLocation; + action->start_index = get_text_location_params.start_index; + action->end_index = get_text_location_params.end_index; + break; + } case api::automation::ACTION_TYPE_NONE: break; }
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc b/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc index 49d181f5..3d7e0d1 100644 --- a/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc +++ b/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc
@@ -426,7 +426,7 @@ // Sync is running. browser_sync::ProfileSyncService* sync_service = ProfileSyncServiceFactory::GetForProfile(profile); - sync_service->SetFirstSetupComplete(); + sync_service->GetUserSettings()->SetFirstSetupComplete(); sync_ui_util::MessageType sync_status = sync_ui_util::GetStatus(profile, sync_service, *signin_manager); ASSERT_EQ(sync_ui_util::SYNCED, sync_status);
diff --git a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc index d4b2f5d..45f8aeb 100644 --- a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc +++ b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc
@@ -19,6 +19,7 @@ #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" #include "crypto/sha2.h" +#include "device/fido/features.h" #include "extensions/common/error_utils.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "url/origin.h" @@ -241,5 +242,14 @@ Respond(OneArgument(std::make_unique<base::Value>(result))); } +CryptotokenPrivateCanProxyToWebAuthnFunction:: + CryptotokenPrivateCanProxyToWebAuthnFunction() {} + +ExtensionFunction::ResponseAction +CryptotokenPrivateCanProxyToWebAuthnFunction::Run() { + return RespondNow(OneArgument(std::make_unique<base::Value>( + base::FeatureList::IsEnabled(device::kWebAuthProxyCryptotoken)))); +} + } // namespace api } // namespace extensions
diff --git a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.h b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.h index 7c92493..3c395087 100644 --- a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.h +++ b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.h
@@ -63,6 +63,17 @@ void Complete(bool result); }; +class CryptotokenPrivateCanProxyToWebAuthnFunction + : public UIThreadExtensionFunction { + public: + CryptotokenPrivateCanProxyToWebAuthnFunction(); + DECLARE_EXTENSION_FUNCTION("cryptotokenPrivate.canProxyToWebAuthn", + CRYPTOTOKENPRIVATE_CANPROXYTOWEBAUTHN) + protected: + ~CryptotokenPrivateCanProxyToWebAuthnFunction() override {} + ResponseAction Run() override; +}; + } // namespace api } // namespace extensions
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index cb9a35b..3bac53f 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -216,8 +216,6 @@ settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[::prefs::kSearchSuggestEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; - (*s_whitelist)[::unified_consent::prefs::kUnifiedConsentGiven] = - settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist) [::unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; @@ -418,6 +416,10 @@ settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[::prefs::kVpnConfigAllowed] = settings_api::PrefType::PREF_TYPE_BOOLEAN; + (*s_whitelist)[arc::prefs::kAlwaysOnVpnPackage] = + settings_api::PrefType::PREF_TYPE_STRING; + (*s_whitelist)[arc::prefs::kAlwaysOnVpnLockdown] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; // Timezone settings. (*s_whitelist)[chromeos::kSystemTimezone] = @@ -502,6 +504,10 @@ settings_api::PrefType::PREF_TYPE_NUMBER; (*s_whitelist)[::prefs::kLanguageXkbAutoRepeatInterval] = settings_api::PrefType::PREF_TYPE_NUMBER; + (*s_whitelist)[chromeos::kDeviceDisplayResolution] = + settings_api::PrefType::PREF_TYPE_DICTIONARY; + (*s_whitelist)[chromeos::kDisplayRotationDefault] = + settings_api::PrefType::PREF_TYPE_DICTIONARY; // Native Printing settings. (*s_whitelist)[::prefs::kUserNativePrintersAllowed] =
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc index ba7b82c..bb4a583 100644 --- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -813,7 +813,8 @@ EXPECT_TRUE(listener_app.WaitUntilSatisfied()); EXPECT_TRUE(listener_extension.WaitUntilSatisfied()); - // Load a page, a content script will ping us when it is ready. + // Load a page, a content script from "webrequest_extensions/extension" will + // ping us when it is ready. ExtensionTestMessageListener listener_pageready("contentscript_ready", true); ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL( "/extensions/test_file.html?match_webrequest_test")); @@ -845,8 +846,10 @@ listener_main2.Reply(""); EXPECT_TRUE(listener_result.WaitUntilSatisfied()); - // The extension frame does run in the extension's process. - EXPECT_EQ("Intercepted requests: ?contentscript", listener_result.message()); + // The extension frame does run in the extension's process. Any requests made + // by it should not be visible to other extensions, since they won't have + // access to the request initiator. + EXPECT_EQ("Did not intercept any requests.", listener_result.message()); } IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, HostedAppRequest) { @@ -1594,9 +1597,9 @@ } } -// Test that initiator is only included as part of event details when the -// extension has a permission matching the initiator. -IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, MinimumAccessInitiator) { +// Test that extensions need host permissions to both the request url and +// initiator to intercept a request. +IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, InitiatorAccessRequired) { ASSERT_TRUE(StartEmbeddedTestServer()); ExtensionTestMessageListener listener("ready", false); @@ -1615,9 +1618,14 @@ std::string expected_initiator; } testcases[] = {{"example.com", "example.com", "example.com"}, {"example2.com", "example3.com", "example2.com"}, - {"no-permission.com", "example4.com", ""}}; + // No access to the initiator. + {"no-permission.com", "example4.com", ""}, + // No access to the request url. + {"example.com", "no-permission.com", ""}}; int port = embedded_test_server()->port(); + + int expected_requests_intercepted_count = 0; for (const auto& testcase : testcases) { SCOPED_TRACE(testcase.navigate_before_start + ":" + testcase.xhr_domain + ":" + testcase.expected_initiator); @@ -1628,11 +1636,25 @@ "/extensions/body1.html")); PerformXhrInFrame(web_contents->GetMainFrame(), testcase.xhr_domain, port, "extensions/api_test/webrequest/xhr/data.json"); - EXPECT_TRUE(initiator_listener.WaitUntilSatisfied()); + + // Ensure that the extension wasn't able to intercept the request if it + // didn't have permission to the initiator or the request url. + if (!testcase.expected_initiator.empty()) + ++expected_requests_intercepted_count; + + // Run a script in the extensions background page to ensure that we have + // received the initiator message from the extension. + ASSERT_EQ( + std::to_string(expected_requests_intercepted_count), + ExecuteScriptInBackgroundPage(extension->id(), + "window.domAutomationController.send(" + "requestsIntercepted.toString());")); + if (testcase.expected_initiator.empty()) { - ASSERT_EQ("NO_INITIATOR", initiator_listener.message()); + EXPECT_FALSE(initiator_listener.was_satisfied()); } else { - ASSERT_EQ( + ASSERT_TRUE(initiator_listener.was_satisfied()); + EXPECT_EQ( "http://" + testcase.expected_initiator + ":" + std::to_string(port), initiator_listener.message()); }
diff --git a/chrome/browser/extensions/extension_disabled_ui_browsertest.cc b/chrome/browser/extensions/extension_disabled_ui_browsertest.cc index adce318a..2ac4f6b 100644 --- a/chrome/browser/extensions/extension_disabled_ui_browsertest.cc +++ b/chrome/browser/extensions/extension_disabled_ui_browsertest.cc
@@ -304,7 +304,7 @@ "http://localhost/autoupdate/updates.xml"); specifics.mutable_extension()->set_version("2"); syncer::SyncData sync_data = - syncer::SyncData::CreateRemoteData(1234567, specifics, base::Time::Now()); + syncer::SyncData::CreateRemoteData(1234567, specifics); ExtensionSyncService* sync_service = ExtensionSyncService::Get(profile()); sync_service->MergeDataAndStartSyncing(
diff --git a/chrome/browser/extensions/extension_service_sync_unittest.cc b/chrome/browser/extensions/extension_service_sync_unittest.cc index 5028d67..3aee86c 100644 --- a/chrome/browser/extensions/extension_service_sync_unittest.cc +++ b/chrome/browser/extensions/extension_service_sync_unittest.cc
@@ -346,7 +346,7 @@ // The user has enabled sync. browser_sync::ProfileSyncService* sync_service = ProfileSyncServiceFactory::GetForProfile(profile()); - sync_service->SetFirstSetupComplete(); + sync_service->GetUserSettings()->SetFirstSetupComplete(); service()->Init(); ASSERT_TRUE(service()->is_ready()); @@ -382,7 +382,7 @@ // Enable sync. browser_sync::ProfileSyncService* sync_service = ProfileSyncServiceFactory::GetForProfile(profile()); - sync_service->SetFirstSetupComplete(); + sync_service->GetUserSettings()->SetFirstSetupComplete(); service()->Init(); @@ -464,7 +464,7 @@ // Enable sync. browser_sync::ProfileSyncService* sync_service = ProfileSyncServiceFactory::GetForProfile(profile()); - sync_service->SetFirstSetupComplete(); + sync_service->GetUserSettings()->SetFirstSetupComplete(); service()->Init(); @@ -530,7 +530,7 @@ // The user has enabled sync. browser_sync::ProfileSyncService* sync_service = ProfileSyncServiceFactory::GetForProfile(profile()); - sync_service->SetFirstSetupComplete(); + sync_service->GetUserSettings()->SetFirstSetupComplete(); // Make sure ExtensionSyncService is created, so it'll be notified of changes. extension_sync_service(); @@ -589,7 +589,9 @@ InitializeInstalledExtensionService(pref_path, source_install_dir); // The user has enabled sync. - ProfileSyncServiceFactory::GetForProfile(profile())->SetFirstSetupComplete(); + ProfileSyncServiceFactory::GetForProfile(profile()) + ->GetUserSettings() + ->SetFirstSetupComplete(); // Make sure ExtensionSyncService is created, so it'll be notified of changes. extension_sync_service(); @@ -1706,7 +1708,9 @@ InitializeEmptyExtensionService(); // The user has enabled sync. - ProfileSyncServiceFactory::GetForProfile(profile())->SetFirstSetupComplete(); + ProfileSyncServiceFactory::GetForProfile(profile()) + ->GetUserSettings() + ->SetFirstSetupComplete(); // Make sure ExtensionSyncService is created, so it'll be notified of changes. extension_sync_service(); @@ -2629,7 +2633,7 @@ // Enable sync. browser_sync::ProfileSyncService* sync_service = ProfileSyncServiceFactory::GetForProfile(profile()); - sync_service->SetFirstSetupComplete(); + sync_service->GetUserSettings()->SetFirstSetupComplete(); test_blacklist_.Attach(service()->blacklist_); service()->Init();
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 46a1396..df5e213 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -3,7 +3,7 @@ // of the review process and to clean up flags that have become obsolete or // unused. For more details, see: // -// https://sites.google.com/a/chromium.org/dev/flag-ownership +// https://sites.google.com/a/chromium.org/dev/developers/contributing-code/flag-ownership // // This file is a list of json objects; each object contains these keys: // @@ -11,9 +11,13 @@ // used as a primary key. The value is a string. // // owners: the person(s) or team(s) responsible for this flag. The value is a -// list of strings, each of which is either an email address, or any other -// text, in which case it is assumed to be the username part of an -// @chromium.org email address. This list must be nonempty. +// nonempty list of strings, each of which is either: +// +// - A string containing '@', which is treated as an email address; +// - A string beginning with '//', which is treated as a path to a file +// containing a list of owners for this flag (commonly an OWNERS file); +// - Any other string, which is treated as the username part of an +// @chromium.org email address; // // expiry_milestone: the milestone after which this flag is obsolete. // Specifically, after the milestone with the given number branches, this flag @@ -39,7 +43,7 @@ }, { "name": "PasswordImport", - // "owners": [ "your-team" ], + "owners": [ "vasilii" ], "expiry_milestone": 76 }, { @@ -79,8 +83,8 @@ }, { "name": "allow-remote-context-for-notifications", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "pshmakov", "peter" ], + "expiry_milestone": 74 }, { "name": "allow-sxg-certs-without-extension", @@ -188,6 +192,11 @@ "expiry_milestone": 76 }, { + "name": "ash-enable-pip-rounded-corners", + "owners": [ "edcourtney" ], + "expiry_milestone": 74 + }, + { "name": "ash-enable-trilinear-filtering", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -334,12 +343,12 @@ }, { "name": "cct-module-cache", - // "owners": [ "your-team" ], + "owners": [ "mvanouwerkerk" ], "expiry_milestone": 76 }, { "name": "cct-module-post-message", - // "owners": [ "your-team" ], + "owners": [ "mvanouwerkerk" ], "expiry_milestone": 76 }, { @@ -458,16 +467,6 @@ "expiry_milestone": 76 }, { - "name": "default-tile-height", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { - "name": "default-tile-width", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "device-discovery-notifications", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -689,7 +688,7 @@ }, { "name": "enable-accessibility-object-model", - // "owners": [ "your-team" ], + "owners": [ "//ui/accessibility/OWNERS" ], "expiry_milestone": 76 }, { @@ -734,8 +733,8 @@ }, { "name": "enable-app-notification-status-messaging", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "knollr", "peter" ], + "expiry_milestone": 74 }, { "name": "enable-app-shortcut-search", @@ -754,7 +753,7 @@ }, { "name": "enable-arc-cups-api", - // "owners": [ "your-team" ], + "owners": [ "luum", "skau" ], "expiry_milestone": 76 }, { @@ -924,7 +923,7 @@ }, { "name": "enable-chromeos-account-manager", - // "owners": [ "your-team" ], + "owners": [ "sinhak@chromium.org" ], "expiry_milestone": 76 }, { @@ -1114,7 +1113,7 @@ }, { "name": "enable-experimental-accessibility-features", - // "owners": [ "your-team" ], + "owners": [ "//ui/accessibility/OWNERS" ], "expiry_milestone": 76 }, { @@ -1204,12 +1203,12 @@ }, { "name": "enable-generic-sensor", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "reillyg@chromium.org", "raphael.kubo.da.costa@intel.com" ], + "expiry_milestone": 72 }, { "name": "enable-generic-sensor-extra-classes", - // "owners": [ "your-team" ], + "owners": [ "reillyg@chromium.org", "raphael.kubo.da.costa@intel.com" ], "expiry_milestone": 76 }, { @@ -1304,8 +1303,8 @@ }, { "name": "enable-layout-ng", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "layout-dev@chromium.org" ], + "expiry_milestone": 80 }, { "name": "enable-lazy-frame-loading", @@ -1359,7 +1358,7 @@ }, { "name": "enable-message-center-new-style-notification", - // "owners": [ "your-team" ], + "owners": [ "knollr", "peter" ], "expiry_milestone": 76 }, { @@ -1394,7 +1393,7 @@ }, { "name": "enable-native-notifications", - // "owners": [ "your-team" ], + "owners": [ "peter", "finnur" ], "expiry_milestone": 76 }, { @@ -1409,13 +1408,13 @@ }, { "name": "enable-new-contacts-picker", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "finnur", "peter" ], + "expiry_milestone": 74 }, { "name": "enable-new-photo-picker", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "finnur", "peter" ], + "expiry_milestone": 72 }, { "name": "enable-new-print-preview", @@ -2106,7 +2105,7 @@ }, { "name": "enforce-tls13-downgrade", - // "owners": [ "your-team" ], + "owners": [ "davidben", "svaldez" ], "expiry_milestone": 76 }, { @@ -2436,12 +2435,12 @@ }, { "name": "new-password-form-parsing", - // "owners": [ "your-team" ], + "owners": [ "dvadym" ], "expiry_milestone": 76 }, { "name": "new-password-form-parsing-for-saving", - // "owners": [ "your-team" ], + "owners": [ "dvadym" ], "expiry_milestone": 76 }, { @@ -2451,7 +2450,7 @@ }, { "name": "new-usb-backend", - // "owners": [ "your-team" ], + "owners": [ "reillyg@chromium.org" ], "expiry_milestone": 76 }, { @@ -2630,11 +2629,6 @@ "expiry_milestone": 76 }, { - "name": "omnibox-ui-elide-suggestion-url-after-host", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "omnibox-ui-hide-steady-state-url-path-query-and-ref", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -2650,11 +2644,6 @@ "expiry_milestone": 76 }, { - "name": "omnibox-ui-jog-textfield-on-popup", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "omnibox-ui-max-autocomplete-matches", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -2665,11 +2654,6 @@ "expiry_milestone": 76 }, { - "name": "omnibox-ui-show-suggestion-favicons", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "omnibox-ui-swap-title-and-url", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -2746,7 +2730,7 @@ }, { "name": "passwords-migrate-linux-to-login-db", - // "owners": [ "your-team" ], + "owners": [ "cfroussios" ], "expiry_milestone": 76 }, { @@ -2841,7 +2825,7 @@ }, { "name": "safe-browsing-use-local-blacklists-v2", - // "owners": [ "your-team" ], + "owners": [ "vakh" ], "expiry_milestone": 76 }, { @@ -3051,7 +3035,7 @@ }, { "name": "tls13-variant", - // "owners": [ "your-team" ], + "owners": [ "davidben", "svaldez" ], "expiry_milestone": 76 }, { @@ -3211,7 +3195,7 @@ }, { "name": "user-activation-v2", - // "owners": [ "your-team" ], + "owners": [ "mustaq@chromium.org" ], "expiry_milestone": 76 }, {
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 866d7bc..1a75517e 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -274,20 +274,6 @@ "Enables debugging context menu options such as Inspect Element for packed " "applications."; -const char kDefaultTileHeightName[] = "Default tile height"; -const char kDefaultTileHeightDescription[] = "Specify the default tile height."; -const char kDefaultTileHeightShort[] = "128"; -const char kDefaultTileHeightTall[] = "256"; -const char kDefaultTileHeightGrande[] = "512"; -const char kDefaultTileHeightVenti[] = "1024"; - -const char kDefaultTileWidthName[] = "Default tile width"; -const char kDefaultTileWidthDescription[] = "Specify the default tile width."; -const char kDefaultTileWidthShort[] = "128"; -const char kDefaultTileWidthTall[] = "256"; -const char kDefaultTileWidthGrande[] = "512"; -const char kDefaultTileWidthVenti[] = "1024"; - const char kDebugShortcutsName[] = "Debugging keyboard shortcuts"; const char kDebugShortcutsDescription[] = "Enables additional keyboard shortcuts that are useful for debugging Ash."; @@ -1349,12 +1335,6 @@ "When the omnibox is focused, start an empty spare renderer. This can " "speed up the load of the navigation from the omnibox."; -const char kOmniboxUIElideSuggestionUrlAfterHostName[] = - "Omnibox UI Elide Suggestion URL After Host"; -const char kOmniboxUIElideSuggestionUrlAfterHostDescription[] = - "Elides the path, query, and ref of suggested URLs in the Omnibox " - "dropdown."; - const char kOmniboxUIHideSteadyStateUrlSchemeName[] = "Omnibox UI Hide Steady-State URL Scheme"; const char kOmniboxUIHideSteadyStateUrlSchemeDescription[] = @@ -1377,14 +1357,6 @@ "In the omnibox, hide the path, query and ref from steady state displayed " "URLs. Hidden portions are restored during editing."; -const char kOmniboxUIJogTextfieldOnPopupName[] = - "Omnibox UI Jog Textfield on Popup"; -const char kOmniboxUIJogTextfieldOnPopupDescription[] = - "In the Omnibox, jog the textfield to align with the dropdown suggestions " - "text when the popup is opened. When this feature is disabled, the " - "textfield is always aligned with the suggestions text, and a separator " - "fills the gap. If Material Refresh is disabled, this has no effect."; - const char kOmniboxUIMaxAutocompleteMatchesName[] = "Omnibox UI Max Autocomplete Matches"; @@ -1392,12 +1364,6 @@ "Changes the maximum number of autocomplete matches displayed in the " "Omnibox UI."; -const char kOmniboxUIShowSuggestionFaviconsName[] = - "Omnibox UI Show Suggestion Favicons"; -const char kOmniboxUIShowSuggestionFaviconsDescription[] = - "Shows favicons instead of generic vector icons for URL suggestions in the " - "Omnibox dropdown."; - const char kOmniboxUISwapTitleAndUrlName[] = "Omnibox UI Swap Title and URL"; const char kOmniboxUISwapTitleAndUrlDescription[] = "In the omnibox dropdown, shows titles before URLs when both are " @@ -1868,11 +1834,6 @@ const char kTabsInCbdDescription[] = "Enables a basic and an advanced tab for the Clear Browsing Data dialog."; -const char kTabModalJsDialogName[] = "Auto-dismissing JavaScript Dialogs"; -const char kTabModalJsDialogDescription[] = - "If enabled, the JavaScript dialog will be auto dismissable when switching" - " tab."; - const char kTcpFastOpenName[] = "TCP Fast Open"; const char kTcpFastOpenDescription[] = "Enable the option to send extra authentication information in the initial " @@ -3152,6 +3113,11 @@ const char kAshEnablePersistentWindowBoundsDescription[] = "Enable persistent window bounds in multi-displays scenario."; +const char kAshEnablePipRoundedCornersName[] = + "Enable Picture-in-Picture rounded corners."; +const char kAshEnablePipRoundedCornersDescription[] = + "Enable rounded corners on the Picture-in-Picture window."; + const char kAshEnableTrilinearFilteringName[] = "Enable trilinear filtering."; const char kAshEnableTrilinearFilteringDescription[] = "Enable trilinear filtering.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index db2d9ff..50b87180 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -195,20 +195,6 @@ extern const char kDebugPackedAppName[]; extern const char kDebugPackedAppDescription[]; -extern const char kDefaultTileHeightName[]; -extern const char kDefaultTileHeightDescription[]; -extern const char kDefaultTileHeightShort[]; -extern const char kDefaultTileHeightTall[]; -extern const char kDefaultTileHeightGrande[]; -extern const char kDefaultTileHeightVenti[]; - -extern const char kDefaultTileWidthName[]; -extern const char kDefaultTileWidthDescription[]; -extern const char kDefaultTileWidthShort[]; -extern const char kDefaultTileWidthTall[]; -extern const char kDefaultTileWidthGrande[]; -extern const char kDefaultTileWidthVenti[]; - extern const char kDebugShortcutsName[]; extern const char kDebugShortcutsDescription[]; @@ -831,9 +817,6 @@ extern const char kOmniboxSpareRendererName[]; extern const char kOmniboxSpareRendererDescription[]; -extern const char kOmniboxUIElideSuggestionUrlAfterHostName[]; -extern const char kOmniboxUIElideSuggestionUrlAfterHostDescription[]; - extern const char kOmniboxUIHideSteadyStateUrlSchemeName[]; extern const char kOmniboxUIHideSteadyStateUrlSchemeDescription[]; @@ -846,15 +829,9 @@ extern const char kOmniboxUIOneClickUnelideName[]; extern const char kOmniboxUIOneClickUnelideDescription[]; -extern const char kOmniboxUIJogTextfieldOnPopupName[]; -extern const char kOmniboxUIJogTextfieldOnPopupDescription[]; - extern const char kOmniboxUIMaxAutocompleteMatchesName[]; extern const char kOmniboxUIMaxAutocompleteMatchesDescription[]; -extern const char kOmniboxUIShowSuggestionFaviconsName[]; -extern const char kOmniboxUIShowSuggestionFaviconsDescription[]; - extern const char kOmniboxUISwapTitleAndUrlName[]; extern const char kOmniboxUISwapTitleAndUrlDescription[]; @@ -1130,9 +1107,6 @@ extern const char kSysInternalsName[]; extern const char kSysInternalsDescription[]; -extern const char kTabModalJsDialogName[]; -extern const char kTabModalJsDialogDescription[]; - extern const char kTabsInCbdName[]; extern const char kTabsInCbdDescription[]; @@ -1897,6 +1871,9 @@ extern const char kAshEnablePersistentWindowBoundsName[]; extern const char kAshEnablePersistentWindowBoundsDescription[]; +extern const char kAshEnablePipRoundedCornersName[]; +extern const char kAshEnablePipRoundedCornersDescription[]; + extern const char kAshEnableTrilinearFilteringName[]; extern const char kAshEnableTrilinearFilteringDescription[];
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc index 38f0f3ab..b3aa7f13 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.cc +++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -301,9 +301,6 @@ // When metrics reporting is enabled, register the notification_helper metrics // files; otherwise delete any existing files in order to preserve user // privacy. - // TODO(chengx): Investigate if there is a need to update - // RegisterOrRemovePreviousRunMetricsFile and apply it here to remove - // potential duplicate code. if (!user_data_dir.empty()) { base::FilePath notification_helper_metrics_upload_dir = user_data_dir.AppendASCII(
diff --git a/chrome/browser/metrics/ukm_browsertest.cc b/chrome/browser/metrics/ukm_browsertest.cc index 79cc299..33abd1e 100644 --- a/chrome/browser/metrics/ukm_browsertest.cc +++ b/chrome/browser/metrics/ukm_browsertest.cc
@@ -35,6 +35,7 @@ #include "components/ukm/ukm_service.h" #include "components/unified_consent/feature.h" #include "components/unified_consent/scoped_unified_consent.h" +#include "components/unified_consent/unified_consent_service.h" #include "components/variations/service/variations_field_trial_creator.h" #include "components/version_info/version_info.h" #include "content/public/browser/browsing_data_remover.h" @@ -220,7 +221,8 @@ protected: std::unique_ptr<ProfileSyncServiceHarness> EnableSyncForProfile( Profile* profile) { - UnifiedConsentServiceFactory::GetForProfile(profile); + unified_consent::UnifiedConsentService* consent_service = + UnifiedConsentServiceFactory::GetForProfile(profile); browser_sync::ProfileSyncService* sync_service = ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile); @@ -245,6 +247,11 @@ profile, username, "unused" /* password */, ProfileSyncServiceHarness::SigninType::FAKE_SIGNIN); EXPECT_TRUE(harness->SetupSync()); + // Opt into unified consent if possible, so url-keyed-anonymized data + // collection is enabled. Note: If the consent service is not available, UKM + // will fall back on the state of history sync. + if (consent_service) + consent_service->SetUnifiedConsentGiven(true); return harness; }
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_browsertest.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_browsertest.cc index 2aa6bef0..90d0a8e7 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_browsertest.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_browsertest.cc
@@ -438,6 +438,23 @@ } IN_PROC_BROWSER_TEST_F(DataReductionProxyFallbackBrowsertest, + BadProxiesResetWhenDisabled) { + SetHeader("bypass=100"); + ui_test_utils::NavigateToURL( + browser(), GURL("http://does.not.resolve/echoheader?Chrome-Proxy")); + EXPECT_THAT(GetBody(), kSecondaryResponse); + + // Disabling and enabling DRP should clear the bypass. + EnableDataSaver(false); + EnableDataSaver(true); + + SetHeader(""); + ui_test_utils::NavigateToURL( + browser(), GURL("http://does.not.resolve/echoheader?Chrome-Proxy")); + EXPECT_THAT(GetBody(), kPrimaryResponse); +} + +IN_PROC_BROWSER_TEST_F(DataReductionProxyFallbackBrowsertest, NoProxyUsedWhenBlockOnceHeaderSent) { net::EmbeddedTestServer test_server; test_server.RegisterRequestHandler(
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index 941eaba..0fe160d 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -429,9 +429,8 @@ if (!PasswordAccessoryController::AllowedForWebContents(web_contents())) { return; // No need to even create the bridge if it's not going to be used. } - // If an accessory exists already, |CreateForWebContents| is a NoOp - PasswordAccessoryController::CreateForWebContents(web_contents()); - PasswordAccessoryController::FromWebContents(web_contents()) + + PasswordAccessoryController::GetOrCreate(web_contents()) ->SavePasswordsForOrigin(best_matches, url::Origin::Create(origin)); #else // !defined(OS_ANDROID) PasswordsClientUIDelegate* manage_passwords_ui_controller = @@ -526,7 +525,7 @@ web_contents()->GetRenderViewHost()->GetWidget(), this); #else // defined(OS_ANDROID) PasswordAccessoryController* accessory = - PasswordAccessoryController::FromWebContents(web_contents()); + PasswordAccessoryController::GetIfExisting(web_contents()); if (accessory) accessory->DidNavigateMainFrame(); #endif // defined(OS_ANDROID) @@ -672,7 +671,6 @@ // Either #passwords-keyboards-accessory or #experimental-ui must be enabled. if (PasswordAccessoryController::AllowedForWebContents(web_contents())) { if (available) { - PasswordAccessoryController::CreateForWebContents(web_contents()); password_manager::PasswordManagerDriver* driver = driver_factory_->GetDriverForFrame( password_manager_client_bindings_.GetCurrentTargetFrame()); @@ -681,7 +679,7 @@ driver, ui_data.value().password_form, ui_data.value().generation_element, false /* is_manually_triggered */); - PasswordAccessoryController::FromWebContents(web_contents()) + PasswordAccessoryController::GetOrCreate(web_contents()) ->OnAutomaticGenerationStatusChanged(true, ui_data, driver->AsWeakPtr()); gfx::RectF element_bounds_in_screen_space = TransformToRootCoordinates( @@ -691,7 +689,7 @@ element_bounds_in_screen_space, ui_data.value().text_direction); } else { PasswordAccessoryController* accessory = - PasswordAccessoryController::FromWebContents(web_contents()); + PasswordAccessoryController::GetIfExisting(web_contents()); if (accessory) { accessory->OnAutomaticGenerationStatusChanged(false, base::nullopt, nullptr); @@ -1066,19 +1064,22 @@ } if (is_password_field) { DCHECK(is_fillable); - PasswordAccessoryController::CreateForWebContents(web_contents()); PasswordAccessoryController* accessory = - PasswordAccessoryController::FromWebContents(web_contents()); + PasswordAccessoryController::GetOrCreate(web_contents()); accessory->RefreshSuggestionsForField( password_manager_driver_bindings_.GetCurrentTargetFrame() ->GetLastCommittedOrigin(), is_fillable, is_password_field); + // TODO(crbug.com/905669): Move all the logic to control accessory + // visibility to ManualFillingController. accessory->ShowWhenKeyboardIsVisible(); } else { // If not a password field, only update the accessory if one exists. PasswordAccessoryController* accessory = - PasswordAccessoryController::FromWebContents(web_contents()); + PasswordAccessoryController::GetIfExisting(web_contents()); if (accessory) { + // TODO(crbug.com/905669): Move all the logic to control accessory + // visibility to ManualFillingController. accessory->Hide(); } }
diff --git a/chrome/browser/password_manager/password_accessory_controller.h b/chrome/browser/password_manager/password_accessory_controller.h index 5eb37a7f..5a8eaed0 100644 --- a/chrome/browser/password_manager/password_accessory_controller.h +++ b/chrome/browser/password_manager/password_accessory_controller.h
@@ -7,232 +7,134 @@ #include <map> #include <memory> -#include <utility> -#include <vector> #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" -#include "base/task/cancelable_task_tracker.h" -#include "chrome/browser/password_manager/password_accessory_view_interface.h" -#include "components/autofill/core/browser/accessory_sheet_data.h" #include "components/autofill/core/common/filling_status.h" #include "components/autofill/core/common/password_generation_util.h" -#include "components/favicon_base/favicon_types.h" -#include "content/public/browser/browser_context.h" #include "content/public/browser/web_contents_user_data.h" -#include "ui/gfx/native_widget_types.h" +#include "ui/gfx/image/image.h" #include "url/gurl.h" namespace autofill { struct PasswordForm; } // namespace autofill -namespace favicon { -class FaviconService; -} - namespace password_manager { class PasswordManagerDriver; } // namespace password_manager -class PasswordGenerationDialogViewInterface; - -// The controller for the view located below the keyboard accessory. -// Upon creation, it creates (and owns) a corresponding PasswordAccessoryView. -// This view will be provided with data and will notify this controller about -// interactions (like requesting to fill a password suggestions). +// Interface for password-specific keyboard accessory controller between the +// ManualFillingController and PasswordManagerClient. // -// Create it for a WebContents instance by calling: -// PasswordAccessoryController::CreateForWebContents(web_contents); -// After that, it's attached to the |web_contents| instance and can be retrieved -// by calling: -// PasswordAccessoryController::FromWebContents(web_contents); -// Any further calls to |CreateForWebContents| will be a noop. -// -// TODO(fhorschig): This class currently only supports credentials originating -// from the main frame. Supporting iframes is intended: https://crbug.com/854150 +// There is a single instance per WebContents that can be accessed by calling: +// PasswordAccessoryController::GetOrCreate(web_contents); +// On the first call, an instance is attached to |web_contents|, so it can be +// returned by subsequent calls. class PasswordAccessoryController - : public content::WebContentsUserData<PasswordAccessoryController> { + : public base::SupportsWeakPtr<PasswordAccessoryController> { public: - using CreateDialogFactory = base::RepeatingCallback<std::unique_ptr< - PasswordGenerationDialogViewInterface>(PasswordAccessoryController*)>; - ~PasswordAccessoryController() override; + PasswordAccessoryController() = default; + virtual ~PasswordAccessoryController() = default; + + // Returns true if the accessory controller may exist for |web_contents|. + // Otherwise (e.g. if VR is enabled), it returns false. + static bool AllowedForWebContents(content::WebContents* web_contents); + + // Returns a reference to the unique PasswordAccessoryController associated + // with |web_contents|. A new instance is created if the first time this + // function is called. Only valid to be called if + // |PasswordAccessoryController::AllowedForWebContents(web_contents)|. + static PasswordAccessoryController* GetOrCreate( + content::WebContents* web_contents); + + // Returns a reference to the unique PasswordAccessoryController associated + // with |web_contents|. Returns null if no such instance exists. + static PasswordAccessoryController* GetIfExisting( + content::WebContents* web_contents); // ----------------------------- // Methods called by the client: // ----------------------------- - // Returns true, if the accessory controller may exist for |web_contents|. - // Otherwise (e.g. if VR is enabled), it returns false. - static bool AllowedForWebContents(content::WebContents* web_contents); - // Saves credentials for an origin so that they can be used in the sheet. - void SavePasswordsForOrigin( + virtual void SavePasswordsForOrigin( const std::map<base::string16, const autofill::PasswordForm*>& best_matches, - const url::Origin& origin); + const url::Origin& origin) = 0; // Notifies the view that automatic password generation status changed. - void OnAutomaticGenerationStatusChanged( + virtual void OnAutomaticGenerationStatusChanged( bool available, const base::Optional< autofill::password_generation::PasswordGenerationUIData>& ui_data, - const base::WeakPtr<password_manager::PasswordManagerDriver>& driver); + const base::WeakPtr<password_manager::PasswordManagerDriver>& driver) = 0; // Completes a filling attempt by recording metrics, giving feedback to the // user and dismissing the accessory sheet. - void OnFilledIntoFocusedField(autofill::FillingStatus status); + virtual void OnFilledIntoFocusedField(autofill::FillingStatus status) = 0; // Makes sure, that all shown suggestions are appropriate for the currently // focused field and for fields that lost the focus. If a field lost focus, // |is_fillable| will be false. - void RefreshSuggestionsForField(const url::Origin& origin, - bool is_fillable, - bool is_password_field); + virtual void RefreshSuggestionsForField(const url::Origin& origin, + bool is_fillable, + bool is_password_field) = 0; // Reacts to a navigation on the main frame, e.g. by clearing caches. - void DidNavigateMainFrame(); + virtual void DidNavigateMainFrame() = 0; // Requests to show the accessory bar. The accessory will only be shown // when the keyboard becomes visible. - void ShowWhenKeyboardIsVisible(); + virtual void ShowWhenKeyboardIsVisible() = 0; // Requests to hide the accessory. This hides both the accessory sheet // (if open) and the accessory bar. - void Hide(); + virtual void Hide() = 0; // -------------------------- // Methods called by UI code: // -------------------------- - // Uses the give |favicon_service| to get an icon for the currently focused - // frame. The given callback is called with an image unless an icon for a new - // origin was called. In the latter case, the callback is dropped. + // Gets an icon for the currently focused frame and passes it to + // |icon_callback|. The callback is invoked with an image unless an icon for + // a new origin was called. In the latter case, the callback is dropped. // The callback is called with an |IsEmpty()| image if there is no favicon. - void GetFavicon(int desired_size_in_pixel, - base::OnceCallback<void(const gfx::Image&)> icon_callback); + virtual void GetFavicon( + int desired_size_in_pixel, + base::OnceCallback<void(const gfx::Image&)> icon_callback) = 0; - // Called by the UI code to request that |textToFill| is to be filled into the - // currently focused field. - void OnFillingTriggered(bool is_password, const base::string16& textToFill); + // Called by the UI code to request that |text_to_fill| is to be filled into + // the currently focused field. + virtual void OnFillingTriggered(bool is_password, + const base::string16& text_to_fill) = 0; - // Called by the UI code because a user triggered the |selectedOption|. - void OnOptionSelected(const base::string16& selectedOption) const; + // Called by the UI code because a user triggered the |selected_option|, + // such as "Manage passwords..." + // TODO(crbug.com/905669): Replace the string param with an enum to indicate + // the selected option. + virtual void OnOptionSelected( + const base::string16& selected_option) const = 0; // Called by the UI code to signal that the user requested password // generation. This should prompt a modal dialog with the generated password. - void OnGenerationRequested(); + virtual void OnGenerationRequested() = 0; // Called from the modal dialog if the user accepted the generated password. - void GeneratedPasswordAccepted(const base::string16& password); + virtual void GeneratedPasswordAccepted(const base::string16& password) = 0; // Called from the modal dialog if the user rejected the generated password. - void GeneratedPasswordRejected(); + virtual void GeneratedPasswordRejected() = 0; // ----------------- // Member accessors: // ----------------- - // The web page view containing the focused field. - gfx::NativeView container_view() const; - - gfx::NativeWindow native_window() const; - - // Like |CreateForWebContents|, it creates the controller and attaches it to - // the given |web_contents|. Additionally, it allows inject a fake/mock view. - static void CreateForWebContentsForTesting( - content::WebContents* web_contents, - std::unique_ptr<PasswordAccessoryViewInterface> test_view, - CreateDialogFactory create_dialog_callback, - favicon::FaviconService* favicon_service); - -#if defined(UNIT_TEST) - // Returns the held view for testing. - PasswordAccessoryViewInterface* view() const { return view_.get(); } -#endif // defined(UNIT_TEST) + virtual gfx::NativeWindow native_window() const = 0; private: - // Data including the form and field for which generation was requested, - // their signatures and the maximum password size. - struct GenerationElementData; - - // Data for a credential pair that is transformed into a suggestion. - struct SuggestionElementData; - - // Data allowing to cache favicons and favicon-related requests. - struct FaviconRequestData; - - // Required for construction via |CreateForWebContents|: - explicit PasswordAccessoryController(content::WebContents* contents); - friend class content::WebContentsUserData<PasswordAccessoryController>; - - // Constructor that allows to inject a mock or fake view. - PasswordAccessoryController( - content::WebContents* web_contents, - std::unique_ptr<PasswordAccessoryViewInterface> view, - CreateDialogFactory create_dialog_callback, - favicon::FaviconService* favicon_service); - - // Creates the view items based on the given |suggestions|. - // If |is_password_field| is false, password suggestions won't be interactive. - static autofill::AccessorySheetData CreateAccessorySheetData( - const url::Origin& origin, - const std::vector<SuggestionElementData>& suggestions, - bool is_password_field); - - // Handles a favicon response requested by |GetFavicon| and calls the waiting - // last_icon_callback_ with a (possibly empty) icon bitmap. - void OnImageFetched( - url::Origin origin, - const favicon_base::FaviconRawBitmapResult& bitmap_results); - - // Contains the last set of credentials by origin. - std::map<url::Origin, std::vector<SuggestionElementData>> origin_suggestions_; - - // The tab for which this class is scoped. - content::WebContents* web_contents_; - - // Data for the generation element used to generate the password. - std::unique_ptr<GenerationElementData> generation_element_data_; - - // The origin of the currently focused frame. It's used to ensure that - // favicons are not displayed across origins. - url::Origin current_origin_; - - // TODO(fhorschig): Find a way to use unordered_map with origin keys. - // A cache for all favicons that were requested. This includes all iframes - // for which the accessory was displayed. - std::map<url::Origin, FaviconRequestData> icons_request_data_; - - // Used to track a requested favicon. If the set of suggestion changes, this - // object aborts the request. Upon destruction, requests are cancelled, too. - base::CancelableTaskTracker favicon_tracker_; - - // Password manager driver for the target frame used for password generation. - base::WeakPtr<password_manager::PasswordManagerDriver> target_frame_driver_; - - // Modal dialog view meant to display the generated password. - std::unique_ptr<PasswordGenerationDialogViewInterface> dialog_view_; - - // Remembers whether the last focused field was a password field. That way, - // the reconstructed elements have the correct type. - bool last_focused_field_was_for_passwords_ = false; - - // Hold the native instance of the view. Must be last declared and initialized - // member so the view can be created in the constructor with a fully set up - // controller instance. - std::unique_ptr<PasswordAccessoryViewInterface> view_; - - // Creation callback for the modal dialog view meant to facilitate testing. - CreateDialogFactory create_dialog_factory_; - - // The favicon service used to make retrieve icons for a given origin. - favicon::FaviconService* favicon_service_; - - base::WeakPtrFactory<PasswordAccessoryController> weak_factory_; - DISALLOW_COPY_AND_ASSIGN(PasswordAccessoryController); };
diff --git a/chrome/browser/password_manager/password_accessory_controller.cc b/chrome/browser/password_manager/password_accessory_controller_impl.cc similarity index 75% rename from chrome/browser/password_manager/password_accessory_controller.cc rename to chrome/browser/password_manager/password_accessory_controller_impl.cc index 9317a66..7f30c0fd 100644 --- a/chrome/browser/password_manager/password_accessory_controller.cc +++ b/chrome/browser/password_manager/password_accessory_controller_impl.cc
@@ -2,14 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/password_manager/password_accessory_controller.h" +#include "chrome/browser/password_manager/password_accessory_controller_impl.h" -#include <vector> +#include <utility> #include "base/callback.h" #include "base/metrics/histogram_macros.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/android/preferences/preferences_launcher.h" +#include "chrome/browser/autofill/manual_filling_controller.h" #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/password_manager/password_accessory_metrics_util.h" #include "chrome/browser/password_manager/password_generation_dialog_view_interface.h" @@ -17,8 +18,6 @@ #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" #include "chrome/browser/vr/vr_tab_helper.h" #include "chrome/grit/generated_resources.h" -#include "components/autofill/content/browser/content_autofill_driver.h" -#include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/autofill/core/common/password_form.h" #include "components/autofill/core/common/password_generation_util.h" #include "components/favicon/core/favicon_service.h" @@ -27,7 +26,6 @@ #include "components/password_manager/content/browser/content_password_manager_driver_factory.h" #include "components/password_manager/core/browser/password_manager_driver.h" #include "components/password_manager/core/common/password_manager_features.h" -#include "components/strings/grit/components_strings.h" #include "content/public/browser/web_contents.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/ui_base_features.h" @@ -45,7 +43,37 @@ } // namespace -struct PasswordAccessoryController::GenerationElementData { +PasswordAccessoryControllerImpl::~PasswordAccessoryControllerImpl() = default; + +// static +bool PasswordAccessoryController::AllowedForWebContents( + content::WebContents* web_contents) { + DCHECK(web_contents) << "Need valid WebContents to attach controller to!"; + if (vr::VrTabHelper::IsInVr(web_contents)) { + return false; // TODO(crbug.com/865749): Reenable if works for VR keyboard. + } + // Either #passwords-keyboards-accessory or #experimental-ui must be enabled. + return base::FeatureList::IsEnabled( + password_manager::features::kPasswordsKeyboardAccessory) || + base::FeatureList::IsEnabled(features::kExperimentalUi); +} + +// static +PasswordAccessoryController* PasswordAccessoryController::GetOrCreate( + content::WebContents* web_contents) { + DCHECK(PasswordAccessoryController::AllowedForWebContents(web_contents)); + + PasswordAccessoryControllerImpl::CreateForWebContents(web_contents); + return PasswordAccessoryControllerImpl::FromWebContents(web_contents); +} + +// static +PasswordAccessoryController* PasswordAccessoryController::GetIfExisting( + content::WebContents* web_contents) { + return PasswordAccessoryControllerImpl::FromWebContents(web_contents); +} + +struct PasswordAccessoryControllerImpl::GenerationElementData { GenerationElementData(autofill::PasswordForm form, autofill::FormSignature form_signature, autofill::FieldSignature field_signature, @@ -68,7 +96,7 @@ uint32_t max_password_length; }; -struct PasswordAccessoryController::SuggestionElementData { +struct PasswordAccessoryControllerImpl::SuggestionElementData { SuggestionElementData(base::string16 password, base::string16 username, bool username_selectable) @@ -86,7 +114,7 @@ bool username_selectable; }; -struct PasswordAccessoryController::FaviconRequestData { +struct PasswordAccessoryControllerImpl::FaviconRequestData { // List of requests waiting for favicons to be available. std::vector<base::OnceCallback<void(const gfx::Image&)>> pending_requests; @@ -94,59 +122,23 @@ gfx::Image cached_icon; }; -PasswordAccessoryController::PasswordAccessoryController( - content::WebContents* web_contents) - : web_contents_(web_contents), - view_(PasswordAccessoryViewInterface::Create(this)), - create_dialog_factory_( - base::BindRepeating(&PasswordGenerationDialogViewInterface::Create)), - favicon_service_(FaviconServiceFactory::GetForProfile( - Profile::FromBrowserContext(web_contents->GetBrowserContext()), - ServiceAccessType::EXPLICIT_ACCESS)), - weak_factory_(this) {} - -// Additional creation functions in unit tests only: -PasswordAccessoryController::PasswordAccessoryController( - content::WebContents* web_contents, - std::unique_ptr<PasswordAccessoryViewInterface> view, - CreateDialogFactory create_dialog_factory, - favicon::FaviconService* favicon_service) - : web_contents_(web_contents), - view_(std::move(view)), - create_dialog_factory_(create_dialog_factory), - favicon_service_(favicon_service), - weak_factory_(this) {} - -PasswordAccessoryController::~PasswordAccessoryController() = default; - // static -bool PasswordAccessoryController::AllowedForWebContents( - content::WebContents* web_contents) { - DCHECK(web_contents) << "Need valid WebContents to attach controller to!"; - if (vr::VrTabHelper::IsInVr(web_contents)) { - return false; // TODO(crbug.com/865749): Reenable if works for VR keyboard. - } - // Either #passwords-keyboards-accessory or #experimental-ui must be enabled. - return base::FeatureList::IsEnabled( - password_manager::features::kPasswordsKeyboardAccessory) || - base::FeatureList::IsEnabled(features::kExperimentalUi); -} - -// static -void PasswordAccessoryController::CreateForWebContentsForTesting( +void PasswordAccessoryControllerImpl::CreateForWebContentsForTesting( content::WebContents* web_contents, - std::unique_ptr<PasswordAccessoryViewInterface> view, + base::WeakPtr<ManualFillingController> mf_controller, CreateDialogFactory create_dialog_factory, favicon::FaviconService* favicon_service) { DCHECK(web_contents) << "Need valid WebContents to attach controller to!"; DCHECK(!FromWebContents(web_contents)) << "Controller already attached!"; + DCHECK(mf_controller); + web_contents->SetUserData( - UserDataKey(), base::WrapUnique(new PasswordAccessoryController( - web_contents, std::move(view), create_dialog_factory, - favicon_service))); + UserDataKey(), base::WrapUnique(new PasswordAccessoryControllerImpl( + web_contents, std::move(mf_controller), + create_dialog_factory, favicon_service))); } -void PasswordAccessoryController::SavePasswordsForOrigin( +void PasswordAccessoryControllerImpl::SavePasswordsForOrigin( const std::map<base::string16, const PasswordForm*>& best_matches, const url::Origin& origin) { std::vector<SuggestionElementData>* suggestions = @@ -159,11 +151,13 @@ } } -void PasswordAccessoryController::OnAutomaticGenerationStatusChanged( +void PasswordAccessoryControllerImpl::OnAutomaticGenerationStatusChanged( bool available, const base::Optional< autofill::password_generation::PasswordGenerationUIData>& ui_data, const base::WeakPtr<password_manager::PasswordManagerDriver>& driver) { + DCHECK(mf_controller_); + target_frame_driver_ = driver; if (available) { DCHECK(ui_data.has_value()); @@ -177,51 +171,66 @@ } else { generation_element_data_.reset(); } - DCHECK(view_); - view_->OnAutomaticGenerationStatusChanged(available); + + mf_controller_->OnAutomaticGenerationStatusChanged(available); } -void PasswordAccessoryController::OnFilledIntoFocusedField( +void PasswordAccessoryControllerImpl::OnFilledIntoFocusedField( autofill::FillingStatus status) { - if (status != autofill::FillingStatus::SUCCESS) - return; // TODO(crbug/853766): Record success rate. - view_->SwapSheetWithKeyboard(); + DCHECK(mf_controller_); + + mf_controller_->OnFilledIntoFocusedField(status); } -void PasswordAccessoryController::RefreshSuggestionsForField( - const url::Origin& origin, - bool is_fillable, - bool is_password_field) { - if (is_fillable) { - current_origin_ = origin; - view_->OnItemsAvailable(CreateAccessorySheetData( - origin, origin_suggestions_[origin], is_password_field)); - view_->SwapSheetWithKeyboard(); - } else { - // For unfillable fields, reset the origin and send the empty state message. - current_origin_ = url::Origin(); - view_->OnItemsAvailable(CreateAccessorySheetData( - origin, std::vector<SuggestionElementData>(), is_password_field)); - view_->CloseAccessorySheet(); +void PasswordAccessoryControllerImpl::OnOptionSelected( + const base::string16& selected_option) const { + // TODO(crbug.com/905669): This shouldn't rely on the selection name and + // metrics::AccessoryAction shouldn't be password-specific. + if (selected_option == + l10n_util::GetStringUTF16( + IDS_PASSWORD_MANAGER_ACCESSORY_ALL_PASSWORDS_LINK)) { + UMA_HISTOGRAM_ENUMERATION("KeyboardAccessory.AccessoryActionSelected", + metrics::AccessoryAction::MANAGE_PASSWORDS, + metrics::AccessoryAction::COUNT); + chrome::android::PreferencesLauncher::ShowPasswordSettings(web_contents_); } } -void PasswordAccessoryController::DidNavigateMainFrame() { +void PasswordAccessoryControllerImpl::RefreshSuggestionsForField( + const url::Origin& origin, + bool is_fillable, + bool is_password_field) { + DCHECK(mf_controller_); + + current_origin_ = is_fillable ? origin : url::Origin(); + mf_controller_->RefreshSuggestionsForField( + is_fillable, CreateAccessorySheetData( + origin, + is_fillable ? origin_suggestions_[origin] + : std::vector<SuggestionElementData>(), + is_password_field)); +} + +void PasswordAccessoryControllerImpl::DidNavigateMainFrame() { favicon_tracker_.TryCancelAll(); // If there is a request pending, cancel it. current_origin_ = url::Origin(); icons_request_data_.clear(); origin_suggestions_.clear(); } -void PasswordAccessoryController::ShowWhenKeyboardIsVisible() { - view_->ShowWhenKeyboardIsVisible(); +void PasswordAccessoryControllerImpl::ShowWhenKeyboardIsVisible() { + DCHECK(mf_controller_); + + mf_controller_->ShowWhenKeyboardIsVisible(); } -void PasswordAccessoryController::Hide() { - view_->Hide(); +void PasswordAccessoryControllerImpl::Hide() { + DCHECK(mf_controller_); + + mf_controller_->Hide(); } -void PasswordAccessoryController::GetFavicon( +void PasswordAccessoryControllerImpl::GetFavicon( int desired_size_in_pixel, base::OnceCallback<void(const gfx::Image&)> icon_callback) { url::Origin origin = current_origin_; // Copy origin in case it changes. @@ -247,14 +256,14 @@ desired_size_in_pixel, /* fallback_to_host = */ false, base::BindRepeating( // FaviconService doesn't support BindOnce yet. - &PasswordAccessoryController::OnImageFetched, - weak_factory_.GetWeakPtr(), origin), + &PasswordAccessoryControllerImpl::OnImageFetched, + base::AsWeakPtr<PasswordAccessoryControllerImpl>(this), origin), &favicon_tracker_); } -void PasswordAccessoryController::OnFillingTriggered( +void PasswordAccessoryControllerImpl::OnFillingTriggered( bool is_password, - const base::string16& textToFill) { + const base::string16& text_to_fill) { password_manager::ContentPasswordManagerDriverFactory* factory = password_manager::ContentPasswordManagerDriverFactory::FromWebContents( web_contents_); @@ -266,24 +275,12 @@ return; } // |driver| can be NULL if the tab is being closed. driver->FillIntoFocusedField( - is_password, textToFill, - base::BindOnce(&PasswordAccessoryController::OnFilledIntoFocusedField, - weak_factory_.GetWeakPtr())); + is_password, text_to_fill, + base::BindOnce(&PasswordAccessoryControllerImpl::OnFilledIntoFocusedField, + base::AsWeakPtr<PasswordAccessoryControllerImpl>(this))); } -void PasswordAccessoryController::OnOptionSelected( - const base::string16& selectedOption) const { - if (selectedOption == - l10n_util::GetStringUTF16( - IDS_PASSWORD_MANAGER_ACCESSORY_ALL_PASSWORDS_LINK)) { - UMA_HISTOGRAM_ENUMERATION("KeyboardAccessory.AccessoryActionSelected", - metrics::AccessoryAction::MANAGE_PASSWORDS, - metrics::AccessoryAction::COUNT); - chrome::android::PreferencesLauncher::ShowPasswordSettings(web_contents_); - } -} - -void PasswordAccessoryController::OnGenerationRequested() { +void PasswordAccessoryControllerImpl::OnGenerationRequested() { if (!target_frame_driver_) return; // TODO(crbug.com/835234): Take the modal dialog logic out of the accessory @@ -304,7 +301,7 @@ dialog_view_->Show(password); } -void PasswordAccessoryController::GeneratedPasswordAccepted( +void PasswordAccessoryControllerImpl::GeneratedPasswordAccepted( const base::string16& password) { if (!target_frame_driver_) return; @@ -313,21 +310,39 @@ dialog_view_.reset(); } -void PasswordAccessoryController::GeneratedPasswordRejected() { +void PasswordAccessoryControllerImpl::GeneratedPasswordRejected() { RecordGenerationDialogDismissal(false); dialog_view_.reset(); } -gfx::NativeView PasswordAccessoryController::container_view() const { - return web_contents_->GetNativeView(); -} - -gfx::NativeWindow PasswordAccessoryController::native_window() const { +gfx::NativeWindow PasswordAccessoryControllerImpl::native_window() const { return web_contents_->GetTopLevelNativeWindow(); } +PasswordAccessoryControllerImpl::PasswordAccessoryControllerImpl( + content::WebContents* web_contents) + : web_contents_(web_contents), + create_dialog_factory_( + base::BindRepeating(&PasswordGenerationDialogViewInterface::Create)), + favicon_service_(FaviconServiceFactory::GetForProfile( + Profile::FromBrowserContext(web_contents->GetBrowserContext()), + ServiceAccessType::EXPLICIT_ACCESS)) { + mf_controller_ = ManualFillingController::GetOrCreate(web_contents); +} + +// Additional creation functions in unit tests only: +PasswordAccessoryControllerImpl::PasswordAccessoryControllerImpl( + content::WebContents* web_contents, + base::WeakPtr<ManualFillingController> mf_controller, + CreateDialogFactory create_dialog_factory, + favicon::FaviconService* favicon_service) + : web_contents_(web_contents), + mf_controller_(std::move(mf_controller)), + create_dialog_factory_(create_dialog_factory), + favicon_service_(favicon_service) {} + // static -AccessorySheetData PasswordAccessoryController::CreateAccessorySheetData( +AccessorySheetData PasswordAccessoryControllerImpl::CreateAccessorySheetData( const url::Origin& origin, const std::vector<SuggestionElementData>& suggestions, bool is_password_field) { @@ -365,7 +380,7 @@ return data; } -void PasswordAccessoryController::OnImageFetched( +void PasswordAccessoryControllerImpl::OnImageFetched( url::Origin origin, const favicon_base::FaviconRawBitmapResult& bitmap_result) { FaviconRequestData* icon_request = &icons_request_data_[origin];
diff --git a/chrome/browser/password_manager/password_accessory_controller_impl.h b/chrome/browser/password_manager/password_accessory_controller_impl.h new file mode 100644 index 0000000..c74616d --- /dev/null +++ b/chrome/browser/password_manager/password_accessory_controller_impl.h
@@ -0,0 +1,170 @@ +// 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_PASSWORD_MANAGER_PASSWORD_ACCESSORY_CONTROLLER_IMPL_H_ +#define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_ACCESSORY_CONTROLLER_IMPL_H_ + +#include <map> +#include <memory> +#include <vector> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/task/cancelable_task_tracker.h" +#include "chrome/browser/password_manager/password_accessory_controller.h" +#include "components/autofill/core/browser/accessory_sheet_data.h" +#include "components/autofill/core/common/filling_status.h" +#include "components/favicon_base/favicon_types.h" +#include "content/public/browser/web_contents_user_data.h" +#include "url/gurl.h" + +namespace autofill { +struct PasswordForm; +} // namespace autofill + +namespace favicon { +class FaviconService; +} // namespace favicon + +namespace password_manager { +class PasswordManagerDriver; +} // namespace password_manager + +class ManualFillingController; +class PasswordGenerationDialogViewInterface; + +// Use either PasswordAccessoryController::GetOrCreate or +// PasswordAccessoryController::GetIfExisting to obtain instances of this class. +// +// TODO(crbug.com/854150): This class currently only supports credentials +// originating from the main frame. Supporting iframes is intended. +class PasswordAccessoryControllerImpl + : public PasswordAccessoryController, + public content::WebContentsUserData<PasswordAccessoryControllerImpl> { + public: + using CreateDialogFactory = base::RepeatingCallback<std::unique_ptr< + PasswordGenerationDialogViewInterface>(PasswordAccessoryController*)>; + + ~PasswordAccessoryControllerImpl() override; + + // PasswordAccessoryController: + void SavePasswordsForOrigin( + const std::map<base::string16, const autofill::PasswordForm*>& + best_matches, + const url::Origin& origin) override; + void OnAutomaticGenerationStatusChanged( + bool available, + const base::Optional< + autofill::password_generation::PasswordGenerationUIData>& ui_data, + const base::WeakPtr<password_manager::PasswordManagerDriver>& driver) + override; + void OnFilledIntoFocusedField(autofill::FillingStatus status) override; + void RefreshSuggestionsForField(const url::Origin& origin, + bool is_fillable, + bool is_password_field) override; + void DidNavigateMainFrame() override; + void ShowWhenKeyboardIsVisible() override; + void Hide() override; + void GetFavicon( + int desired_size_in_pixel, + base::OnceCallback<void(const gfx::Image&)> icon_callback) override; + void OnFillingTriggered(bool is_password, + const base::string16& text_to_fill) override; + void OnOptionSelected(const base::string16& selected_option) const override; + void OnGenerationRequested() override; + void GeneratedPasswordAccepted(const base::string16& password) override; + void GeneratedPasswordRejected() override; + gfx::NativeWindow native_window() const override; + + // Like |CreateForWebContents|, it creates the controller and attaches it to + // the given |web_contents|. Additionally, it allows inject a manual filling + // controller. + static void CreateForWebContentsForTesting( + content::WebContents* web_contents, + base::WeakPtr<ManualFillingController> mf_controller, + CreateDialogFactory create_dialog_callback, + favicon::FaviconService* favicon_service); + + private: + // Data including the form and field for which generation was requested, + // their signatures and the maximum password size. + struct GenerationElementData; + + // Data for a credential pair that is transformed into a suggestion. + struct SuggestionElementData; + + // Data allowing to cache favicons and favicon-related requests. + struct FaviconRequestData; + + friend class content::WebContentsUserData<PasswordAccessoryControllerImpl>; + + // Required for construction via |CreateForWebContents|: + explicit PasswordAccessoryControllerImpl(content::WebContents* contents); + + // Constructor that allows to inject a mock or fake view. + PasswordAccessoryControllerImpl( + content::WebContents* web_contents, + base::WeakPtr<ManualFillingController> mf_controller, + CreateDialogFactory create_dialog_callback, + favicon::FaviconService* favicon_service); + + // Creates the view items based on the given |suggestions|. + // If |is_password_field| is false, password suggestions won't be interactive. + static autofill::AccessorySheetData CreateAccessorySheetData( + const url::Origin& origin, + const std::vector<SuggestionElementData>& suggestions, + bool is_password_field); + + // Handles a favicon response requested by |GetFavicon| and responds to + // pending favicon requests with a (possibly empty) icon bitmap. + void OnImageFetched( + url::Origin origin, + const favicon_base::FaviconRawBitmapResult& bitmap_results); + + // Contains the last set of credentials by origin. + std::map<url::Origin, std::vector<SuggestionElementData>> origin_suggestions_; + + // The tab for which this class is scoped. + content::WebContents* web_contents_; + + // Data for the generation element used to generate the password. + std::unique_ptr<GenerationElementData> generation_element_data_; + + // The origin of the currently focused frame. It's used to ensure that + // favicons are not displayed across origins. + url::Origin current_origin_; + + // TODO(fhorschig): Find a way to use unordered_map with origin keys. + // A cache for all favicons that were requested. This includes all iframes + // for which the accessory was displayed. + std::map<url::Origin, FaviconRequestData> icons_request_data_; + + // Used to track a requested favicon. If the set of suggestion changes, this + // object aborts the request. Upon destruction, requests are cancelled, too. + base::CancelableTaskTracker favicon_tracker_; + + // Password manager driver for the target frame used for password generation. + base::WeakPtr<password_manager::PasswordManagerDriver> target_frame_driver_; + + // The password accessory controller object to forward client requests to. + base::WeakPtr<ManualFillingController> mf_controller_; + + // Modal dialog view meant to display the generated password. + std::unique_ptr<PasswordGenerationDialogViewInterface> dialog_view_; + + // Remembers whether the last focused field was a password field. That way, + // the reconstructed elements have the correct type. + bool last_focused_field_was_for_passwords_ = false; + + // Creation callback for the modal dialog view meant to facilitate testing. + CreateDialogFactory create_dialog_factory_; + + // The favicon service used to make retrieve icons for a given origin. + favicon::FaviconService* favicon_service_; + + DISALLOW_COPY_AND_ASSIGN(PasswordAccessoryControllerImpl); +}; + +#endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_ACCESSORY_CONTROLLER_IMPL_H_
diff --git a/chrome/browser/password_manager/password_accessory_controller_unittest.cc b/chrome/browser/password_manager/password_accessory_controller_impl_unittest.cc similarity index 85% rename from chrome/browser/password_manager/password_accessory_controller_unittest.cc rename to chrome/browser/password_manager/password_accessory_controller_impl_unittest.cc index b7094e13..dd5956c 100644 --- a/chrome/browser/password_manager/password_accessory_controller_unittest.cc +++ b/chrome/browser/password_manager/password_accessory_controller_impl_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/password_manager/password_accessory_controller.h" +#include "chrome/browser/password_manager/password_accessory_controller_impl.h" #include <algorithm> #include <memory> @@ -11,20 +11,15 @@ #include <vector> #include "base/callback.h" -#include "base/memory/weak_ptr.h" -#include "base/optional.h" -#include "base/strings/string_util.h" +#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/mock_callback.h" -#include "base/test/scoped_task_environment.h" -#include "chrome/browser/password_manager/password_accessory_view_interface.h" +#include "chrome/browser/autofill/manual_filling_controller.h" #include "chrome/browser/password_manager/password_generation_dialog_view_interface.h" #include "chrome/grit/generated_resources.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "components/autofill/core/browser/accessory_sheet_data.h" #include "components/autofill/core/common/password_form.h" -#include "components/autofill/core/common/password_generation_util.h" #include "components/autofill/core/common/signatures_util.h" #include "components/favicon/core/test/mock_favicon_service.h" #include "components/password_manager/core/browser/password_generation_manager.h" @@ -42,19 +37,12 @@ using autofill::FooterCommand; using autofill::PasswordForm; using autofill::UserInfo; -using autofill::FillingStatus; -using autofill::PasswordForm; using autofill::password_generation::PasswordGenerationUIData; using base::ASCIIToUTF16; -using base::UTF16ToWide; using testing::_; -using testing::AnyNumber; using testing::ByMove; -using testing::ElementsAre; using testing::Mock; using testing::NiceMock; -using testing::NotNull; -using testing::PrintToString; using testing::Return; using testing::StrictMock; @@ -62,25 +50,23 @@ constexpr char kExampleDomain[] = "example.com"; constexpr int kIconSize = 75; // An example size for favicons (=> 3.5*20px). -// The mock view mocks the platform-specific implementation. That also means -// that we have to care about the lifespan of the Controller because that would -// usually be responsibility of the view. -class MockPasswordAccessoryView : public PasswordAccessoryViewInterface { +class MockManualFillingController + : public ManualFillingController, + public base::SupportsWeakPtr<MockManualFillingController> { public: - MockPasswordAccessoryView() = default; - - MOCK_METHOD1(OnItemsAvailable, - void(const AccessorySheetData& AccessorySheetData)); - MOCK_METHOD1(OnFillingTriggered, void(const base::string16& textToFill)); - MOCK_METHOD0(OnViewDestroyed, void()); MOCK_METHOD1(OnAutomaticGenerationStatusChanged, void(bool)); - MOCK_METHOD0(CloseAccessorySheet, void()); - MOCK_METHOD0(SwapSheetWithKeyboard, void()); + MOCK_METHOD1(OnFilledIntoFocusedField, void(FillingStatus)); + MOCK_METHOD2(RefreshSuggestionsForField, + void(bool, const AccessorySheetData&)); MOCK_METHOD0(ShowWhenKeyboardIsVisible, void()); MOCK_METHOD0(Hide, void()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockPasswordAccessoryView); + MOCK_METHOD2(GetFavicon, + void(int, base::OnceCallback<void(const gfx::Image&)>)); + MOCK_METHOD2(OnFillingTriggered, + void(bool is_password, const base::string16&)); + MOCK_CONST_METHOD1(OnOptionSelected, void(const base::string16&)); + MOCK_METHOD0(OnGenerationRequested, void()); + MOCK_CONST_METHOD0(container_view, gfx::NativeView()); }; class MockPasswordManagerDriver @@ -214,6 +200,7 @@ base::string16 no_user_str() { return l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_EMPTY_LOGIN); } + base::string16 manage_passwords_str() { return l10n_util::GetStringUTF16( IDS_PASSWORD_MANAGER_ACCESSORY_ALL_PASSWORDS_LINK); @@ -300,19 +287,15 @@ public: PasswordAccessoryControllerTest() : mock_favicon_service_( - std::make_unique< - testing::StrictMock<favicon::MockFaviconService>>()) {} + std::make_unique<StrictMock<favicon::MockFaviconService>>()) {} void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); NavigateAndCommit(GURL(kExampleSite)); - PasswordAccessoryController::CreateForWebContentsForTesting( - web_contents(), - std::make_unique<StrictMock<MockPasswordAccessoryView>>(), + PasswordAccessoryControllerImpl::CreateForWebContentsForTesting( + web_contents(), mock_manual_filling_controller_.AsWeakPtr(), mock_dialog_factory_.Get(), favicon_service()); NavigateAndCommit(GURL(kExampleSite)); - EXPECT_CALL(*view(), CloseAccessorySheet()).Times(AnyNumber()); - EXPECT_CALL(*view(), SwapSheetWithKeyboard()).Times(AnyNumber()); // Mock objects needed by password generation mock_password_manager_driver_ = @@ -325,14 +308,11 @@ } PasswordAccessoryController* controller() { - return PasswordAccessoryController::FromWebContents(web_contents()); + return PasswordAccessoryControllerImpl::FromWebContents(web_contents()); } - MockPasswordAccessoryView* view() { - return static_cast<MockPasswordAccessoryView*>(controller()->view()); - } - - const base::MockCallback<PasswordAccessoryController::CreateDialogFactory>& + const base::MockCallback< + PasswordAccessoryControllerImpl::CreateDialogFactory>& mock_dialog_factory() { return mock_dialog_factory_; } @@ -343,9 +323,11 @@ protected: // Sets up mocks needed by the generation flow and signals the - // |PasswordAccessoryController| that generation is available. + // |PasswordAccessoryControllerImpl| that generation is available. void InitializeGeneration(const base::string16& password); + StrictMock<MockManualFillingController> mock_manual_filling_controller_; + std::unique_ptr<NiceMock<MockPasswordManagerDriver>> mock_password_manager_driver_; std::unique_ptr<NiceMock<MockPasswordGenerationManager>> @@ -353,9 +335,10 @@ std::unique_ptr<NiceMock<MockPasswordGenerationDialogView>> mock_dialog_; private: - NiceMock<base::MockCallback<PasswordAccessoryController::CreateDialogFactory>> + NiceMock< + base::MockCallback<PasswordAccessoryControllerImpl::CreateDialogFactory>> mock_dialog_factory_; - std::unique_ptr<testing::StrictMock<favicon::MockFaviconService>> + std::unique_ptr<StrictMock<favicon::MockFaviconService>> mock_favicon_service_; }; @@ -365,7 +348,8 @@ GetPasswordGenerationManager()) .WillByDefault(Return(mock_generation_manager_.get())); - EXPECT_CALL(*view(), OnAutomaticGenerationStatusChanged(true)); + EXPECT_CALL(mock_manual_filling_controller_, + OnAutomaticGenerationStatusChanged(true)); controller()->OnAutomaticGenerationStatusChanged( true, GetTestGenerationUIData1(), @@ -379,11 +363,11 @@ } TEST_F(PasswordAccessoryControllerTest, IsNotRecreatedForSameWebContents) { - PasswordAccessoryController* initial_controller = - PasswordAccessoryController::FromWebContents(web_contents()); + PasswordAccessoryControllerImpl* initial_controller = + PasswordAccessoryControllerImpl::FromWebContents(web_contents()); EXPECT_NE(nullptr, initial_controller); - PasswordAccessoryController::CreateForWebContents(web_contents()); - EXPECT_EQ(PasswordAccessoryController::FromWebContents(web_contents()), + PasswordAccessoryControllerImpl::CreateForWebContents(web_contents()); + EXPECT_EQ(PasswordAccessoryControllerImpl::FromWebContents(web_contents()), initial_controller); } @@ -392,8 +376,9 @@ url::Origin::Create(GURL(kExampleSite))); EXPECT_CALL( - *view(), - OnItemsAvailable( + mock_manual_filling_controller_, + RefreshSuggestionsForField( + /*is_fillable=*/true, PasswordAccessorySheetDataBuilder(passwords_title_str(kExampleDomain)) .AddUserInfo() .AppendField(ASCIIToUTF16("Ben"), ASCIIToUTF16("Ben"), false, @@ -412,8 +397,9 @@ url::Origin::Create(GURL(kExampleSite))); EXPECT_CALL( - *view(), - OnItemsAvailable( + mock_manual_filling_controller_, + RefreshSuggestionsForField( + /*is_fillable=*/true, PasswordAccessorySheetDataBuilder(passwords_title_str(kExampleDomain)) .AddUserInfo() .AppendField(no_user_str(), no_user_str(), false, false) @@ -433,8 +419,9 @@ url::Origin::Create(GURL(kExampleSite))); EXPECT_CALL( - *view(), - OnItemsAvailable( + mock_manual_filling_controller_, + RefreshSuggestionsForField( + /*is_fillable=*/true, PasswordAccessorySheetDataBuilder(passwords_title_str(kExampleDomain)) .AddUserInfo() .AppendField(ASCIIToUTF16("Alf"), ASCIIToUTF16("Alf"), false, @@ -469,8 +456,9 @@ // Pretend that any input in the same frame was focused. EXPECT_CALL( - *view(), - OnItemsAvailable( + mock_manual_filling_controller_, + RefreshSuggestionsForField( + /*is_fillable=*/true, PasswordAccessorySheetDataBuilder(passwords_title_str(kExampleDomain)) .AddUserInfo() .AppendField(ASCIIToUTF16("Ben"), ASCIIToUTF16("Ben"), false, @@ -488,7 +476,9 @@ controller()->SavePasswordsForOrigin({}, url::Origin::Create(GURL(kExampleSite))); - EXPECT_CALL(*view(), OnItemsAvailable(PasswordAccessorySheetDataBuilder( + EXPECT_CALL(mock_manual_filling_controller_, + RefreshSuggestionsForField( + /*is_fillable=*/true, PasswordAccessorySheetDataBuilder( passwords_empty_str(kExampleDomain)) .Build())); controller()->RefreshSuggestionsForField( @@ -497,41 +487,30 @@ /*is_password_field=*/false); } -// TODO(fhorschig): Check for recorded metrics here or similar to this. -TEST_F(PasswordAccessoryControllerTest, ClosesViewOnSuccessfullFillingOnly) { - // If the filling wasn't successful, no call is expected. - EXPECT_CALL(*view(), CloseAccessorySheet()).Times(0); - EXPECT_CALL(*view(), SwapSheetWithKeyboard()).Times(0); +TEST_F(PasswordAccessoryControllerTest, OnFilledIntoFocusedField) { + EXPECT_CALL(mock_manual_filling_controller_, + OnFilledIntoFocusedField(FillingStatus::ERROR_NOT_ALLOWED)); controller()->OnFilledIntoFocusedField(FillingStatus::ERROR_NOT_ALLOWED); + + EXPECT_CALL(mock_manual_filling_controller_, + OnFilledIntoFocusedField(FillingStatus::ERROR_NO_VALID_FIELD)); controller()->OnFilledIntoFocusedField(FillingStatus::ERROR_NO_VALID_FIELD); - // If the filling completed successfully, let the view know. - EXPECT_CALL(*view(), SwapSheetWithKeyboard()); + EXPECT_CALL(mock_manual_filling_controller_, + OnFilledIntoFocusedField(FillingStatus::SUCCESS)); controller()->OnFilledIntoFocusedField(FillingStatus::SUCCESS); } -// TODO(fhorschig): Check for recorded metrics here or similar to this. -TEST_F(PasswordAccessoryControllerTest, ClosesViewWhenRefreshingSuggestions) { - // Ignore Items - only the closing calls are interesting here. - EXPECT_CALL(*view(), OnItemsAvailable(_)).Times(AnyNumber()); - - EXPECT_CALL(*view(), CloseAccessorySheet()); - EXPECT_CALL(*view(), SwapSheetWithKeyboard()) - .Times(0); // Don't touch the keyboard! - controller()->RefreshSuggestionsForField( - url::Origin::Create(GURL(kExampleSite)), - /*is_fillable=*/false, - /*is_password_field=*/false); -} - TEST_F(PasswordAccessoryControllerTest, RelaysAutomaticGenerationAvailable) { - EXPECT_CALL(*view(), OnAutomaticGenerationStatusChanged(true)); + EXPECT_CALL(mock_manual_filling_controller_, + OnAutomaticGenerationStatusChanged(true)); controller()->OnAutomaticGenerationStatusChanged( true, GetTestGenerationUIData1(), nullptr); } TEST_F(PasswordAccessoryControllerTest, RelaysAutmaticGenerationUnavailable) { - EXPECT_CALL(*view(), OnAutomaticGenerationStatusChanged(false)); + EXPECT_CALL(mock_manual_filling_controller_, + OnAutomaticGenerationStatusChanged(false)); controller()->OnAutomaticGenerationStatusChanged(false, base::nullopt, nullptr); } @@ -542,7 +521,9 @@ TEST_F(PasswordAccessoryControllerTest, UpdatesSignaturesForDifferentGenerationForms) { // Called twice for different forms. - EXPECT_CALL(*view(), OnAutomaticGenerationStatusChanged(true)).Times(2); + EXPECT_CALL(mock_manual_filling_controller_, + OnAutomaticGenerationStatusChanged(true)) + .Times(2); controller()->OnAutomaticGenerationStatusChanged( true, GetTestGenerationUIData1(), mock_password_manager_driver_->AsWeakPtr()); @@ -578,8 +559,9 @@ // Pretend a username field was focused. This should result in non-interactive // suggestion. EXPECT_CALL( - *view(), - OnItemsAvailable( + mock_manual_filling_controller_, + RefreshSuggestionsForField( + /*is_fillable=*/true, PasswordAccessorySheetDataBuilder(passwords_title_str(kExampleDomain)) .AddUserInfo() .AppendField(ASCIIToUTF16("Ben"), ASCIIToUTF16("Ben"), false, @@ -595,8 +577,9 @@ // Pretend that we focus a password field now: By triggering a refresh with // |is_password_field| set to true, all suggestions should become interactive. EXPECT_CALL( - *view(), - OnItemsAvailable( + mock_manual_filling_controller_, + RefreshSuggestionsForField( + /*is_fillable=*/true, PasswordAccessorySheetDataBuilder(passwords_title_str(kExampleDomain)) .AddUserInfo() .AppendField(ASCIIToUTF16("Ben"), ASCIIToUTF16("Ben"), false, @@ -614,8 +597,9 @@ controller()->SavePasswordsForOrigin({CreateEntry("Ben", "S3cur3").first}, url::Origin::Create(GURL(kExampleSite))); EXPECT_CALL( - *view(), - OnItemsAvailable( + mock_manual_filling_controller_, + RefreshSuggestionsForField( + /*is_fillable=*/true, PasswordAccessorySheetDataBuilder(passwords_title_str(kExampleDomain)) .AddUserInfo() .AppendField(ASCIIToUTF16("Ben"), ASCIIToUTF16("Ben"), false, @@ -631,8 +615,9 @@ controller()->SavePasswordsForOrigin({CreateEntry("Alf", "M3lm4k").first}, url::Origin::Create(GURL(kExampleSite))); EXPECT_CALL( - *view(), - OnItemsAvailable( + mock_manual_filling_controller_, + RefreshSuggestionsForField( + /*is_fillable=*/true, PasswordAccessorySheetDataBuilder(passwords_title_str(kExampleDomain)) .AddUserInfo() .AppendField(ASCIIToUTF16("Alf"), ASCIIToUTF16("Alf"), false, @@ -652,8 +637,9 @@ // Pretend a username field was focused. This should result in non-emtpy // suggestions. EXPECT_CALL( - *view(), - OnItemsAvailable( + mock_manual_filling_controller_, + RefreshSuggestionsForField( + /*is_fillable=*/true, PasswordAccessorySheetDataBuilder(passwords_title_str(kExampleDomain)) .AddUserInfo() .AppendField(ASCIIToUTF16("Ben"), ASCIIToUTF16("Ben"), false, @@ -668,9 +654,12 @@ // Pretend that the focus was lost or moved to an unfillable field. Now, only // the empty state message should be sent. - EXPECT_CALL(*view(), OnItemsAvailable(PasswordAccessorySheetDataBuilder( - passwords_empty_str(kExampleDomain)) - .Build())); + EXPECT_CALL( + mock_manual_filling_controller_, + RefreshSuggestionsForField( + /*is_fillable=*/false, + PasswordAccessorySheetDataBuilder(passwords_empty_str(kExampleDomain)) + .Build())); controller()->RefreshSuggestionsForField( url::Origin::Create(GURL(kExampleSite)), /*is_fillable=*/false, @@ -683,8 +672,9 @@ controller()->SavePasswordsForOrigin({CreateEntry("Ben", "S3cur3").first}, url::Origin::Create(GURL(kExampleSite))); EXPECT_CALL( - *view(), - OnItemsAvailable( + mock_manual_filling_controller_, + RefreshSuggestionsForField( + /*is_fillable=*/true, PasswordAccessorySheetDataBuilder(passwords_title_str(kExampleDomain)) .AddUserInfo() .AppendField(ASCIIToUTF16("Ben"), ASCIIToUTF16("Ben"), false, @@ -702,10 +692,12 @@ controller()->DidNavigateMainFrame(); // Now, only the empty state message should be sent. - EXPECT_CALL(*view(), - OnItemsAvailable(PasswordAccessorySheetDataBuilder( - passwords_empty_str("random.other-site.org")) - .Build())); + EXPECT_CALL(mock_manual_filling_controller_, + RefreshSuggestionsForField( + /*is_fillable=*/true, + PasswordAccessorySheetDataBuilder( + passwords_empty_str("random.other-site.org")) + .Build())); controller()->RefreshSuggestionsForField( url::Origin::Create(GURL("https://random.other-site.org/")), /*is_fillable=*/true, @@ -715,7 +707,8 @@ TEST_F(PasswordAccessoryControllerTest, FetchFaviconForCurrentUrl) { base::MockCallback<base::OnceCallback<void(const gfx::Image&)>> mock_callback; - EXPECT_CALL(*view(), OnItemsAvailable(_)); + EXPECT_CALL(mock_manual_filling_controller_, + RefreshSuggestionsForField(/*is_fillable=*/true, _)); controller()->RefreshSuggestionsForField( url::Origin::Create(GURL(kExampleSite)), /*is_fillable=*/true, @@ -732,7 +725,8 @@ TEST_F(PasswordAccessoryControllerTest, RequestsFaviconsOnceForOneOrigin) { base::MockCallback<base::OnceCallback<void(const gfx::Image&)>> mock_callback; - EXPECT_CALL(*view(), OnItemsAvailable(_)); + EXPECT_CALL(mock_manual_filling_controller_, RefreshSuggestionsForField( + /*is_fillable=*/true, _)); controller()->RefreshSuggestionsForField( url::Origin::Create(GURL(kExampleSite)), /*is_fillable=*/true, @@ -769,7 +763,8 @@ non_empty_result.icon_url = GURL(kExampleSite); // Populate the cache by requesting a favicon. - EXPECT_CALL(*view(), OnItemsAvailable(_)); + EXPECT_CALL(mock_manual_filling_controller_, + RefreshSuggestionsForField(/*is_fillable=*/true, _)); controller()->RefreshSuggestionsForField( url::Origin::Create(GURL(kExampleSite)), /*is_fillable=*/true, @@ -795,9 +790,11 @@ controller()->DidNavigateMainFrame(); NavigateAndCommit(GURL(kExampleSite)); // Same origin as intially. controller()->DidNavigateMainFrame(); - EXPECT_CALL(*view(), OnItemsAvailable(_)); + EXPECT_CALL(mock_manual_filling_controller_, + RefreshSuggestionsForField(/*is_fillable=*/true, _)); controller()->RefreshSuggestionsForField( - url::Origin::Create(GURL(kExampleSite)), true, false); + url::Origin::Create(GURL(kExampleSite)), /*is_fillable=*/true, + /*is_password_field=*/false); // The cache was cleared, so now the service has to be queried again. EXPECT_CALL(*favicon_service(), GetRawFaviconForPageURL(GURL(kExampleSite), _, @@ -811,7 +808,9 @@ TEST_F(PasswordAccessoryControllerTest, NoFaviconCallbacksWhenOriginChanges) { base::MockCallback<base::OnceCallback<void(const gfx::Image&)>> mock_callback; - EXPECT_CALL(*view(), OnItemsAvailable(_)).Times(2); + EXPECT_CALL(mock_manual_filling_controller_, + RefreshSuggestionsForField(/*is_fillable=*/true, _)) + .Times(2); controller()->RefreshSuggestionsForField( url::Origin::Create(GURL(kExampleSite)), true, false); @@ -857,9 +856,7 @@ "KeyboardAccessory.GeneratedPasswordDialog", true, 1); } -TEST_F(PasswordAccessoryControllerTest, RelaysShowAndHideKeyboardAccessory) { - EXPECT_CALL(*view(), ShowWhenKeyboardIsVisible()); - controller()->ShowWhenKeyboardIsVisible(); - EXPECT_CALL(*view(), Hide()); +TEST_F(PasswordAccessoryControllerTest, Hide) { + EXPECT_CALL(mock_manual_filling_controller_, Hide()); controller()->Hide(); }
diff --git a/chrome/browser/password_manager/password_generation_dialog_view_interface.h b/chrome/browser/password_manager/password_generation_dialog_view_interface.h index 88922c7..7b1b058 100644 --- a/chrome/browser/password_manager/password_generation_dialog_view_interface.h +++ b/chrome/browser/password_manager/password_generation_dialog_view_interface.h
@@ -17,7 +17,7 @@ virtual void Show(base::string16& password) = 0; private: - friend class PasswordAccessoryController; + friend class PasswordAccessoryControllerImpl; // Factory function used to create a concrete instance of this view. static std::unique_ptr<PasswordGenerationDialogViewInterface> Create( PasswordAccessoryController* controller);
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc index b3796bcc..4bea0d7 100644 --- a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc +++ b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
@@ -172,13 +172,18 @@ UserCloudPolicyManagerFactory::GetInstance()->RegisterTestingFactory( base::BindRepeating(&BuildCloudPolicyManager)); - TestingProfile::TestingFactories factories = { - {AccountFetcherServiceFactory::GetInstance(), - base::BindRepeating(&FakeAccountFetcherServiceBuilder::BuildForTests)}, - {ChromeSigninClientFactory::GetInstance(), - base::BindRepeating(&signin::BuildTestSigninClient)}}; + TestingProfile::Builder builder; + builder.SetPrefService( + std::unique_ptr<sync_preferences::PrefServiceSyncable>( + std::move(prefs))); + builder.AddTestingFactory( + AccountFetcherServiceFactory::GetInstance(), + base::BindRepeating(&FakeAccountFetcherServiceBuilder::BuildForTests)); + builder.AddTestingFactory( + ChromeSigninClientFactory::GetInstance(), + base::BindRepeating(&signin::BuildTestSigninClient)); profile_ = IdentityTestEnvironmentProfileAdaptor:: - CreateProfileForIdentityTestEnvironment(factories, std::move(prefs)); + CreateProfileForIdentityTestEnvironment(builder); identity_test_env_adaptor_ = std::make_unique<IdentityTestEnvironmentProfileAdaptor>(profile_.get());
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index 7d2cdbf..66d79b1 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc
@@ -17,7 +17,6 @@ #include "base/callback.h" #include "base/callback_helpers.h" #include "base/command_line.h" -#include "base/feature_list.h" #include "base/files/file_enumerator.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -136,8 +135,10 @@ #include "components/content_settings/core/common/content_settings_pattern.h" #include "components/content_settings/core/common/pref_names.h" #include "components/download/public/common/download_item.h" +#include "components/google/core/common/google_util.h" #include "components/infobars/core/infobar.h" #include "components/language/core/browser/pref_names.h" +#include "components/network_session_configurator/common/network_switches.h" #include "components/network_time/network_time_tracker.h" #include "components/omnibox/browser/autocomplete_controller.h" #include "components/omnibox/browser/omnibox_edit_model.h" @@ -772,10 +773,6 @@ } }; -bool AreCommittedInterstitialsEnabled() { - return base::FeatureList::IsEnabled(features::kSSLCommittedInterstitials); -} - } // namespace class PolicyTest : public InProcessBrowserTest { @@ -1032,12 +1029,14 @@ return GURL(expected_url); } - static void CheckSafeSearch(Browser* browser, bool expect_safe_search) { + static void CheckSafeSearch(Browser* browser, + bool expect_safe_search, + const std::string& url = "http://google.com/") { content::WebContents* web_contents = browser->tab_strip_model()->GetActiveWebContents(); content::TestNavigationObserver observer(web_contents); LocationBar* location_bar = browser->window()->GetLocationBar(); - ui_test_utils::SendToOmniboxAndSubmit(location_bar, "http://google.com/"); + ui_test_utils::SendToOmniboxAndSubmit(location_bar, url); OmniboxEditModel* model = location_bar->GetOmniboxView()->model(); observer.Wait(); EXPECT_TRUE(model->CurrentMatch(NULL).destination_url.is_valid()); @@ -1121,7 +1120,7 @@ void SetUpCommandLine(base::CommandLine* command_line) override { PolicyTest::SetUpCommandLine(command_line); - if (GetParam()) { + if (AreCommittedInterstitialsEnabled()) { scoped_feature_list_.InitAndEnableFeature( features::kSSLCommittedInterstitials); } @@ -1132,6 +1131,8 @@ } protected: + bool AreCommittedInterstitialsEnabled() const { return GetParam(); } + bool IsShowingInterstitial(content::WebContents* tab) { if (AreCommittedInterstitialsEnabled()) { security_interstitials::SecurityInterstitialTabHelper* helper = @@ -1753,6 +1754,46 @@ } } +class PolicyTestSafeSearchRedirect : public PolicyTest { + public: + PolicyTestSafeSearchRedirect() = default; + + private: + void SetUpOnMainThread() override { + // The test makes requests to google.com which we want to redirect to the + // test server. + host_resolver()->AddRule("*", "127.0.0.1"); + + // 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(); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + // 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); + } + + DISALLOW_COPY_AND_ASSIGN(PolicyTestSafeSearchRedirect); +}; + +IN_PROC_BROWSER_TEST_F(PolicyTestSafeSearchRedirect, ForceGoogleSafeSearch) { + net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); + https_server.AddDefaultHandlers( + base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); + ASSERT_TRUE(https_server.Start()); + + ApplySafeSearchPolicy(nullptr, // ForceSafeSearch + std::make_unique<base::Value>(true), + nullptr, // ForceYouTubeSafetyMode + nullptr); // ForceYouTubeRestrict + + GURL url = https_server.GetURL("www.google.com", + "/server-redirect?http://google.com/"); + CheckSafeSearch(browser(), true, url.spec()); +} + IN_PROC_BROWSER_TEST_F(PolicyTest, ForceYouTubeRestrict) { base::Lock lock; std::map<GURL, net::HttpRequestHeaders> urls_requested; @@ -4643,29 +4684,15 @@ ui_test_utils::NavigateToURL(browser(), https_server_ok.GetURL("/")); - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - // The page should initially be blocked. - content::RenderFrameHost* main_frame; - if (AreCommittedInterstitialsEnabled()) { - security_interstitials::SecurityInterstitialTabHelper* helper = - security_interstitials::SecurityInterstitialTabHelper::FromWebContents( - web_contents); - ASSERT_TRUE(helper); - ASSERT_TRUE( - helper->GetBlockingPageForCurrentlyCommittedNavigationForTesting()); - main_frame = web_contents->GetMainFrame(); - } else { - const content::InterstitialPage* interstitial = - content::InterstitialPage::GetInterstitialPage(web_contents); - ASSERT_TRUE(interstitial); - main_frame = interstitial->GetMainFrame(); - } - ASSERT_TRUE(content::WaitForRenderFrameReady(main_frame)); - EXPECT_TRUE(chrome_browser_interstitials::IsInterstitialDisplayingText( - main_frame, "proceed-link")); + const content::InterstitialPage* interstitial = + content::InterstitialPage::GetInterstitialPage( + browser()->tab_strip_model()->GetActiveWebContents()); + ASSERT_TRUE(interstitial); + ASSERT_TRUE(content::WaitForRenderFrameReady(interstitial->GetMainFrame())); + EXPECT_TRUE(chrome_browser_interstitials::IsInterstitialDisplayingText( + interstitial->GetMainFrame(), "proceed-link")); EXPECT_NE(base::UTF8ToUTF16("OK"), browser()->tab_strip_model()->GetActiveWebContents()->GetTitle()); @@ -4688,15 +4715,9 @@ https_server_ok.GetURL("/simple.html")); // There should be no interstitial after the page loads. - // With committed interstitials enabled, we don't have an interstitial page to - // check against, so we only check that the title is the correct one after - // navigating away. - if (!AreCommittedInterstitialsEnabled()) { - const content::InterstitialPage* interstitial = - content::InterstitialPage::GetInterstitialPage( - browser()->tab_strip_model()->GetActiveWebContents()); - ASSERT_FALSE(interstitial); - } + interstitial = content::InterstitialPage::GetInterstitialPage( + browser()->tab_strip_model()->GetActiveWebContents()); + ASSERT_FALSE(interstitial); EXPECT_EQ(base::UTF8ToUTF16("OK"), browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index edd85e91..8b6c9e7 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -382,6 +382,9 @@ const char kNetworkQualities[] = "net.network_qualities"; const char kForceSessionSync[] = "settings.history_recorded"; const char kOnboardDuringNUX[] = "browser.onboard_during_nux"; +// This pref is particularly large, taking up 15+% of the prefs file, so should +// perhaps be kept around longer than the others. +const char kHttpServerProperties[] = "net.http_server_properties"; // Register prefs used only for migration (clearing or moving to a new key). void RegisterProfilePrefsForMigration( @@ -412,6 +415,8 @@ registry->RegisterDictionaryPref(kNetworkQualities, PrefRegistry::LOSSY_PREF); registry->RegisterBooleanPref(kForceSessionSync, false); registry->RegisterBooleanPref(kOnboardDuringNUX, false); + registry->RegisterDictionaryPref(kHttpServerProperties, + PrefRegistry::LOSSY_PREF); } } // namespace @@ -876,4 +881,5 @@ profile_prefs->ClearPref(kNetworkQualities); profile_prefs->ClearPref(kForceSessionSync); profile_prefs->ClearPref(kOnboardDuringNUX); + profile_prefs->ClearPref(kHttpServerProperties); }
diff --git a/chrome/browser/prefs/synced_pref_change_registrar_browsertest.cc b/chrome/browser/prefs/synced_pref_change_registrar_browsertest.cc index ee1f815..6319a884 100644 --- a/chrome/browser/prefs/synced_pref_change_registrar_browsertest.cc +++ b/chrome/browser/prefs/synced_pref_change_registrar_browsertest.cc
@@ -58,8 +58,8 @@ pref_specifics->set_name(name); pref_specifics->set_value(serialized_value); - syncer::SyncData change_data = syncer::SyncData::CreateRemoteData( - ++next_sync_data_id_, specifics, base::Time()); + syncer::SyncData change_data = + syncer::SyncData::CreateRemoteData(++next_sync_data_id_, specifics); syncer::SyncChange change( FROM_HERE, syncer::SyncChange::ACTION_UPDATE, change_data);
diff --git a/chrome/browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc b/chrome/browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc index 53f2150..6eaf2ea 100644 --- a/chrome/browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc +++ b/chrome/browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc
@@ -363,6 +363,8 @@ 1); histogram_tester.ExpectUniqueSample( "ResourceLoadingHints.ResourcePatternsAvailableAtCommit", 1, 1); + histogram_tester.ExpectTotalCount( + "ResourceLoadingHints.ResourcePatternsAvailableAtCommitForRedirect", 0); histogram_tester.ExpectBucketCount( "Previews.EligibilityReason.ResourceLoadingHints", static_cast<int>(previews::PreviewsEligibilityReason::ALLOWED), 1); @@ -386,6 +388,8 @@ 2); histogram_tester.ExpectUniqueSample( "ResourceLoadingHints.ResourcePatternsAvailableAtCommit", 1, 2); + histogram_tester.ExpectTotalCount( + "ResourceLoadingHints.ResourcePatternsAvailableAtCommitForRedirect", 0); histogram_tester.ExpectBucketCount( "Previews.EligibilityReason.ResourceLoadingHints", static_cast<int>(previews::PreviewsEligibilityReason::ALLOWED), 2); @@ -458,6 +462,8 @@ 1); histogram_tester.ExpectUniqueSample( "ResourceLoadingHints.ResourcePatternsAvailableAtCommit", 1, 1); + histogram_tester.ExpectTotalCount( + "ResourceLoadingHints.ResourcePatternsAvailableAtCommitForRedirect", 0); histogram_tester.ExpectBucketCount( "Previews.EligibilityReason.ResourceLoadingHints", static_cast<int>(previews::PreviewsEligibilityReason::ALLOWED), 1); @@ -501,6 +507,8 @@ 1); histogram_tester.ExpectUniqueSample( "ResourceLoadingHints.ResourcePatternsAvailableAtCommit", 1, 1); + histogram_tester.ExpectTotalCount( + "ResourceLoadingHints.ResourcePatternsAvailableAtCommitForRedirect", 0); histogram_tester.ExpectBucketCount( "Previews.EligibilityReason.ResourceLoadingHints", static_cast<int>(previews::PreviewsEligibilityReason::ALLOWED), 1); @@ -571,6 +579,11 @@ RetryForHistogramUntilCountReached( &histogram_tester, "ResourceLoadingHints.CountBlockedSubresourcePatterns", 1); + histogram_tester.ExpectUniqueSample( + "ResourceLoadingHints.ResourcePatternsAvailableAtCommit", 1, 1); + histogram_tester.ExpectUniqueSample( + "ResourceLoadingHints.ResourcePatternsAvailableAtCommitForRedirect", 1, + 1); histogram_tester.ExpectBucketCount( "Previews.EligibilityReason.ResourceLoadingHints", static_cast<int>(previews::PreviewsEligibilityReason::ALLOWED), 2);
diff --git a/chrome/browser/previews/resource_loading_hints/resource_loading_hints_web_contents_observer.cc b/chrome/browser/previews/resource_loading_hints/resource_loading_hints_web_contents_observer.cc index 27cba13b..df34e67 100644 --- a/chrome/browser/previews/resource_loading_hints/resource_loading_hints_web_contents_observer.cc +++ b/chrome/browser/previews/resource_loading_hints/resource_loading_hints_web_contents_observer.cc
@@ -60,11 +60,13 @@ } DCHECK(previews::params::IsResourceLoadingHintsEnabled()); - SendResourceLoadingHints(navigation_handle); + SendResourceLoadingHints(navigation_handle, + previews_user_data->is_redirect()); } void ResourceLoadingHintsWebContentsObserver::SendResourceLoadingHints( - content::NavigationHandle* navigation_handle) const { + content::NavigationHandle* navigation_handle, + bool is_redirect) const { // Hints should be sent only after the renderer frame has committed. DCHECK(navigation_handle->HasCommitted()); DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); @@ -82,6 +84,11 @@ UMA_HISTOGRAM_BOOLEAN( "ResourceLoadingHints.ResourcePatternsAvailableAtCommit", !hints.empty()); + if (is_redirect) { + UMA_HISTOGRAM_BOOLEAN( + "ResourceLoadingHints.ResourcePatternsAvailableAtCommitForRedirect", + !hints.empty()); + } if (hints.empty()) return;
diff --git a/chrome/browser/previews/resource_loading_hints/resource_loading_hints_web_contents_observer.h b/chrome/browser/previews/resource_loading_hints/resource_loading_hints_web_contents_observer.h index f7cd690..c5a7af37 100644 --- a/chrome/browser/previews/resource_loading_hints/resource_loading_hints_web_contents_observer.h +++ b/chrome/browser/previews/resource_loading_hints/resource_loading_hints_web_contents_observer.h
@@ -37,8 +37,8 @@ content::NavigationHandle* navigation_handle) override; // Sends resource loading hints to the renderer. - void SendResourceLoadingHints( - content::NavigationHandle* navigation_handle) const; + void SendResourceLoadingHints(content::NavigationHandle* navigation_handle, + bool is_reload) const; // Returns the pattern of resources that should be blocked when loading // |document_gurl|. The pattern may be a single substring to match against the
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index d3b944b..0e48027 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -1170,23 +1170,6 @@ } #if defined(OS_CHROMEOS) -#if BUILDFLAG(ENABLE_CROS_ASSISTANT) - { - service_manager::EmbeddedServiceInfo info; - info.factory = base::BindRepeating([] { - network::NetworkConnectionTracker* network_connection_tracker = - content::GetNetworkConnectionTracker(); - return std::unique_ptr<service_manager::Service>( - std::make_unique<chromeos::assistant::Service>( - network_connection_tracker)); - }); - info.task_runner = base::CreateSingleThreadTaskRunnerWithTraits( - {content::BrowserThread::UI}); - services->insert( - std::make_pair(chromeos::assistant::mojom::kServiceName, info)); - } -#endif - if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) { service_manager::EmbeddedServiceInfo info; info.task_runner = base::ThreadTaskRunnerHandle::Get(); @@ -1233,6 +1216,21 @@ std::make_pair(identity::mojom::kServiceName, identity_service_info)); } +std::unique_ptr<service_manager::Service> ProfileImpl::HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) { +#if defined(OS_CHROMEOS) +#if BUILDFLAG(ENABLE_CROS_ASSISTANT) + if (service_name == chromeos::assistant::mojom::kServiceName) { + return std::make_unique<chromeos::assistant::Service>( + std::move(request), content::GetNetworkConnectionTracker()); + } +#endif +#endif + + return nullptr; +} + std::string ProfileImpl::GetMediaDeviceIDSalt() { return media_device_id_salt_->GetSalt(); }
diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h index 2d8e7f1..b5d7f91 100644 --- a/chrome/browser/profiles/profile_impl.h +++ b/chrome/browser/profiles/profile_impl.h
@@ -99,6 +99,9 @@ const base::FilePath& partition_path, bool in_memory) override; void RegisterInProcessServices(StaticServiceMap* services) override; + std::unique_ptr<service_manager::Service> HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) override; std::string GetMediaDeviceIDSalt() override; download::InProgressDownloadManager* RetriveInProgressDownloadManager() override;
diff --git a/chrome/browser/resource_coordinator/tab_helper.cc b/chrome/browser/resource_coordinator/tab_helper.cc index 8b30ceb8..8934081a 100644 --- a/chrome/browser/resource_coordinator/tab_helper.cc +++ b/chrome/browser/resource_coordinator/tab_helper.cc
@@ -154,10 +154,6 @@ render_frame_host->GetFrameResourceCoordinator(); page_resource_coordinator_->AddFrame(*frame_resource_coordinator); - auto* process_resource_coordinator = - render_frame_host->GetProcess()->GetProcessResourceCoordinator(); - process_resource_coordinator->AddFrame(*frame_resource_coordinator); - if (navigation_handle->IsInMainFrame()) { if (auto* page_signal_receiver = GetPageSignalReceiver()) { // Update the last observed navigation ID for this WebContents.
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js index 7dcb11f..21c908cd 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
@@ -2052,9 +2052,10 @@ if (!this.outputContextFirst_) this.ancestry_(node, prevNode, type, buff, ruleStr); - var loc = range.start.node.boundsForRange(rangeStart, rangeEnd); - if (loc) - this.locations_.push(loc); + range.start.node.boundsForRange(rangeStart, rangeEnd, (loc) => { + if (loc) + this.locations_.push(loc); + }); }, /**
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bn.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bn.xtb index c495d62..e1a01c4 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bn.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_bn.xtb
@@ -398,7 +398,7 @@ <translation id="4058278702844053247">একটি পৃষ্ঠা লোড হচ্ছে</translation> <translation id="4065205963140826639">‘পরবর্তী’ বোতাম খুঁজতে সার্চ + ডান তীরচিহ্ন ব্যবহার করে দেখুন, এটা ক্লিক করার জন্য সার্চ + স্পেস টিপুন।</translation> <translation id="4081085052247739398">{COUNT,plural, =1{টিলড চিহ্ন}one{#টি টিলড চিহ্ন}other{#টি টিলড চিহ্ন}}</translation> -<translation id="4086311032171418648">শিক্ষণ মোড থামানো হচ্ছে</translation> +<translation id="4086311032171418648">লার্ন মোড থামানো হচ্ছে</translation> <translation id="409334809956508737">পূর্ববর্তী বস্তু</translation> <translation id="4099274309791143834">উপমেনুর সাথে</translation> <translation id="4101527861445851766">একটি টিকচিহ্ন দেওয়া চেকবাক্স</translation> @@ -501,7 +501,7 @@ <translation id="4877261390094455813">একটি সার্চ ক্যোয়ারী লিখুন৷</translation> <translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation> <translation id="489907760999452556">অভ্যন্তরীণ লিঙ্ক</translation> -<translation id="4915087353619183190">শিক্ষণ মোড শুরু করা হচ্ছে। এটির ক্রিয়াকলাপ সম্বন্ধে জানার জন্য qwerty কী, রিফ্রেশ করা যায় এমন ব্রেইল কী বা স্পর্শের ইঙ্গিত টিপুন। বেরিয়ে আসার জন্য কন্ট্রোলের সাথে w অথবা escape কী টিপুন।</translation> +<translation id="4915087353619183190">লার্ন মোড শুরু করা হচ্ছে। এটির ক্রিয়াকলাপ সম্বন্ধে জানার জন্য কোয়ার্টি কী, রিফ্রেশ করা যায় এমন ব্রেইল কী টিপুন বা স্ক্রিন স্পর্শ করুন। বেরিয়ে আসার জন্য Ctrl কী সহ w অথবা Esc কী টিপুন।</translation> <translation id="492295894462528572">মুখবন্ধ</translation> <translation id="495170559598752135">ক্রিয়াসমূহ</translation> <translation id="4953585991029886728">পাঠ্য সম্পাদনা করুন</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_cs.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_cs.xtb index 46d0e28..1ae42666 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_cs.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_cs.xtb
@@ -45,6 +45,7 @@ <translation id="1275718070701477396">Vybráno</translation> <translation id="1286609444451033486">Lze přepnout stisknutím kláves Hledat + mezerník.</translation> <translation id="1291286136605998134">Přepínač</translation> +<translation id="1303806948938513162">Klepnutím čtyřmi prsty přejdete do nabídek funkce ChromeVox</translation> <translation id="1319608975892113573">Žádná předchozí bloková citace.</translation> <translation id="1321576897702511272">Skrýt nápovědu programu ChromeVox</translation> <translation id="1331702245475014624"><ph name="INDEX" /> z <ph name="TOTAL" /></translation> @@ -238,6 +239,7 @@ <translation id="3046838483509668188">Možnosti programu ChromeVox</translation> <translation id="3047143736589213134">Experimentální mapa kláves</translation> <translation id="3060756054951570867">otevřena nabídka <ph name="TITLE" /></translation> +<translation id="3060880924447482063">Přejetím prstem vlevo nebo vpravo můžete přecházet mezi položkami</translation> <translation id="3070245424257836917">Přejeďte třemi prsty nahoru</translation> <translation id="3078345202707391975">Další nadpis 2. úrovně</translation> <translation id="3078740164268491126">tabulka</translation> @@ -331,6 +333,7 @@ <translation id="3389259863310851658">Předchozí pole formuláře</translation> <translation id="3390225400784126843">Další jiný prvek</translation> <translation id="3392045790598181549"><ph name="NAME" />, položka nabídky</translation> +<translation id="3393605254399152980">Přejetím jedním prstem získáte hlasovou odezvu</translation> <translation id="3406283310380167331">Zobrazit seznam formulářů</translation> <translation id="3423495725743882470">řádek $1, sloupec $2</translation> <translation id="3457000393508828486">Částečně stisknuto</translation> @@ -346,6 +349,7 @@ <translation id="3497063866483065785">{COUNT,plural, =1{otazník}few{# otazníky}many{# question marks}other{# otazníků}}</translation> <translation id="3514822174137761109">{COUNT,plural, =1{stříška}few{# stříšky}many{# carets}other{# stříšek}}</translation> <translation id="352577523970648069">Upravitelné textové pole</translation> +<translation id="3549680091535286226">Klepnutím dvěma prsty hlasovou odezvu dočasně zastavíte</translation> <translation id="3568702578574425662"><ph name="NAME" />, zaškrtávací políčko není zaškrtnuto</translation> <translation id="3589661172894441357">Glosář</translation> <translation id="3599054940393788245">Nejedná se o matematiku</translation> @@ -410,6 +414,7 @@ <translation id="4166192625054637755">Konec dolního indexu</translation> <translation id="4173994908659439270">Žádné další upravitelné textové pole.</translation> <translation id="4176463684765177261">Deaktivováno</translation> +<translation id="4187322598335821254">Přejetím prstem nahoru nebo dolů můžete přecházet mezi řádky</translation> <translation id="4188530942454211480">Předchozí věta</translation> <translation id="4191918948604314587">Tlačítko</translation> <translation id="419265409837491189">Přejít na předchozí sloupec</translation> @@ -708,6 +713,7 @@ <translation id="6583174818554398774">Přejít na další při úrovni podrobnosti</translation> <translation id="6587021927234520429">Žádný další nadpis 4. úrovně.</translation> <translation id="6601344353291556895">Aktivovat podrobné popisy.</translation> +<translation id="6609828810966525877">Další gesta najdete v režimu výuky a v centru nápovědy pro Chromebooky</translation> <translation id="6615602925644411249">Vyhledávání na stránce</translation> <translation id="6628427060004938651">Část</translation> <translation id="6633350132811819843">Žádná další tabulka.</translation> @@ -759,6 +765,7 @@ Chcete-li přejít na další otevřenou kartu, stiskněte Control + tabulátor. Chcete-li otevřít nabídku prohlížeče Chrome, stiskněte Alt + F.</translation> <translation id="7086377898680121060">Zvýšit jas</translation> +<translation id="7088743565397416204">Dvojitým klepnutím aktivujete vybranou položku</translation> <translation id="7095834689119144465">Úprava textu – pouze číslice</translation> <translation id="7096001299300236431">Předchozí mediální objekt</translation> <translation id="7116595520562830928">více řádků</translation> @@ -814,6 +821,7 @@ <translation id="7491962110804786152">karta</translation> <translation id="7492049978501397201">Aktivovaný dialog</translation> <translation id="7518543783849163354">Chcete-li hlasovou odezvu nástroje ChromeVox dočasně pozastavit, stiskněte klávesu Control.</translation> +<translation id="7521682724501952239">Funkci ChromeVox můžete používat s dotykovou obrazovkou.</translation> <translation id="7532613204005497612">Červen</translation> <translation id="7552432549459840808">Užitečné klávesové zkratky prohlížeče Chrome</translation> <translation id="7579911500627256166">bod <ph name="DOT" /></translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_el.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_el.xtb index 01f0720..d45f078 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_el.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_el.xtb
@@ -45,6 +45,7 @@ <translation id="1275718070701477396">Επιλεγμένο</translation> <translation id="1286609444451033486">Πατήστε τα πλήκτρα Αναζήτηση+Space για εναλλαγή.</translation> <translation id="1291286136605998134">Κουμπί εναλλαγής</translation> +<translation id="1303806948938513162">Πατήστε με τέσσερα δάκτυλα για εισαγωγή στα μενού ChromeVox</translation> <translation id="1319608975892113573">Δεν υπάρχει προηγούμενη ενότητα σε παράθεση.</translation> <translation id="1321576897702511272">Απόκρυψη βοήθειας ChromeVox</translation> <translation id="1331702245475014624"><ph name="INDEX" /> από <ph name="TOTAL" /></translation> @@ -239,6 +240,7 @@ <translation id="3046838483509668188">Επιλογές ChromeVox</translation> <translation id="3047143736589213134">Πειραματική αντιστοίχιση πλήκτρων</translation> <translation id="3060756054951570867">Το μενού <ph name="TITLE" /> άνοιξε</translation> +<translation id="3060880924447482063">Σύρετε προς τα αριστερά ή προς τα δεξιά για μετακίνηση ανά στοιχείο</translation> <translation id="3070245424257836917">Σύρετε τρία δάκτυλα προς τα πάνω</translation> <translation id="3078345202707391975">Επικεφαλίδα επόμενου επιπέδου 2</translation> <translation id="3078740164268491126">πίνακας</translation> @@ -332,6 +334,7 @@ <translation id="3389259863310851658">Προηγούμενο πεδίο φόρμας</translation> <translation id="3390225400784126843">Επόμενο διαφορετικό στοιχείο.</translation> <translation id="3392045790598181549"><ph name="NAME" />, στοιχείο μενού</translation> +<translation id="3393605254399152980">Σύρετε ένα δάκτυλο για να ακούσετε τι αγγίζετε</translation> <translation id="3406283310380167331">Εμφάνιση λίστας φορμών</translation> <translation id="3423495725743882470">σειρά $1 στήλη $2</translation> <translation id="3457000393508828486">Έχει πατηθεί μερικώς</translation> @@ -347,6 +350,7 @@ <translation id="3497063866483065785">{COUNT,plural, =1{λατινικό ερωτηματικό}other{# λατινικά ερωτηματικά}}</translation> <translation id="3514822174137761109">{COUNT,plural, =1{σύμβολο προσθήκης}other{# σύμβολα προσθήκης}}</translation> <translation id="352577523970648069">Ένα πεδίο κειμένου με δυνατότητα επεξεργασίας</translation> +<translation id="3549680091535286226">Πατήστε με δύο δάκτυλα για να διακόψετε προσωρινά την ομιλία</translation> <translation id="3568702578574425662"><ph name="NAME" />, το πλαίσιο ελέγχου δεν είναι επιλεγμένο</translation> <translation id="3589661172894441357">Γλωσσάρι</translation> <translation id="3599054940393788245">Εκτός του math</translation> @@ -411,6 +415,7 @@ <translation id="4166192625054637755">Λήξη δείκτη</translation> <translation id="4173994908659439270">Δεν υπάρχει επόμενο πεδίο με δυνατότητα επεξεργασίας.</translation> <translation id="4176463684765177261">Απενεργοποιημένη</translation> +<translation id="4187322598335821254">Σύρετε προς τα επάνω ή προς τα κάτω για μετακίνηση ανά γραμμή</translation> <translation id="4188530942454211480">Προηγούμενη πρόταση</translation> <translation id="4191918948604314587">Ένα κουμπί</translation> <translation id="419265409837491189">Μετάβαση στην προηγούμενη στήλη</translation> @@ -709,6 +714,7 @@ <translation id="6583174818554398774">Μετακίνηση στο επόμενο επίπεδο ευαισθησίας</translation> <translation id="6587021927234520429">Δεν υπάρχει επόμενη επικεφαλίδα επιπέδου 4.</translation> <translation id="6601344353291556895">Ενεργοποίηση περιγραφών verbose.</translation> +<translation id="6609828810966525877">Εξερευνήστε περισσότερες κινήσεις στη λειτουργία εκμάθησης και στο Κέντρο βοήθειας Chromebook</translation> <translation id="6615602925644411249">Εύρεση στη σελίδα.</translation> <translation id="6628427060004938651">Τμήμα</translation> <translation id="6633350132811819843">Δεν υπάρχει επόμενος πίνακας.</translation> @@ -761,6 +767,7 @@ Για μετακίνηση προς τα εμπρός μεταξύ των ανοικτών καρτελών, χρησιμοποιήστε τον συνδυασμό Control+Tab. Για άνοιγμα του μενού του προγράμματος περιήγησης Chrome, πατήστε Alt+F.</translation> <translation id="7086377898680121060">Αύξηση φωτεινότητας</translation> +<translation id="7088743565397416204">Πατήστε δύο φορές για να ενεργοποιήσετε το εστιασμένο στοιχείο</translation> <translation id="7095834689119144465">Επεξεργασία κειμένου μόνο για αριθμούς</translation> <translation id="7096001299300236431">Προηγούμενο μέσο</translation> <translation id="7116595520562830928">πολλές γραμμές</translation> @@ -816,6 +823,7 @@ <translation id="7491962110804786152">καρτέλα</translation> <translation id="7492049978501397201">Έγινε εισαγωγή διαλόγου</translation> <translation id="7518543783849163354">Για προσωρινή διακοπή της εκφώνησης του ChromeVox, πατήστε το πλήκτρο Control.</translation> +<translation id="7521682724501952239">Μπορείτε να χρησιμοποιήσετε το ChromeVox με την οθόνη αφής.</translation> <translation id="7532613204005497612">Ιούνιος</translation> <translation id="7552432549459840808">Χρήσιμες συντομεύσεις Chrome</translation> <translation id="7579911500627256166">κουκκίδα <ph name="DOT" /></translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_en-GB.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_en-GB.xtb index 48cbb767f..23b9f92 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_en-GB.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_en-GB.xtb
@@ -45,6 +45,7 @@ <translation id="1275718070701477396">Selected</translation> <translation id="1286609444451033486">Press Search+Space to toggle.</translation> <translation id="1291286136605998134">Toggle button</translation> +<translation id="1303806948938513162">Tap with 4 fingers to enter the ChromeVox menus</translation> <translation id="1319608975892113573">No previous block quote.</translation> <translation id="1321576897702511272">Hide ChromeVox help</translation> <translation id="1331702245475014624"><ph name="INDEX" /> of <ph name="TOTAL" /></translation> @@ -239,6 +240,7 @@ <translation id="3046838483509668188">ChromeVox Options</translation> <translation id="3047143736589213134">Experimental keymap</translation> <translation id="3060756054951570867"><ph name="TITLE" /> menu opened</translation> +<translation id="3060880924447482063">Swipe left or right to move by item</translation> <translation id="3070245424257836917">Swipe three fingers up</translation> <translation id="3078345202707391975">Next level 2 heading</translation> <translation id="3078740164268491126">table</translation> @@ -332,6 +334,7 @@ <translation id="3389259863310851658">Previous form field</translation> <translation id="3390225400784126843">Next different element.</translation> <translation id="3392045790598181549"><ph name="NAME" />, menu item</translation> +<translation id="3393605254399152980">Drag one finger to hear what you touch</translation> <translation id="3406283310380167331">Show forms list</translation> <translation id="3423495725743882470">row $1 column $2</translation> <translation id="3457000393508828486">Partially pressed</translation> @@ -347,6 +350,7 @@ <translation id="3497063866483065785">{COUNT,plural, =1{question mark}other{# question marks}}</translation> <translation id="3514822174137761109">{COUNT,plural, =1{caret}other{# carets}}</translation> <translation id="352577523970648069">An editable text field</translation> +<translation id="3549680091535286226">Tap with 2 fingers to temporarily stop speech</translation> <translation id="3568702578574425662"><ph name="NAME" />, tick box not ticked</translation> <translation id="3589661172894441357">Glossary</translation> <translation id="3599054940393788245">Not inside math</translation> @@ -411,6 +415,7 @@ <translation id="4166192625054637755">Subscript end</translation> <translation id="4173994908659439270">No next editable text field.</translation> <translation id="4176463684765177261">Disabled</translation> +<translation id="4187322598335821254">Swipe up or down to move by line</translation> <translation id="4188530942454211480">Previous Sentence</translation> <translation id="4191918948604314587">A button</translation> <translation id="419265409837491189">Go to the previous column</translation> @@ -709,6 +714,7 @@ <translation id="6583174818554398774">Move to next at granularity</translation> <translation id="6587021927234520429">No next level 4 heading.</translation> <translation id="6601344353291556895">Enable verbose descriptions.</translation> +<translation id="6609828810966525877">Explore more gestures in Learn Mode and the Chromebook Help Centre</translation> <translation id="6615602925644411249">Find in page.</translation> <translation id="6628427060004938651">Part</translation> <translation id="6633350132811819843">No next table.</translation> @@ -760,6 +766,7 @@ To move forward between open tabs, use Control+Tab. To open the Chrome browser menu, press Alt+F.</translation> <translation id="7086377898680121060">Brightness up</translation> +<translation id="7088743565397416204">Double-tap to activate what is focused</translation> <translation id="7095834689119144465">Edit text numeric only</translation> <translation id="7096001299300236431">Previous media</translation> <translation id="7116595520562830928">multln</translation> @@ -815,6 +822,7 @@ <translation id="7491962110804786152">tab</translation> <translation id="7492049978501397201">Entered dialogue</translation> <translation id="7518543783849163354">To temporarily stop ChromeVox from speaking, press the Control key.</translation> +<translation id="7521682724501952239">You can use ChromeVox with the touchscreen.</translation> <translation id="7532613204005497612">June</translation> <translation id="7552432549459840808">Helpful Chrome Shortcuts</translation> <translation id="7579911500627256166">dot <ph name="DOT" /></translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_iw.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_iw.xtb index 026f9cd..92600cd 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_iw.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_iw.xtb
@@ -398,7 +398,7 @@ <translation id="4058278702844053247">מתבצעת טעינת דף</translation> <translation id="4065205963140826639">נסה להקיש על מקש החיפוש ועל החץ ימינה כדי למצוא את לחצן 'הבא'. לאחר מכן הקש על מקש החיפוש ומקש הרווח כדי ללחוץ עליו.</translation> <translation id="4081085052247739398">{COUNT,plural, =1{טילדה (~)}two{# סימני טילדה (~)}many{# סימני טילדה (~)}other{# סימני טילדה (~)}}</translation> -<translation id="4086311032171418648">יוצא ממצב למידה.</translation> +<translation id="4086311032171418648">יציאה ממצב למידה.</translation> <translation id="409334809956508737">האובייקט הקודם</translation> <translation id="4099274309791143834">כולל תפריט משנה</translation> <translation id="4101527861445851766">תיבת סימון שסומנה</translation> @@ -501,7 +501,7 @@ <translation id="4877261390094455813">הזן שאילתת חיפוש.</translation> <translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation> <translation id="489907760999452556">קישור פנימי</translation> -<translation id="4915087353619183190">מפעיל מצב למידה. הקשה על מקש במקלדת qwerty, מקש ברייל בתצוגה הניתנת לרענון או ביצוע תנועת מגע יציגו את הפעולה המבוצעת. כדי לצאת יש להקיש על Control יחד עם W, או על מקש Esc.</translation> +<translation id="4915087353619183190">הפעלה של מצב למידה. הקשה על מקש במקלדת qwerty, מקש ברייל בתצוגה הניתנת לרענון או ביצוע תנועת מגע יציגו את הפעולה המבוצעת. כדי לצאת יש להקיש על Control יחד עם W, או על מקש Esc.</translation> <translation id="492295894462528572">פתח דבר</translation> <translation id="495170559598752135">פעולות</translation> <translation id="4953585991029886728">ערוך טקסט</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_te.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_te.xtb index 87dc1a7b..b17772b 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_te.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_te.xtb
@@ -53,7 +53,7 @@ <translation id="1342835525016946179">కథనం</translation> <translation id="1346748346194534595">కుడి</translation> <translation id="135978014023467274">మీరు ChromeVox 63కు అప్డేట్ అయ్యారు!</translation> -<translation id="136718599399906424">తదుపరి పట్టిక అడ్డు వరుస</translation> +<translation id="136718599399906424">తర్వాత పట్టిక అడ్డు వరుస</translation> <translation id="1377925789329510816">ఇది చివరి ముఖ్యశీర్షిక. మొదటి ముఖ్యశీర్షికకు సర్దుబాటు చేసేందుకు, శోధన+H నొక్కండి లేదా ఈ పేజీలోని రెండవ ముఖ్యశీర్షికకు వెళ్లేందుకు, శోధన+Shift+Hను నొక్కండి.</translation> <translation id="1383876407941801731">శోధించు</translation> <translation id="1385214448885562192">ఆమోదించడానికి enterని లేదా రద్దు చేయడానికి escapeని, తదుపరి దాని కోసం క్రిందికి మరియు మునుపటి దాని కోసం పైకి నొక్కండి.</translation> @@ -617,7 +617,7 @@ <translation id="5703716265115423771">వాల్యూమ్ తగ్గిస్తుంది</translation> <translation id="5709192780268610569">పెద్ద వివరణ లేదు</translation> <translation id="5712244464475377681">popbtn</translation> -<translation id="5712338278108304766">తదుపరి పట్టిక నిలువు వరుస</translation> +<translation id="5712338278108304766">తర్వాత పట్టిక నిలువు వరుస</translation> <translation id="571866080859340309">విశ్లేషణ సమూహాలు</translation> <translation id="5728409797179002635">పట్టిక కనుగొనబడలేదు.</translation> <translation id="5729047866208036762">గణితాన్ని అన్వేషించడానికి పైకి, కిందకు, ఎడమకు లేదా కుడి చిహ్నాల కీలను నొక్కండి.</translation> @@ -711,7 +711,7 @@ <translation id="6601344353291556895">విశదీకృత వివరణలను ప్రారంభించండి.</translation> <translation id="6615602925644411249">పేజీలో కనుగొనండి.</translation> <translation id="6628427060004938651">భాగం</translation> -<translation id="6633350132811819843">తదుపరి పట్టిక లేదు.</translation> +<translation id="6633350132811819843">తర్వాత పట్టిక లేదు.</translation> <translation id="6637586476836377253">log</translation> <translation id="6657128831881431364">ప్రోగ్రెస్ పట్టీ</translation> <translation id="6659594942844771486">టాబ్</translation> @@ -801,7 +801,7 @@ <translation id="7362871137496673139">మునుపటి స్థాయి 2 శీర్షిక లేదు.</translation> <translation id="7370432716629432284">{COUNT,plural, =1{ఆంపర్సండ్ గుర్తు}other{# ఆంపర్సండ్ గుర్తులు}}</translation> <translation id="737396357417333429">clk</translation> -<translation id="7374104575779636480">పట్టిక నుండి నిష్క్రమిస్తున్నారు.</translation> +<translation id="7374104575779636480">పట్టికను వదిలిపెడుతున్నారు.</translation> <translation id="7392145451309930991">వచన సరిపోలిక ప్రారంభం</translation> <translation id="739763518212184081">మునుపటి పంక్తి</translation> <translation id="7400575256015741911">అక్షరదోషం కనుగొనబడింది</translation> @@ -825,7 +825,7 @@ <translation id="7609363189280667021">బ్రెయిలీ శీర్షికలను టోగుల్ చేయండి</translation> <translation id="761303759119251275">సహకారి</translation> <translation id="762020119231868829">ప్రస్తుతం ప్లే అవుతున్న అన్ని మీడియా విడ్జెట్లను పాజ్ చేస్తుంది</translation> -<translation id="7625690649919402823">తదుపరి పట్టిక</translation> +<translation id="7625690649919402823">తర్వాత పట్టిక</translation> <translation id="7628927569678398026"><ph name="LOCALE" /> (<ph name="VARIANT" />), గ్రేడ్ <ph name="GRADE" /></translation> <translation id="7641134354185483015">మునుపటి స్థాయి 3 శీర్షిక లేదు.</translation> <translation id="7647456547678091388">చిట్కా</translation>
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-TW.xtb b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-TW.xtb index 0deb50b..ee23f661 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-TW.xtb +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings_zh-TW.xtb
@@ -501,7 +501,7 @@ <translation id="4877261390094455813">輸入搜尋查詢。</translation> <translation id="4886524826165775965">第 <ph name="INDEX" /> 個,共 <ph name="TOTAL" /> 個</translation> <translation id="489907760999452556">內部連結</translation> -<translation id="4915087353619183190">正在啟動學習模式。按下 Qwerty 鍵、可更新點字鍵或觸控手勢即可學習相關功能。按下 Ctrl + W 或 Escape 鍵即可結束。</translation> +<translation id="4915087353619183190">正在啟動學習模式。按下 Qwerty 鍵、可更新的點字鍵或觸控手勢即可學習相關功能。按下 Ctrl + W 或 Escape 鍵即可結束。</translation> <translation id="492295894462528572">前言</translation> <translation id="495170559598752135">動作</translation> <translation id="4953585991029886728">編輯文字</translation>
diff --git a/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js b/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js index f3706ce..38ad21d 100644 --- a/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js +++ b/chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js
@@ -781,21 +781,23 @@ } if (this.prefsManager_.wordHighlightingEnabled() && this.currentNodeWord_ != null) { - // Only show the highlight if this is an inline text box. - // Otherwise we'd be highlighting entire nodes, like images. - // Highlight should be only for text. - // Note that boundsForRange doesn't work on staticText. + var charIndexInParent = 0; + // getStartCharIndexInParent is only defined for nodes with role + // INLINE_TEXT_BOX. if (node.role == RoleType.INLINE_TEXT_BOX) { - let charIndexInParent = ParagraphUtils.getStartCharIndexInParent(node); - chrome.accessibilityPrivate.setHighlights( - [node.boundsForRange( - this.currentNodeWord_.start - charIndexInParent, - this.currentNodeWord_.end - charIndexInParent)], - this.prefsManager_.highlightColor()); - } else { - chrome.accessibilityPrivate.setHighlights( - [], this.prefsManager_.highlightColor()); + charIndexInParent = ParagraphUtils.getStartCharIndexInParent(node); } + node.boundsForRange( + this.currentNodeWord_.start - charIndexInParent, + this.currentNodeWord_.end - charIndexInParent, (bounds) => { + if (bounds) { + chrome.accessibilityPrivate.setHighlights( + [bounds], this.prefsManager_.highlightColor()); + } else { + chrome.accessibilityPrivate.setHighlights( + [], this.prefsManager_.highlightColor()); + } + }); } // Show the parent element of the currently verbalized node with the // focus ring. This is a nicer user-facing behavior than jumping from
diff --git a/chrome/browser/resources/cryptotoken/signer.js b/chrome/browser/resources/cryptotoken/signer.js index e909bd79..9cbb78d 100644 --- a/chrome/browser/resources/cryptotoken/signer.js +++ b/chrome/browser/resources/cryptotoken/signer.js
@@ -425,8 +425,9 @@ * @return {boolean} Whether the challenge could be added. * @private */ -Signer.prototype.doSign_ = function() { +Signer.prototype.doSign_ = async function() { // Create the browser data for each challenge. + let challengeVal; for (var i = 0; i < this.signChallenges_.length; i++) { var challenge = this.signChallenges_[i]; var serverChallenge; @@ -435,6 +436,7 @@ } else { serverChallenge = this.defaultChallenge_; } + challengeVal = serverChallenge; if (!serverChallenge) { console.warn(UTIL_fmt('challenge missing')); return false; @@ -452,13 +454,161 @@ this.getChallengeHash_.bind(this)); var timeoutSeconds = this.timer_.millisecondsUntilExpired() / 1000.0; - var request = - makeSignHelperRequest(encodedChallenges, timeoutSeconds, this.logMsgUrl_); - this.handler_ = FACTORY_REGISTRY.getRequestHelper().getHandler( - /** @type {HelperRequest} */ (request)); - if (!this.handler_) + + // Check to see if WebAuthn or legacy U2F requests should be used. + await new Promise(resolve => { + if (!chrome.cryptotokenPrivate || !window.PublicKeyCredential) { + resolve(false); + } else { + chrome.cryptotokenPrivate.canProxyToWebAuthn(resolve); + } + }).then(shouldUseWebAuthn => { + if (shouldUseWebAuthn) { + // If we can proxy to WebAuthn, send the request via WebAuthn. + return this.doSignWebAuthn_(encodedChallenges, challengeVal); + } + var request = makeSignHelperRequest( + encodedChallenges, timeoutSeconds, this.logMsgUrl_); + this.handler_ = FACTORY_REGISTRY.getRequestHelper().getHandler( + /** @type {HelperRequest} */ (request)); + if (!this.handler_) + return false; + return this.handler_.run(this.helperComplete_.bind(this)); + }); +}; + +/** + * Sends the sign request via the WebAuthn API. + * @param {!Array<SignHelperChallenge>} encodedChallenges Credential list + * provided by the relying party to be signed. + * @param {string} challengeVal Base64 encoded challenge. + * @return {boolean} If the message was sent. + * @private + */ +Signer.prototype.doSignWebAuthn_ = function(encodedChallenges, challengeVal) { + // Only try to sign if challenges were provided. + if (encodedChallenges.length === 0) { return false; - return this.handler_.run(this.helperComplete_.bind(this)); + } + + const credentialList = []; + for (let i = 0; i < encodedChallenges.length; i++) { + credentialList.push({ + type: 'public-key', + id: new Uint8Array(B64_decode(encodedChallenges[i].keyHandle)).buffer, + }); + } + // App ID could be defined for each challenge or globally. + const appid = this.signChallenges_[0].hasOwnProperty('appId') ? + this.signChallenges_[0]['appId'] : + this.appId_; + + const request = { + publicKey: { + challenge: new Uint8Array(B64_decode(challengeVal)).buffer, + timeout: this.timer_.millisecondsUntilExpired(), + rpId: this.sender_.origin, + allowCredentials: credentialList, + userVerification: 'discouraged', + extensions: { + appid: appid, + }, + }, + }; + navigator.credentials.get(request) + .then(response => { + this.handleWebAuthnSuccess_(response); + }) + .catch(exception => { + this.handleWebAuthnError_(exception); + }); + + return true; +}; + +/** + * Converts the WebAuthn error code to a U2F error code. + * @param {*} exception Exception returned from the WebAuthn request. + * @private + */ +Signer.prototype.handleWebAuthnError_ = function(exception) { + const domError = /** @type {!DOMException} */ (exception); + let errorCode = ErrorCodes.OTHER_ERROR; + let errorDetails; + + if (domError && domError.name) { + switch (domError.name) { + case 'NotAllowedError': + errorCode = ErrorCodes.TIMEOUT; + break; + case 'InvalidStateError': + errorCode = ErrorCodes.DEVICE_INELIGIBLE; + break; + default: + // Fall through + break; + } + } + + this.notifyError_({ + errorCode: errorCode, + errorMessage: domError.toString(), + }); +}; + +/** + * Converts the WebAuthn response to the response for cryptotoken. + * @param {?PublicKeyCredential} assertion Assertion object received from + * credential request. + * @private + */ +Signer.prototype.handleWebAuthnSuccess_ = function(assertion) { + // Find the challenge to which this assertion corresponds. + const assertionKeyHandle = assertion['id']; + let signChallenge; + for (let i = 0; i < this.signChallenges_.length; i++) { + if (this.signChallenges_[i]['keyHandle'] === assertionKeyHandle) { + signChallenge = this.signChallenges_[i]; + break; + } + } + + if (signChallenge === undefined) { + console.warn('Response received from unknown key'); + this.notifyError_({ + errorCode: ErrorCodes.DEVICE_INELIGIBLE, + errorMessage: 'Response received from unknown key', + }); + return; + } + + // First 32 bytes of authenticator data is the rpIdHash. + let index = 32; + const authenticatorDataBytes = + new Uint8Array(assertion['response']['authenticatorData']); + if (authenticatorDataBytes.length < index + 4) { + // Invalid response length. + this.notifyError_({ + errorCode: ErrorCodes.OTHER_ERROR, + errorMessage: 'Invalid response message', + }); + return; + } + + const flags = [authenticatorDataBytes[index++] & 0x3]; + const counter = Array.from(authenticatorDataBytes.slice(index, index + 4)); + const signature = + Array.from(new Uint8Array(assertion['response']['signature'])); + + // Combine the flags byte with the counter and signature to recreate the U2F + // authentication response message. + const signResponse = flags.concat(counter).concat(signature); + + // Decode the ArrayBuffer view of the clientDataJSON into a string. + const clientDataJSON = new TextDecoder('utf-8').decode( + new Uint8Array(assertion['response']['clientDataJSON'])); + + this.notifySuccess_(signChallenge, B64_encode(signResponse), clientDataJSON); }; /**
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js index 955ceaf..c790f1f 100644 --- a/chrome/browser/resources/gaia_auth_host/authenticator.js +++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -398,8 +398,12 @@ url = appendParam(url, 'source', CONSTRAINED_FLOW_SOURCE); if (data.flow) url = appendParam(url, 'flow', data.flow); - if (data.emailDomain) + 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; };
diff --git a/chrome/browser/resources/md_bookmarks/.eslintrc.js b/chrome/browser/resources/md_bookmarks/.eslintrc.js index 847d6e995..e9a7f15 100644 --- a/chrome/browser/resources/md_bookmarks/.eslintrc.js +++ b/chrome/browser/resources/md_bookmarks/.eslintrc.js
@@ -7,6 +7,9 @@ 'browser': true, 'es6': true, }, + 'parserOptions': { + 'ecmaVersion': 2017, + }, 'rules': { 'no-var': 'error', },
diff --git a/chrome/browser/resources/md_bookmarks/command_manager.js b/chrome/browser/resources/md_bookmarks/command_manager.js index 1956541..e573fdf 100644 --- a/chrome/browser/resources/md_bookmarks/command_manager.js +++ b/chrome/browser/resources/md_bookmarks/command_manager.js
@@ -735,18 +735,16 @@ * @param {boolean} canUndo If true, shows an undo button in the toast. * @private */ - showTitleToast_: function(labelPromise, title, canUndo) { - labelPromise.then(function(label) { - const pieces = loadTimeData.getSubstitutedStringPieces(label, title) - .map(function(p) { - // Make the bookmark name collapsible. - p.collapsible = !!p.arg; - return p; - }); + showTitleToast_: async function(labelPromise, title, canUndo) { + const label = await labelPromise; + const pieces = loadTimeData.getSubstitutedStringPieces(label, title) + .map(function(p) { + // Make the bookmark name collapsible. + p.collapsible = !!p.arg; + return p; + }); - bookmarks.ToastManager.getInstance().showForStringPieces( - pieces, canUndo); - }); + bookmarks.ToastManager.getInstance().showForStringPieces(pieces, canUndo); }, ////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/resources/md_bookmarks/list.js b/chrome/browser/resources/md_bookmarks/list.js index e5ea45f..f2b2c60c 100644 --- a/chrome/browser/resources/md_bookmarks/list.js +++ b/chrome/browser/resources/md_bookmarks/list.js
@@ -95,15 +95,15 @@ * @param {Array<string>} newValue * @param {Array<string>} oldValue */ - onDisplayedIdsChanged_: function(newValue, oldValue) { + onDisplayedIdsChanged_: async function(newValue, oldValue) { const updatedList = newValue.map(id => ({id: id})); this.updateList('displayedList_', item => item.id, updatedList); // Trigger a layout of the iron list. Otherwise some elements may render // as blank entries. See https://crbug.com/848683 this.$.list.fire('iron-resize'); - cr.sendWithPromise( - 'getPluralString', 'listChanged', this.displayedList_.length) - .then(label => this.fire('iron-announce', {text: label})); + const label = await cr.sendWithPromise( + 'getPluralString', 'listChanged', this.displayedList_.length); + this.fire('iron-announce', {text: label}); }, /** @private */
diff --git a/chrome/browser/resources/settings/controls/controlled_button.html b/chrome/browser/resources/settings/controls/controlled_button.html index 96fe2f6..8490516 100644 --- a/chrome/browser/resources/settings/controls/controlled_button.html +++ b/chrome/browser/resources/settings/controls/controlled_button.html
@@ -31,8 +31,6 @@ } :host(:not([end-justified])) cr-policy-pref-indicator { - margin-inline-end: calc( - var(--cr-controlled-by-spacing) - var(--justify-margin)); margin-inline-start: var(--cr-controlled-by-spacing); }
diff --git a/chrome/browser/resources/settings/device_page/display.html b/chrome/browser/resources/settings/device_page/display.html index 8c7b7425..4419719 100644 --- a/chrome/browser/resources/settings/device_page/display.html +++ b/chrome/browser/resources/settings/device_page/display.html
@@ -4,6 +4,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> <link rel="import" href="chrome://resources/cr_elements/paper_tabs_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> @@ -54,6 +55,10 @@ padding-inline-start: 0 } + .settings-box > cr-policy-pref-indicator { + margin-inline-end: var(--cr-controlled-by-spacing); + } + #controlsDiv > .settings-box:first-of-type { border-top: none; } @@ -146,10 +151,20 @@ [[logicalResolutionText_]] </div> </div> + <template is="dom-if" if="[[isDisplayScaleManagedByPolicy_( + selectedDisplay, prefs.cros.device_display_resolution)]]"> + <cr-policy-pref-indicator + pref="[[prefs.cros.device_display_resolution]]" + icon-aria-label="$i18n{displayResolutionText}"> + </cr-policy-pref-indicator> + </template> <settings-slider id="displaySizeSlider" ticks="[[zoomValues_]]" pref="{{selectedZoomPref_}}" label-min="$i18n{displaySizeSliderMinLabel}" label-max="$i18n{displaySizeSliderMaxLabel}" + disabled="[[isDisplayScaleMandatory_( + selectedDisplay, + prefs.cros.device_display_resolution)]]" on-value-changed="onDisplaySizeSliderDrag_"> </settings-slider> </div> @@ -163,8 +178,17 @@ $i18n{displayResolutionSublabel} </div> </div> + <template is="dom-if" if="[[isDisplayResolutionManagedByPolicy_( + prefs.cros.device_display_resolution)]]"> + <cr-policy-pref-indicator + pref="[[prefs.cros.device_display_resolution]]" + icon-aria-label="$i18n{displayResolutionText}"> + </cr-policy-pref-indicator> + </template> <settings-dropdown-menu id="displayModeSelector" pref="{{selectedModePref_}}" + disabled="[[isDisplayResolutionMandatory_( + prefs.cros.device_display_resolution)]]" label="Display Mode Menu" menu-options="[[displayModeList_]]"> </settings-dropdown-menu> @@ -174,6 +198,13 @@ <div id="displayOrientation" class="start text-area"> $i18n{displayOrientation} </div> + <template is="dom-if" if="[[isDevicePolicyEnabled_( + prefs.cros.display_rotation_default)]]"> + <cr-policy-pref-indicator + pref="[[prefs.cros.display_rotation_default]]" + icon-aria-label="$i18n{displayOrientation}"> + </cr-policy-pref-indicator> + </template> <select class="md-select" value="[[selectedDisplay.rotation]]" disabled="[[selectedDisplay.isTabletMode]]" aria-labelledby="displayOrientation"
diff --git a/chrome/browser/resources/settings/device_page/display.js b/chrome/browser/resources/settings/device_page/display.js index cbe128d..51ddbb4e 100644 --- a/chrome/browser/resources/settings/device_page/display.js +++ b/chrome/browser/resources/settings/device_page/display.js
@@ -18,6 +18,20 @@ CUSTOM: 2, }; +/** + * @typedef {{ + * value: (!{ + * recommended: (boolean|undefined), + * external_width: (number|undefined), + * external_height: (number|undefined), + * external_use_native: (boolean|undefined), + * external_scale_percentage: (number|undefined), + * internal_scale_percentage: (number|undefined) + * }|null) + * }} + */ +let DisplayResolutionPrefObject; + cr.define('settings.display', function() { const systemDisplayApi = /** @type {!SystemDisplay} */ (chrome.system.display); @@ -182,7 +196,7 @@ 'updateNightLightScheduleSettings_(prefs.ash.night_light.schedule_type.*,' + ' prefs.ash.night_light.enabled.*)', 'onSelectedModeChange_(selectedModePref_.value)', - 'onSelectedZoomChange_(selectedZoomPref_.value)', + 'onSelectedZoomChange_(selectedZoomPref_.value)' ], /** @private {number} Selected mode index received from chrome. */ @@ -285,6 +299,69 @@ }, /** + * Checks if the given device policy is enabled. + * @param {DisplayResolutionPrefObject} policyPref + * @return {boolean} + * @private + */ + isDevicePolicyEnabled_: function(policyPref) { + return policyPref !== undefined && policyPref.value !== null; + }, + + /** + * Checks if display resolution is managed by device policy. + * @param {DisplayResolutionPrefObject} resolutionPref + * @return {boolean} + * @private + */ + isDisplayResolutionManagedByPolicy_: function(resolutionPref) { + return this.isDevicePolicyEnabled_(resolutionPref) && + (resolutionPref.value.external_use_native !== undefined || + (resolutionPref.value.external_width !== undefined && + resolutionPref.value.external_height !== undefined)); + }, + + /** + * Checks if display resolution is managed by policy and the policy + * is mandatory. + * @param {DisplayResolutionPrefObject} resolutionPref + * @return {boolean} + * @private + */ + isDisplayResolutionMandatory_: function(resolutionPref) { + return this.isDisplayResolutionManagedByPolicy_(resolutionPref) && + !resolutionPref.value.recommended; + }, + + /** + * Checks if display scale factor is managed by device policy. + * @param {chrome.system.display.DisplayUnitInfo} selectedDisplay + * @param {DisplayResolutionPrefObject} resolutionPref + * @return {boolean} + * @private + */ + isDisplayScaleManagedByPolicy_: function(selectedDisplay, resolutionPref) { + if (!this.isDevicePolicyEnabled_(resolutionPref) || !selectedDisplay) + return false; + if (selectedDisplay.isInternal) + return resolutionPref.value.internal_scale_percentage !== undefined; + return resolutionPref.value.external_scale_percentage !== undefined; + }, + + /** + * Checks if display scale factor is managed by policy and the policy + * is mandatory. + * @param {DisplayResolutionPrefObject} resolutionPref + * @return {boolean} + * @private + */ + isDisplayScaleMandatory_: function(selectedDisplay, resolutionPref) { + return this.isDisplayScaleManagedByPolicy_( + selectedDisplay, resolutionPref) && + !resolutionPref.value.recommended; + }, + + /** * Returns the list of display modes that is shown to the user in a drop down * menu. * @param {!chrome.system.display.DisplayUnitInfo} selectedDisplay
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.html b/chrome/browser/resources/settings/internet_page/internet_detail_page.html index 217c99d..5db10d87 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.html
@@ -47,7 +47,8 @@ } cr-policy-network-indicator, - cr-policy-indicator { + cr-policy-indicator, + cr-policy-pref-indicator { margin-inline-start: var(--settings-controlled-by-spacing); } @@ -178,6 +179,30 @@ </cr-toggle> </div> </template> + <!-- Always-on VPN. --> + <template is="dom-if" + if="[[showAlwaysOnVpn_(networkProperties)]]"> + <div class="settings-box"> + <div id="AlwaysOnVpnToggleLabel" class="start"> + $i18n{networkAlwaysOnVpn} + </div> + <cr-toggle checked="{{alwaysOnVpn_}}" + disabled="[[!enableAlwaysOnVpn_(networkProperties, + prefs.vpn_config_allowed)]]" + aria-labelledby="AlwaysOnVpnToggleLabel" + on-change="onAlwaysOnVpnChange_"> + </cr-toggle> + <template is="dom-if" + if="[[!enableAlwaysOnVpn_(networkProperties, + prefs.vpn_config_allowed)]]"> + <cr-policy-pref-indicator + pref="[[getVpnConfigPrefFromValue_(networkProperties, + prefs.vpn_config_allowed)]]" on-click="onIndicatorTap_" + icon-aria-label="AlwaysOnVpnToggleLabel"> + </cr-policy-pref-indicator> + </template> + </div> + </template> <!-- Data roaming (Cellular only). --> <template is="dom-if" if="[[isCellular_(networkProperties)]]"> <settings-toggle-button id="allowDataRoaming"
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.js b/chrome/browser/resources/settings/internet_page/internet_detail_page.js index d1439e6..d3ceb3eb 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.js +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.js
@@ -115,6 +115,15 @@ }, /** + * State of the Always-on VPN toggle. + * @private + */ + alwaysOnVpn_: { + type: Boolean, + value: false, + }, + + /** * The network preferred state. * @private */ @@ -143,6 +152,10 @@ proxyExpanded_: Boolean, }, + observers: [ + 'onAlwaysOnPrefChanged_(prefs.arc.vpn.always_on.*)', + ], + listeners: { 'network-list-changed': 'checkNetworkExists_', 'networks-changed': 'updateNetworkDetails_' @@ -1038,6 +1051,48 @@ /** * @param {!CrOnc.NetworkProperties} networkProperties + * @return {boolean} Whether the toggle for the Always-on VPN feature is + * displayed. + * @private + */ + showAlwaysOnVpn_: function(networkProperties) { + return this.isArcVpn_(networkProperties) && this.prefs.arc && + this.prefs.arc.vpn && this.prefs.arc.vpn.always_on && + this.prefs.arc.vpn.always_on.vpn_package && + networkProperties.VPN.Host.Active === + this.prefs.arc.vpn.always_on.vpn_package.value; + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties + * @param {!chrome.settingsPrivate.PrefObject} vpnConfigAllowed + * @return {boolean} Whether the toggle for the Always-on VPN feature is + * enabled. + * @private + */ + enableAlwaysOnVpn_: function(networkProperties, vpnConfigAllowed) { + return this.isArcVpn_(networkProperties) && vpnConfigAllowed && + !!vpnConfigAllowed.value; + }, + + /** @private */ + onAlwaysOnPrefChanged_: function() { + if (this.prefs.arc && this.prefs.arc.vpn && this.prefs.arc.vpn.always_on && + this.prefs.arc.vpn.always_on.lockdown) { + this.alwaysOnVpn_ = this.prefs.arc.vpn.always_on.lockdown.value; + } + }, + + /** @private */ + onAlwaysOnVpnChange_: function() { + if (this.prefs.arc && this.prefs.arc.vpn && this.prefs.arc.vpn.always_on && + this.prefs.arc.vpn.always_on.lockdown) { + this.set('prefs.arc.vpn.always_on.lockdown.value', this.alwaysOnVpn_); + } + }, + + /** + * @param {!CrOnc.NetworkProperties} networkProperties * @param {!chrome.networkingPrivate.GlobalPolicy} globalPolicy * @param {boolean} managedNetworkAvailable * @return {boolean} True if the prefer network checkbox should be shown.
diff --git a/chrome/browser/resources/settings/people_page/sync_browser_proxy.js b/chrome/browser/resources/settings/people_page/sync_browser_proxy.js index ffd95617..59b58d05 100644 --- a/chrome/browser/resources/settings/people_page/sync_browser_proxy.js +++ b/chrome/browser/resources/settings/people_page/sync_browser_proxy.js
@@ -218,13 +218,6 @@ * Opens the Google Activity Controls url in a new tab. */ openActivityControlsUrl() {} - - /** - * Function to invoke when the unified consent toggle state changes, to - * notify the C++ layer. - * @param {boolean} toggleChecked - */ - unifiedConsentToggleChanged(toggleChecked) {} } /** @@ -317,11 +310,6 @@ chrome.metricsPrivate.recordUserAction( 'Signin_AccountSettings_GoogleActivityControlsClicked'); } - - /** @override */ - unifiedConsentToggleChanged(toggleChecked) { - chrome.send('UnifiedConsentToggleChanged', [toggleChecked]); - } } cr.addSingletonGetter(SyncBrowserProxyImpl);
diff --git a/chrome/browser/resources/settings/people_page/sync_page.html b/chrome/browser/resources/settings/people_page/sync_page.html index 5e31e9e..ab05881 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.html +++ b/chrome/browser/resources/settings/people_page/sync_page.html
@@ -151,16 +151,6 @@ </div> </template> - <!-- A change of the unified consent toggle state is automatically handled - in the C++ code after a change in the pref is observed. --> - <settings-toggle-button id="unifiedConsentToggle" class="first" - pref="{{prefs.unified_consent_given}}" - label="$i18n{syncUnifiedConsentToggleTitle}" - on-settings-boolean-control-change="onUnifiedConsentToggleChange_" - hidden="[[!shouldShowUnifiedConsentToggle_(unifiedConsentEnabled, - syncStatus.disabled, syncStatus.signedIn)]]" - disabled="[[syncPrefs.encryptAllData]]"> - </settings-toggle-button> <div class="settings-box two-line" id="sync-section-toggle" actionable$="[[!syncSectionDisabled_]]" on-click="toggleExpandButton_" @@ -219,7 +209,7 @@ </div> </template> - <div class="settings-box first" hidden="[[unifiedConsentEnabled]]"> + <div class="settings-box first"> <div id="syncEverythingCheckboxLabel" class="start"> $i18n{syncEverythingCheckboxLabel} </div> @@ -496,7 +486,6 @@ <settings-personalization-options class="list-frame" prefs="{{prefs}}" page-visibility="[[pageVisibility]]" unified-consent-enabled="[[unifiedConsentEnabled]]" - unified-consent-given="{{prefs.unified_consent_given.value}}"> </settings-personalization-options> </iron-collapse> </template>
diff --git a/chrome/browser/resources/settings/people_page/sync_page.js b/chrome/browser/resources/settings/people_page/sync_page.js index 199914c..69e5698 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.js +++ b/chrome/browser/resources/settings/people_page/sync_page.js
@@ -88,7 +88,6 @@ /** @type {settings.SyncStatus} */ syncStatus: { type: Object, - observer: 'onSyncStatusChanged_', }, /** @@ -143,6 +142,7 @@ computed: 'computeSyncSectionDisabled_(' + 'unifiedConsentEnabled, syncStatus.signedIn, syncStatus.disabled, ' + 'syncStatus.hasError, syncStatus.statusAction)', + observer: 'onSyncSectionDisabledChanged_', }, /** @private */ @@ -172,12 +172,6 @@ unifiedConsentEnabled: Boolean, }, - observers: [ - // Depends on signedIn_ so that the sync section is updated on signin - // changes, even though the actual value of signedIn_ is not used. - 'onSyncSectionOpenedShouldChange_(signedIn_, syncSectionDisabled_)', - ], - /** @private {?settings.SyncBrowserProxy} */ browserProxy_: null, @@ -312,20 +306,6 @@ }, /** - * Handles the change event for the unfied consent toggle. - * @private - */ - onUnifiedConsentToggleChange_: function() { - const checked = this.$$('#unifiedConsentToggle').checked; - this.browserProxy_.unifiedConsentToggleChanged(checked); - - if (!checked) { - this.syncSectionOpened_ = !this.syncSectionDisabled_; - this.personalizeSectionOpened_ = true; - } - }, - - /** * Handler for when the sync preferences are updated. * @private */ @@ -584,27 +564,9 @@ settings.navigateTo(settings.routes.BASIC); }, - // Computes the initial layout for the sync section and the personalize - // section. This function only does something on its first call. - onSyncStatusChanged_: function() { - if (!!this.syncStatus && !this.collapsibleSectionsInitialized_) { - this.collapsibleSectionsInitialized_ = true; - this.personalizeSectionOpened_ = - !this.$$('#unifiedConsentToggle').checked || - !!this.syncStatus.setupInProgress; - this.syncSectionOpened_ = - this.personalizeSectionOpened_ && !this.syncSectionDisabled_; - } - }, - - /** - * Collapses the sync section if it becomes disabled, and expands it when it's - * re-enabled. - * @private - */ - onSyncSectionOpenedShouldChange_: function() { - this.syncSectionOpened_ = - !this.syncSectionDisabled_ && !this.$$('#unifiedConsentToggle').checked; + /** @private */ + onSyncSectionDisabledChanged_: function() { + this.syncSectionOpened_ = !this.syncSectionDisabled_; }, /** @@ -696,15 +658,6 @@ return !!this.unifiedConsentEnabled && this.syncStatus !== undefined && !this.syncStatus.disabled; }, - - /** - * @return {boolean} - * @private - */ - shouldShowUnifiedConsentToggle_: function() { - return !!this.unifiedConsentEnabled && this.syncStatus !== undefined && - !this.syncStatus.disabled && !!this.syncStatus.signedIn; - }, }); })();
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.html b/chrome/browser/resources/settings/privacy_page/personalization_options.html index f985df8..eba047b 100644 --- a/chrome/browser/resources/settings/privacy_page/personalization_options.html +++ b/chrome/browser/resources/settings/privacy_page/personalization_options.html
@@ -25,46 +25,39 @@ <settings-toggle-button hidden="[[!pageVisibility.searchPrediction]]" pref="{{prefs.search.suggest_enabled}}" label="$i18n{searchSuggestPref}" - sub-label="$i18n{searchSuggestPrefDesc}" - disabled="[[unifiedConsentGiven]]"> + sub-label="$i18n{searchSuggestPrefDesc}"> </settings-toggle-button> <settings-toggle-button hidden="[[!pageVisibility.networkPrediction]]" pref="{{prefs.net.network_prediction_options}}" label="$i18n{networkPredictionEnabled}" sub-label="$i18n{networkPredictionEnabledDesc}" - numeric-unchecked-value="[[networkPredictionEnum_.NEVER]]" - disabled="[[unifiedConsentGiven]]"> + numeric-unchecked-value="[[networkPredictionEnum_.NEVER]]"> </settings-toggle-button> <settings-toggle-button pref="{{prefs.alternate_error_pages.enabled}}" label="$i18n{linkDoctorPref}" - sub-label="$i18n{linkDoctorPrefDesc}" - disabled="[[unifiedConsentGiven]]"> + sub-label="$i18n{linkDoctorPrefDesc}"> </settings-toggle-button> <settings-toggle-button pref="{{prefs.safebrowsing.enabled}}" label="$i18n{safeBrowsingEnableProtection}" - sub-label="$i18n{safeBrowsingEnableProtectionDesc}" - disabled="[[unifiedConsentGiven]]"> + sub-label="$i18n{safeBrowsingEnableProtectionDesc}"> </settings-toggle-button> <settings-toggle-button pref="{{prefs.safebrowsing.scout_reporting_enabled}}" label="$i18n{safeBrowsingEnableExtendedReporting}" - sub-label="$i18n{safeBrowsingEnableExtendedReportingDesc}" - disabled="[[unifiedConsentGiven]]"> + sub-label="$i18n{safeBrowsingEnableExtendedReportingDesc}"> </settings-toggle-button> <if expr="_google_chrome"> <if expr="chromeos"> <settings-toggle-button pref="{{prefs.cros.metrics.reportingEnabled}}" label="$i18n{enableLogging}" - sub-label="$i18n{enableLoggingDesc}" - disabled="[[unifiedConsentGiven]]"> + sub-label="$i18n{enableLoggingDesc}"> </settings-toggle-button> </if><!-- chromeos --> <if expr="not chromeos"> <settings-toggle-button id="metricsReportingControl" pref="[[metricsReportingPref_]]" label="$i18n{enableLogging}" sub-label="$i18n{enableLoggingDesc}" no-set-pref - on-settings-boolean-control-change="onMetricsReportingChange_" - disabled="[[unifiedConsentGiven]]"> + on-settings-boolean-control-change="onMetricsReportingChange_"> <template is="dom-if" if="[[showRestart_]]" restamp> <paper-button on-click="onRestartTap_" id="restart" slot="more-actions"> @@ -78,8 +71,7 @@ <settings-toggle-button pref="{{prefs.url_keyed_anonymized_data_collection.enabled}}" label="$i18n{urlKeyedAnonymizedDataCollection}" - sub-label="$i18n{urlKeyedAnonymizedDataCollectionDesc}" - disabled="[[unifiedConsentGiven]]"> + sub-label="$i18n{urlKeyedAnonymizedDataCollectionDesc}"> </settings-toggle-button> </template> <if expr="_google_chrome"> @@ -87,7 +79,6 @@ pref="{{prefs.spellcheck.use_spelling_service}}" label="$i18n{spellingPref}" sub-label="$i18n{spellingDescription}" - disabled="[[unifiedConsentGiven]]" hidden="[[!showSpellCheckControl_(prefs.spellcheck.dictionaries)]]"> </settings-toggle-button> </if><!-- _google_chrome -->
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.js b/chrome/browser/resources/settings/privacy_page/personalization_options.js index 10b2d38..7db8150 100644 --- a/chrome/browser/resources/settings/privacy_page/personalization_options.js +++ b/chrome/browser/resources/settings/privacy_page/personalization_options.js
@@ -52,8 +52,6 @@ unifiedConsentEnabled: Boolean, - unifiedConsentGiven: Boolean, - // <if expr="_google_chrome and not chromeos"> // TODO(dbeam): make a virtual.* pref namespace and set/get this normally // (but handled differently in C++). @@ -132,9 +130,10 @@ * @private */ showSpellCheckControl_: function() { - return !!this.prefs.spellcheck && - /** @type {!Array<string>} */ - (this.prefs.spellcheck.dictionaries.value).length > 0; + return !this.unifiedConsentEnabled || + (!!this.prefs.spellcheck && + /** @type {!Array<string>} */ + (this.prefs.spellcheck.dictionaries.value).length > 0); }, }); })();
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc b/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc index 7ec4abc..3da013e 100644 --- a/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc +++ b/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/safe_browsing/certificate_reporting_service.h" #include "base/command_line.h" -#include "base/feature_list.h" #include "base/macros.h" #include "base/task/post_task.h" #include "base/test/metrics/histogram_tester.h" @@ -57,10 +56,6 @@ net::URLRequestFilter::GetInstance()->ClearHandlers(); } -bool AreCommittedInterstitialsEnabled() { - return base::FeatureList::IsEnabled(features::kSSLCommittedInterstitials); -} - } // namespace namespace safe_browsing { @@ -173,14 +168,15 @@ TabStripModel* tab_strip_model = browser()->tab_strip_model(); content::WebContents* contents = tab_strip_model->GetActiveWebContents(); ui_test_utils::NavigateToURL(browser(), kCertErrorURL); - // When committed interstitials are enabled, no interstitial attaches; once - // a navigation commits, the error page is present. - if (!AreCommittedInterstitialsEnabled()) + // When GetParam() is true, committed interstitials are enabled. In this + // case, no interstitial attaches; once a navigation commits, the error page + // is present. + if (!GetParam()) content::WaitForInterstitialAttach(contents); // Navigate away from the interstitial to trigger report upload. ui_test_utils::NavigateToURL(browser(), GURL("about:blank")); - if (!AreCommittedInterstitialsEnabled()) + if (!GetParam()) content::WaitForInterstitialDetach(contents); }
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.cc b/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.cc index c01db6f..7be2dc05 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.cc
@@ -14,6 +14,7 @@ #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h" #include "components/crx_file/id_util.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/uninstall_reason.h" @@ -53,35 +54,41 @@ using ExtensionCollection = ChromeCleanerScannerResults::ExtensionCollection; if (on_prompt_user_) { + if (base::FeatureList::IsEnabled(kChromeCleanupExtensionsFeature) && + extension_ids) { + extension_ids_ = extension_ids.value(); + } else { + extension_ids_.clear(); + } + ChromeCleanerScannerResults scanner_results( FileCollection(files_to_delete.begin(), files_to_delete.end()), registry_keys ? RegistryKeyCollection(registry_keys->begin(), registry_keys->end()) : RegistryKeyCollection(), - extension_ids - ? ExtensionCollection(extension_ids->begin(), extension_ids->end()) - : ExtensionCollection()); - if (extension_ids.has_value()) { - extension_ids_ = extension_ids; - } + extension_ids_.empty() ? ExtensionCollection() + : ExtensionCollection(extension_ids_.begin(), + extension_ids_.end())); + std::move(on_prompt_user_) .Run(std::move(scanner_results), std::move(callback)); } } +// The |extensions_ids| passed to this function are a subset of the +// |extension_ids| passed to PromptUser because the extensions are not all +// disabled at the same time. void ChromePromptImpl::DisableExtensions( const std::vector<base::string16>& extension_ids, ChromePrompt::DisableExtensionsCallback callback) { - if (extension_service_ == nullptr || !extension_ids_.has_value()) { + if (extension_service_ == nullptr || extension_ids_.empty()) { std::move(callback).Run(false); return; } // Clear the stored extension_ids by moving it onto this stack frame, // so subsequent calls will fail. - base::Optional<std::vector<base::string16>> optional_verified_extension_ids{}; - extension_ids_.swap(optional_verified_extension_ids); - std::vector<base::string16> verified_extension_ids = - optional_verified_extension_ids.value(); + std::vector<base::string16> verified_extension_ids{}; + extension_ids_.swap(verified_extension_ids); bool ids_are_valid = std::all_of( extension_ids.begin(), extension_ids.end(), [this, &verified_extension_ids](const base::string16& id) {
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.h b/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.h index 843af0c..426b7a66 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.h +++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.h
@@ -50,7 +50,7 @@ mojo::Binding<chrome_cleaner::mojom::ChromePrompt> binding_; extensions::ExtensionService* extension_service_; OnPromptUser on_prompt_user_; - base::Optional<std::vector<base::string16>> extension_ids_; + std::vector<base::string16> extension_ids_; DISALLOW_COPY_AND_ASSIGN(ChromePromptImpl); };
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_delete_extension_win_unittest.cc b/chrome/browser/safe_browsing/chrome_cleaner/srt_delete_extension_win_unittest.cc index 9252ef33..dcded8f1 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/srt_delete_extension_win_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_delete_extension_win_unittest.cc
@@ -4,13 +4,20 @@ #include "chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.h" +#include <vector> + +#include "base/feature_list.h" #include "base/location.h" +#include "base/macros.h" #include "base/sequenced_task_runner.h" +#include "base/strings/string16.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service_test_base.h" #include "chrome/browser/extensions/test_extension_service.h" +#include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h" #include "content/public/test/test_browser_thread_bundle.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/mock_extension_system.h" @@ -23,31 +30,92 @@ class ExtensionDeletionTest : public extensions::ExtensionServiceTestBase { public: - ExtensionDeletionTest() { InitializeEmptyExtensionService(); } ~ExtensionDeletionTest() override = default; - void SetUp() override {} + void SetUp() override { + const std::vector<base::Feature> enabled_features = GetEnabledFeatures(); + const std::vector<base::Feature> disabled_features = GetDisabledFeatures(); + + scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features); + + ExtensionServiceTestBase::SetUp(); + } + + protected: + // Protected constructor to make this class abstract. Following + // implementations will be explicit about the feature flag state. + ExtensionDeletionTest() { InitializeEmptyExtensionService(); } + + // Hooks to set up feature flags. + virtual const std::vector<base::Feature> GetEnabledFeatures() const { + return {}; + } + + virtual const std::vector<base::Feature> GetDisabledFeatures() const { + return {}; + } + + // Creates some extension IDs and registers them in the service. + std::vector<base::string16> PopulateExtensionIds( + bool installExtensions = true) { + std::vector<base::string16> extension_ids{}; + extensions::ExtensionService* extension_service = this->service(); + for (int i = 40; i < 43; i++) { + scoped_refptr<const extensions::Extension> extension = + extensions::ExtensionBuilder(base::NumberToString(i)) + .SetManifestKey("version", "1") + .Build(); + auto id = extension->id(); + extension_ids.push_back(base::UTF8ToUTF16(id)); + if (installExtensions) { + extension_service->AddExtension(extension.get()); + extension_service->EnableExtension(id); + } + } + + return extension_ids; + } private: + base::test::ScopedFeatureList scoped_feature_list_; DISALLOW_COPY_AND_ASSIGN(ExtensionDeletionTest); }; -TEST_F(ExtensionDeletionTest, DisableExtensionTest) { - std::vector<base::string16> extension_ids{}; - extensions::ExtensionService* extension_service = this->service(); - for (int i = 40; i < 43; i++) { - scoped_refptr<const extensions::Extension> extension = - extensions::ExtensionBuilder(base::NumberToString(i)) - .SetManifestKey("version", "1") - .Build(); - auto id = extension->id(); - extension_ids.push_back(base::UTF8ToUTF16(id)); - extension_service->AddExtension(extension.get()); - extension_service->EnableExtension(id); +class ExtensionDeletionEnabledTest : public ExtensionDeletionTest { + public: + ExtensionDeletionEnabledTest() = default; + ~ExtensionDeletionEnabledTest() override = default; + + protected: + const std::vector<base::Feature> GetEnabledFeatures() const override { + return {kChromeCleanupExtensionsFeature}; } + + private: + DISALLOW_COPY_AND_ASSIGN(ExtensionDeletionEnabledTest); +}; + +class ExtensionDeletionDisabledTest : public ExtensionDeletionTest { + public: + ExtensionDeletionDisabledTest() = default; + ~ExtensionDeletionDisabledTest() override = default; + + protected: + const std::vector<base::Feature> GetDisabledFeatures() const override { + return {kChromeCleanupExtensionsFeature}; + } + + private: + DISALLOW_COPY_AND_ASSIGN(ExtensionDeletionDisabledTest); +}; + +TEST_F(ExtensionDeletionEnabledTest, DisableExtensionTest) { + std::vector<base::string16> extension_ids = PopulateExtensionIds(); + extensions::ExtensionService* extension_service = this->service(); std::unique_ptr<ChromePromptImpl> chrome_prompt = std::make_unique<ChromePromptImpl>(extension_service, nullptr, base::DoNothing(), base::DoNothing()); + chrome_prompt->PromptUser({}, {}, extension_ids, base::DoNothing()); std::vector<base::string16> extensions_to_disable{extension_ids[0]}; chrome_prompt->DisableExtensions( @@ -81,22 +149,13 @@ nullptr); } -TEST_F(ExtensionDeletionTest, CantDeleteNonPromptedExtensions) { - std::vector<base::string16> extension_ids{}; +TEST_F(ExtensionDeletionEnabledTest, CantDeleteNonPromptedExtensions) { + std::vector<base::string16> extension_ids = PopulateExtensionIds(); extensions::ExtensionService* extension_service = this->service(); - for (int i = 40; i < 43; i++) { - scoped_refptr<const extensions::Extension> extension = - extensions::ExtensionBuilder(base::NumberToString(i)) - .SetManifestKey("version", "1") - .Build(); - auto id = extension->id(); - extension_ids.push_back(base::UTF8ToUTF16(id)); - extension_service->AddExtension(extension.get()); - extension_service->EnableExtension(id); - } std::unique_ptr<ChromePromptImpl> chrome_prompt = std::make_unique<ChromePromptImpl>(extension_service, nullptr, base::DoNothing(), base::DoNothing()); + std::vector<base::string16> extensions_to_disable{extension_ids[0]}; chrome_prompt->DisableExtensions( extensions_to_disable, @@ -140,23 +199,14 @@ nullptr); } -TEST_F(ExtensionDeletionTest, EmptyDeletionTest) { - std::vector<base::string16> extension_ids{}; +TEST_F(ExtensionDeletionEnabledTest, EmptyDeletionTest) { + std::vector<base::string16> extension_ids = PopulateExtensionIds(); extensions::ExtensionService* extension_service = this->service(); std::unique_ptr<ChromePromptImpl> chrome_prompt = std::make_unique<ChromePromptImpl>(extension_service, nullptr, base::DoNothing(), base::DoNothing()); + chrome_prompt->PromptUser({}, {}, extension_ids, base::DoNothing()); - for (int i = 40; i < 43; i++) { - scoped_refptr<const extensions::Extension> extension = - extensions::ExtensionBuilder(base::NumberToString(i)) - .SetManifestKey("version", "1") - .Build(); - auto id = extension->id(); - extension_ids.push_back(base::UTF8ToUTF16(id)); - extension_service->AddExtension(extension.get()); - extension_service->EnableExtension(id); - } chrome_prompt->DisableExtensions( {}, base::BindOnce([](bool result) { EXPECT_TRUE(result); })); EXPECT_TRUE(extension_service->IsExtensionEnabled( @@ -167,22 +217,13 @@ base::UTF16ToUTF8(extension_ids[2]))); } -TEST_F(ExtensionDeletionTest, BadlyFormattedDeletionTest) { - std::vector<base::string16> extension_ids{}; +TEST_F(ExtensionDeletionEnabledTest, BadlyFormattedDeletionTest) { + std::vector<base::string16> extension_ids = PopulateExtensionIds(); extensions::ExtensionService* extension_service = this->service(); std::unique_ptr<ChromePromptImpl> chrome_prompt = std::make_unique<ChromePromptImpl>(extension_service, nullptr, base::DoNothing(), base::DoNothing()); - for (int i = 40; i < 43; i++) { - scoped_refptr<const extensions::Extension> extension = - extensions::ExtensionBuilder(base::NumberToString(i)) - .SetManifestKey("version", "1") - .Build(); - auto id = extension->id(); - extension_ids.push_back(base::UTF8ToUTF16(id)); - extension_service->AddExtension(extension.get()); - extension_service->EnableExtension(id); - } + chrome_prompt->DisableExtensions( {L"bad-extension-id"}, base::BindOnce([](bool result) { EXPECT_FALSE(result); })); @@ -193,23 +234,41 @@ base::BindOnce([](bool result) { EXPECT_FALSE(result); })); } -TEST_F(ExtensionDeletionTest, NotInstalledExtensionTest) { - std::vector<base::string16> extension_ids{}; +TEST_F(ExtensionDeletionEnabledTest, NotInstalledExtensionTest) { + // Don't actually install the extension + std::vector<base::string16> extension_ids = PopulateExtensionIds(false); extensions::ExtensionService* extension_service = this->service(); std::unique_ptr<ChromePromptImpl> chrome_prompt = std::make_unique<ChromePromptImpl>(extension_service, nullptr, base::DoNothing(), base::DoNothing()); - for (int i = 40; i < 43; i++) { - // Don't actually install the extension - scoped_refptr<const extensions::Extension> extension = - extensions::ExtensionBuilder(base::NumberToString(i)) - .SetManifestKey("version", "1") - .Build(); - auto id = extension->id(); - extension_ids.push_back(base::UTF8ToUTF16(id)); - } + chrome_prompt->DisableExtensions( extension_ids, base::BindOnce([](bool result) { EXPECT_FALSE(result); })); } +TEST_F(ExtensionDeletionDisabledTest, CannotDisableExtensionTest) { + std::vector<base::string16> extension_ids = PopulateExtensionIds(); + extensions::ExtensionService* extension_service = this->service(); + + std::unique_ptr<ChromePromptImpl> chrome_prompt = + std::make_unique<ChromePromptImpl>(extension_service, nullptr, + base::DoNothing(), base::DoNothing()); + chrome_prompt->PromptUser({}, {}, extension_ids, base::DoNothing()); + std::vector<base::string16> extensions_to_disable{extension_ids[0]}; + chrome_prompt->DisableExtensions( + extensions_to_disable, + base::BindOnce([](bool result) { EXPECT_FALSE(result); })); + + // Even if we called disable, the extension doesn't get disabled. + EXPECT_NE(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[0])), + nullptr); + EXPECT_NE(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[1])), + nullptr); + EXPECT_NE(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[2])), + nullptr); +} + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc index 658dd86a..6918ee6 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc
@@ -47,6 +47,9 @@ const base::Feature kChromeCleanupQuarantineFeature{ "ChromeCleanupQuarantine", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kChromeCleanupExtensionsFeature{ + "ChromeCleanupExtensions", base::FEATURE_DISABLED_BY_DEFAULT}; + bool IsInSRTPromptFieldTrialGroups() { return !base::StartsWith(base::FieldTrialList::FindFullName(kSRTPromptTrial), kSRTPromptOffGroup, base::CompareCase::SENSITIVE);
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h index 372f60b..5ae4111 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h +++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h
@@ -74,6 +74,10 @@ // files. extern const base::Feature kChromeCleanupQuarantineFeature; +// Extensions cleanup feature. When enabled, Chrome Cleaner will prompt users +// for, and cleanup, bad extensions. +extern const base::Feature kChromeCleanupExtensionsFeature; + extern const char kSRTPromptTrial[]; // Returns true if this Chrome is in a field trial group which shows the SRT
diff --git a/chrome/browser/signin/about_signin_internals_factory.cc b/chrome/browser/signin/about_signin_internals_factory.cc index 06047d9..d151549b 100644 --- a/chrome/browser/signin/about_signin_internals_factory.cc +++ b/chrome/browser/signin/about_signin_internals_factory.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/chrome_signin_client_factory.h" #include "chrome/browser/signin/gaia_cookie_manager_service_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_error_controller_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" @@ -54,6 +55,7 @@ AboutSigninInternals* service = new AboutSigninInternals( ProfileOAuth2TokenServiceFactory::GetForProfile(profile), AccountTrackerServiceFactory::GetForProfile(profile), + IdentityManagerFactory::GetForProfile(profile), SigninManagerFactory::GetForProfile(profile), SigninErrorControllerFactory::GetForProfile(profile), GaiaCookieManagerServiceFactory::GetForProfile(profile),
diff --git a/chrome/browser/signin/dice_response_handler_unittest.cc b/chrome/browser/signin/dice_response_handler_unittest.cc index dcf9d81..08011bd 100644 --- a/chrome/browser/signin/dice_response_handler_unittest.cc +++ b/chrome/browser/signin/dice_response_handler_unittest.cc
@@ -139,6 +139,7 @@ &cookie_service_), about_signin_internals_(&token_service_, &account_tracker_service_, + identity_test_env_.identity_manager(), &signin_manager_, &signin_error_controller_, &cookie_service_,
diff --git a/chrome/browser/signin/identity_test_environment_profile_adaptor.cc b/chrome/browser/signin/identity_test_environment_profile_adaptor.cc index 07f8c4c0..e4a3093 100644 --- a/chrome/browser/signin/identity_test_environment_profile_adaptor.cc +++ b/chrome/browser/signin/identity_test_environment_profile_adaptor.cc
@@ -36,17 +36,13 @@ // static std::unique_ptr<TestingProfile> IdentityTestEnvironmentProfileAdaptor::CreateProfileForIdentityTestEnvironment( - const TestingProfile::TestingFactories& input_factories, - std::unique_ptr<sync_preferences::PrefServiceSyncable> prefs) { + const TestingProfile::TestingFactories& input_factories) { TestingProfile::Builder builder; for (auto& input_factory : input_factories) { builder.AddTestingFactory(input_factory.first, input_factory.second); } - if (prefs) - builder.SetPrefService(std::move(prefs)); - return CreateProfileForIdentityTestEnvironment(builder); }
diff --git a/chrome/browser/signin/identity_test_environment_profile_adaptor.h b/chrome/browser/signin/identity_test_environment_profile_adaptor.h index 59d10e9..3daee2e 100644 --- a/chrome/browser/signin/identity_test_environment_profile_adaptor.h +++ b/chrome/browser/signin/identity_test_environment_profile_adaptor.h
@@ -25,14 +25,14 @@ CreateProfileForIdentityTestEnvironment(); // Like the above, but additionally configures the returned Profile with - // |input_factories| and |prefs|. + // |input_factories|. static std::unique_ptr<TestingProfile> CreateProfileForIdentityTestEnvironment( - const TestingProfile::TestingFactories& input_factories, - std::unique_ptr<sync_preferences::PrefServiceSyncable> prefs = nullptr); + const TestingProfile::TestingFactories& input_factories); // Creates and returns a TestingProfile that has been configured with the - // given |builder|. + // given |builder| and the set of testing factories that + // IdentityTestEnvironment requires. static std::unique_ptr<TestingProfile> CreateProfileForIdentityTestEnvironment(TestingProfile::Builder& builder);
diff --git a/chrome/browser/speech/tts_platform_fuzzer.cc b/chrome/browser/speech/tts_platform_fuzzer.cc index 04ed8b7..6aefc3c4 100644 --- a/chrome/browser/speech/tts_platform_fuzzer.cc +++ b/chrome/browser/speech/tts_platform_fuzzer.cc
@@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <objbase.h> + +#include "build/build_config.h" #include "chrome/browser/speech/tts_platform.h" // Entry point for LibFuzzer. @@ -15,6 +18,14 @@ params.rate = 1.0; params.volume = 0.1; +#if defined(OS_WIN) + static bool initialized = false; + if (!initialized) { + initialized = true; + CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + } +#endif + // First byte gives us the utterance ID. size_t i = 0; if (i < size)
diff --git a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc index df71275..b9a6a5b 100644 --- a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc +++ b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
@@ -2232,6 +2232,13 @@ // TODO(estark): add console messages for the |kMarkHttpAsParameterWarning| // configuration of |kMarkHttpAsFeature| and update this test accordingly. // https://crbug.com/802921 +#if defined(OS_WIN) +#define MAYBE_ConsoleMessageNotPrintedForAbortedNavigation \ + DISABLED_ConsoleMessageNotPrintedForAbortedNavigation +#else +#define MAYBE_ConsoleMessageNotPrintedForAbortedNavigation \ + ConsoleMessageNotPrintedForAbortedNavigation +#endif IN_PROC_BROWSER_TEST_P(SecurityStateTabHelperIncognitoTest, ConsoleMessageNotPrintedForAbortedNavigation) { base::test::ScopedFeatureList scoped_feature_list;
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc index 6ae3eb4..128c751 100644 --- a/chrome/browser/ssl/ssl_browsertest.cc +++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -1034,7 +1034,7 @@ } SSLBlockingPage* GetSSLBlockingPage(WebContents* tab) override { - if (AreCommittedInterstitialsEnabled()) { + if (IsCommittedInterstitialTest()) { security_interstitials::SecurityInterstitialTabHelper* helper = security_interstitials::SecurityInterstitialTabHelper:: FromWebContents(tab); @@ -1048,7 +1048,7 @@ } BadClockBlockingPage* GetBadClockBlockingPage(WebContents* tab) override { - if (AreCommittedInterstitialsEnabled()) { + if (IsCommittedInterstitialTest()) { security_interstitials::SecurityInterstitialTabHelper* helper = security_interstitials::SecurityInterstitialTabHelper:: FromWebContents(tab); @@ -1064,7 +1064,7 @@ bool IsCommittedInterstitialTest() const { return GetParam(); } void DontProceedThroughInterstitial(WebContents* tab) override { - if (AreCommittedInterstitialsEnabled()) { + if (IsCommittedInterstitialTest()) { content::TestNavigationObserver nav_observer(tab, 1); SendInterstitialCommand(tab, security_interstitials::CMD_DONT_PROCEED); nav_observer.Wait(); @@ -1076,7 +1076,7 @@ void SendInterstitialCommand( WebContents* tab, security_interstitials::SecurityInterstitialCommand command) override { - if (AreCommittedInterstitialsEnabled()) { + if (IsCommittedInterstitialTest()) { std::string javascript; switch (command) { case security_interstitials::CMD_DONT_PROCEED: { @@ -1754,7 +1754,7 @@ chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB); content::WaitForLoadStop(tab); - if (!AreCommittedInterstitialsEnabled()) { + if (!IsCommittedInterstitialTest()) { // Make sure we haven't changed the previous RFH. Prevents regression of // http://crbug.com/82667. This is only applicable to pre-committed // interstitials. With committed interstitials, the interstitial is a @@ -1788,7 +1788,7 @@ // committed interstitials enabled, this triggers a navigation. content::TestNavigationObserver nav_observer(tab); tab->GetController().GoToOffset(-1); - if (AreCommittedInterstitialsEnabled()) + if (IsCommittedInterstitialTest()) nav_observer.Wait(); // We should be back at the original good page. @@ -1813,7 +1813,7 @@ CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); - if (AreCommittedInterstitialsEnabled()) { + if (IsCommittedInterstitialTest()) { content::WindowedNotificationObserver observer( content::NOTIFICATION_LOAD_STOP, content::Source<NavigationController>(&tab->GetController())); @@ -1833,8 +1833,6 @@ // interstitials wipe out forward history like other committed navigations and // committed error pages. IN_PROC_BROWSER_TEST_F(SSLUITestBase, TestHTTPSExpiredCertAndGoForward) { - if (AreCommittedInterstitialsEnabled()) - return; ASSERT_TRUE(embedded_test_server()->Start()); ASSERT_TRUE(https_server_expired_.Start()); @@ -3284,13 +3282,13 @@ Browser* popup_browser = chrome::FindBrowserWithProfile(browser()->profile()); WebContents* popup = popup_browser->tab_strip_model()->GetActiveWebContents(); EXPECT_NE(popup, tab1); - if (AreCommittedInterstitialsEnabled()) + if (IsCommittedInterstitialTest()) nav_observer.Wait(); WaitForInterstitial(popup); // Since the popup is showing an interstitial, it shouldn't have a last // committed entry (except when committed interstitials are enabled, in which // case an interstitial is a committed entry). - if (!AreCommittedInterstitialsEnabled()) { + if (!IsCommittedInterstitialTest()) { EXPECT_FALSE(popup->GetController().GetLastCommittedEntry()); } ASSERT_TRUE(popup->GetController().GetVisibleEntry()); @@ -7394,7 +7392,7 @@ // Checks that SimpleURLLoader, which uses services/network/url_loader.cc, goes // through the new NetworkServiceClient interface to deliver cert error // notifications to the browser which then overrides the certificate error. -IN_PROC_BROWSER_TEST_P(SSLUITest, SimpleURLLoaderCertError) { +IN_PROC_BROWSER_TEST_F(SSLUITestBase, SimpleURLLoaderCertError) { WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); ASSERT_NO_FATAL_FAILURE(SetUpUnsafeContentsWithUserException( "/ssl/page_with_unsafe_contents.html")); @@ -8069,7 +8067,7 @@ // Proceed through the interstitial and observe that the histogram is // recorded correctly. content::TestNavigationObserver nav_observer(tab, 1); - if (AreCommittedInterstitialsEnabled()) { + if (IsCommittedInterstitialTest()) { ASSERT_TRUE(content::ExecuteScript( tab, "window.certificateErrorPageController.proceed();")); } else {
diff --git a/chrome/browser/sync/sessions/sync_sessions_web_contents_router_unittest.cc b/chrome/browser/sync/sessions/sync_sessions_web_contents_router_unittest.cc index 64d8058..db7e27c 100644 --- a/chrome/browser/sync/sessions/sync_sessions_web_contents_router_unittest.cc +++ b/chrome/browser/sync/sessions/sync_sessions_web_contents_router_unittest.cc
@@ -7,10 +7,8 @@ #include "build/build_config.h" #include "chrome/browser/sync/sessions/sync_sessions_web_contents_router_factory.h" #include "chrome/browser/ui/sync/browser_synced_tab_delegate.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "content/public/test/web_contents_tester.h" -#include "testing/gtest/include/gtest/gtest.h" namespace sync_sessions { @@ -27,26 +25,25 @@ bool was_run_ = false; }; -class SyncSessionsWebContentsRouterTest : public testing::Test { +class SyncSessionsWebContentsRouterTest + : public ChromeRenderViewHostTestHarness { protected: - ~SyncSessionsWebContentsRouterTest() override {} + SyncSessionsWebContentsRouterTest() = default; + ~SyncSessionsWebContentsRouterTest() override = default; void SetUp() override { + ChromeRenderViewHostTestHarness::SetUp(); router_ = SyncSessionsWebContentsRouterFactory::GetInstance()->GetForProfile( - &profile_); - test_contents_ = - content::WebContentsTester::CreateTestWebContents(&profile_, nullptr); + profile()); } SyncSessionsWebContentsRouter* router() { return router_; } - content::WebContents* test_contents() { return test_contents_.get(); } private: - content::TestBrowserThreadBundle thread_bundle_; - TestingProfile profile_; SyncSessionsWebContentsRouter* router_; - std::unique_ptr<content::WebContents> test_contents_; + + DISALLOW_COPY_AND_ASSIGN(SyncSessionsWebContentsRouterTest); }; // Disabled on android due to complexity of creating a full TabAndroid object @@ -59,25 +56,25 @@ base::Bind(&StartSyncFlareMock::StartSyncFlare, base::Unretained(&mock))); // There's no delegate for the tab, so the flare shouldn't run. - router()->NotifyTabModified(test_contents(), false); + router()->NotifyTabModified(web_contents(), false); EXPECT_FALSE(mock.was_run()); - BrowserSyncedTabDelegate::CreateForWebContents(test_contents()); + BrowserSyncedTabDelegate::CreateForWebContents(web_contents()); // There's a delegate for the tab, but it's not a load completed event, so the // flare still shouldn't run. - router()->NotifyTabModified(test_contents(), false); + router()->NotifyTabModified(web_contents(), false); EXPECT_FALSE(mock.was_run()); } // Make sure we don't crash when there's not a flare. TEST_F(SyncSessionsWebContentsRouterTest, FlareNotSet) { - BrowserSyncedTabDelegate::CreateForWebContents(test_contents()); - router()->NotifyTabModified(test_contents(), false); + BrowserSyncedTabDelegate::CreateForWebContents(web_contents()); + router()->NotifyTabModified(web_contents(), false); } TEST_F(SyncSessionsWebContentsRouterTest, FlareRunsForLoadCompleted) { - BrowserSyncedTabDelegate::CreateForWebContents(test_contents()); + BrowserSyncedTabDelegate::CreateForWebContents(web_contents()); StartSyncFlareMock mock; router()->InjectStartSyncFlare( @@ -85,7 +82,7 @@ // There's a delegate for the tab, and it's a load completed event, so the // flare should run. - router()->NotifyTabModified(test_contents(), true); + router()->NotifyTabModified(web_contents(), true); EXPECT_TRUE(mock.was_run()); } #endif // !defined(OS_ANDROID)
diff --git a/chrome/browser/sync/test/integration/enable_disable_test.cc b/chrome/browser/sync/test/integration/enable_disable_test.cc index cfa57460..c90e05a0 100644 --- a/chrome/browser/sync/test/integration/enable_disable_test.cc +++ b/chrome/browser/sync/test/integration/enable_disable_test.cc
@@ -18,7 +18,6 @@ #include "components/sync/driver/sync_driver_switches.h" #include "components/sync/test/fake_server/bookmark_entity_builder.h" #include "components/sync/test/fake_server/entity_builder_factory.h" -#include "components/unified_consent/feature.h" using base::FeatureList; using syncer::ModelType;
diff --git a/chrome/browser/sync/test/integration/profile_sync_service_harness.cc b/chrome/browser/sync/test/integration/profile_sync_service_harness.cc index 4299c88..13a40b9 100644 --- a/chrome/browser/sync/test/integration/profile_sync_service_harness.cc +++ b/chrome/browser/sync/test/integration/profile_sync_service_harness.cc
@@ -21,12 +21,9 @@ #include "chrome/browser/ui/webui/signin/login_ui_service.h" #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" #include "chrome/browser/ui/webui/signin/login_ui_test_utils.h" -#include "chrome/browser/unified_consent/unified_consent_service_factory.h" #include "chrome/common/channel_info.h" #include "components/sync/driver/about_sync_util.h" #include "components/sync/engine/sync_string_conversions.h" -#include "components/unified_consent/feature.h" -#include "components/unified_consent/unified_consent_service.h" #include "services/identity/public/cpp/identity_manager.h" #include "services/identity/public/cpp/identity_test_utils.h" @@ -264,19 +261,8 @@ // Choose the datatypes to be synced. If all datatypes are to be synced, // set sync_everything to true; otherwise, set it to false. bool sync_everything = (synced_datatypes == syncer::UserSelectableTypes()); - if (unified_consent::IsUnifiedConsentFeatureEnabled()) { - // When unified consent given is set to |true|, the unified consent service - // enables syncing all datatypes. - UnifiedConsentServiceFactory::GetForProfile(profile_) - ->SetUnifiedConsentGiven(sync_everything); - if (!sync_everything) { - service()->GetUserSettings()->SetChosenDataTypes(sync_everything, - synced_datatypes); - } - } else { - service()->GetUserSettings()->SetChosenDataTypes(sync_everything, - synced_datatypes); - } + service()->GetUserSettings()->SetChosenDataTypes(sync_everything, + synced_datatypes); if (encryption_passphrase.has_value()) { service()->GetUserSettings()->SetEncryptionPassphrase( @@ -525,12 +511,6 @@ return true; } - // Disable unified consent first as otherwise disabling sync is not possible. - if (unified_consent::IsUnifiedConsentFeatureEnabled()) { - UnifiedConsentServiceFactory::GetForProfile(profile_) - ->SetUnifiedConsentGiven(false); - } - synced_datatypes.RetainAll(syncer::UserSelectableTypes()); synced_datatypes.Remove(datatype); service()->GetUserSettings()->SetChosenDataTypes(false, synced_datatypes); @@ -560,14 +540,9 @@ return false; } - if (unified_consent::IsUnifiedConsentFeatureEnabled()) { - // Setting unified consent given to true will enable all sync data types. - UnifiedConsentServiceFactory::GetForProfile(profile_) - ->SetUnifiedConsentGiven(true); - } else { - service()->GetUserSettings()->SetChosenDataTypes( - true, syncer::UserSelectableTypes()); - } + service()->GetUserSettings()->SetChosenDataTypes( + true, syncer::UserSelectableTypes()); + if (AwaitSyncSetupCompletion(/*skip_passphrase_verification=*/false)) { DVLOG(1) << "EnableSyncForAllDatatypes(): Enabled sync for all datatypes " << "on " << profile_debug_name_ << ".";
diff --git a/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc b/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc index 47f1be8..38410a3 100644 --- a/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc
@@ -8,7 +8,6 @@ #include "base/macros.h" #include "base/strings/stringprintf.h" #include "base/test/metrics/histogram_tester.h" -#include "build/build_config.h" #include "chrome/browser/sync/test/integration/feature_toggler.h" #include "chrome/browser/sync/test/integration/preferences_helper.h" #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" @@ -140,17 +139,8 @@ ASSERT_TRUE(ListPrefMatchChecker(prefs::kURLsToRestoreOnStartup).Wait()); } -// Disabled due to flakiness on Chrome OS: https://crbug.com/873902. -#if defined(OS_CHROMEOS) -#define MAYBE_SingleClientEnabledEncryptionBothChanged \ - DISABLED_SingleClientEnabledEncryptionBothChanged -#else -#define MAYBE_SingleClientEnabledEncryptionBothChanged \ - SingleClientEnabledEncryptionBothChanged -#endif -IN_PROC_BROWSER_TEST_P( - TwoClientPreferencesSyncTest, - E2E_ENABLED(MAYBE_SingleClientEnabledEncryptionBothChanged)) { +IN_PROC_BROWSER_TEST_P(TwoClientPreferencesSyncTest, + E2E_ENABLED(SingleClientEnabledEncryptionBothChanged)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(BooleanPrefMatchChecker(prefs::kHomePageIsNewTabPage).Wait()); ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait());
diff --git a/chrome/browser/themes/theme_syncable_service_unittest.cc b/chrome/browser/themes/theme_syncable_service_unittest.cc index d5f5535..cdf96a5a 100644 --- a/chrome/browser/themes/theme_syncable_service_unittest.cc +++ b/chrome/browser/themes/theme_syncable_service_unittest.cc
@@ -456,7 +456,7 @@ syncer::SyncChangeList change_list; change_list.push_back(syncer::SyncChange( FROM_HERE, syncer::SyncChange::ACTION_UPDATE, - syncer::SyncData::CreateRemoteData(1, entity_specifics, base::Time()))); + syncer::SyncData::CreateRemoteData(1, entity_specifics))); error = theme_sync_service_->ProcessSyncChanges(FROM_HERE, change_list); EXPECT_FALSE(error.IsSet()) << error.message(); EXPECT_EQ(fake_theme_service_->theme_extension(), theme_extension_.get());
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index e830eb6..71c7676 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1817,6 +1817,8 @@ "user_manager.h", "views/external_protocol_dialog.cc", "views/external_protocol_dialog.h", + "views/message_center/popups_only_ui_delegate.cc", + "views/message_center/popups_only_ui_delegate.h", "views/profiles/badged_profile_photo.cc", "views/profiles/badged_profile_photo.h", "views/profiles/dice_accounts_menu.cc", @@ -2027,8 +2029,6 @@ "cocoa/media_picker/desktop_media_picker_item.mm", "cocoa/native_window_tracker_cocoa.h", "cocoa/native_window_tracker_cocoa.mm", - "cocoa/notifications/message_center_bridge.h", - "cocoa/notifications/message_center_bridge.mm", "cocoa/nsmenuitem_additions.h", "cocoa/nsmenuitem_additions.mm", "cocoa/profiles/profile_menu_controller.h", @@ -3035,8 +3035,6 @@ "views/frame/browser_non_client_frame_view_factory_views.cc", "views/frame/desktop_browser_frame_aura.cc", "views/frame/desktop_browser_frame_aura.h", - "views/message_center/popups_only_ui_delegate.cc", - "views/message_center/popups_only_ui_delegate.h", ] } }
diff --git a/chrome/browser/ui/android/infobars/app_banner_infobar_android.cc b/chrome/browser/ui/android/infobars/app_banner_infobar_android.cc index 8aac8f60..d0bb984 100644 --- a/chrome/browser/ui/android/infobars/app_banner_infobar_android.cc +++ b/chrome/browser/ui/android/infobars/app_banner_infobar_android.cc
@@ -54,12 +54,6 @@ return infobar; } -void AppBannerInfoBarAndroid::OnInstallStateChanged(int new_state) { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_AppBannerInfoBarAndroid_onInstallStateChanged(env, java_infobar_, - new_state); -} - banners::AppBannerInfoBarDelegateAndroid* AppBannerInfoBarAndroid::GetDelegate() { return static_cast<banners::AppBannerInfoBarDelegateAndroid*>(delegate());
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc index 68e3227e..94c2b59 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc +++ b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
@@ -117,7 +117,7 @@ app_list->set_item_pin_ordinal(item_pin_ordinal); return syncer::SyncData::CreateRemoteData(std::hash<std::string>{}(id), - specifics, base::Time()); + specifics); } syncer::SyncDataList CreateBadAppRemoteData(const std::string& id) {
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc index d511c63..ab75458 100644 --- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc +++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
@@ -18,7 +18,9 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/night_light/night_light_client.h" +#include "chrome/browser/chromeos/policy/display_resolution_handler.h" #include "chrome/browser/chromeos/policy/display_rotation_default_handler.h" +#include "chrome/browser/chromeos/policy/display_settings_handler.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/signin_error_notifier_factory_ash.h" @@ -252,10 +254,15 @@ login_screen_client_ = std::make_unique<LoginScreenClient>(); media_client_ = std::make_unique<MediaClient>(); - // Instantiate DisplayRotationDefaultHandler after CrosSettings has been + // Instantiate DisplaySettingsHandler after CrosSettings has been // initialized. - display_rotation_handler_ = - std::make_unique<policy::DisplayRotationDefaultHandler>(); + display_settings_handler_ = + std::make_unique<policy::DisplaySettingsHandler>(); + display_settings_handler_->RegisterHandler( + std::make_unique<policy::DisplayResolutionHandler>()); + display_settings_handler_->RegisterHandler( + std::make_unique<policy::DisplayRotationDefaultHandler>()); + display_settings_handler_->Start(); // Do not create a NetworkPortalNotificationController for tests since the // NetworkPortalDetector instance may be replaced. @@ -304,7 +311,7 @@ // Initialized in PostProfileInit: network_portal_notification_controller_.reset(); - display_rotation_handler_.reset(); + display_settings_handler_.reset(); media_client_.reset(); login_screen_client_.reset(); cast_config_client_media_router_.reset();
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h index e308304e..2ff85ee 100644 --- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h +++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h
@@ -20,7 +20,7 @@ } namespace policy { -class DisplayRotationDefaultHandler; +class DisplaySettingsHandler; } namespace ui { @@ -120,8 +120,7 @@ std::unique_ptr<CastConfigClientMediaRouter> cast_config_client_media_router_; std::unique_ptr<LoginScreenClient> login_screen_client_; std::unique_ptr<MediaClient> media_client_; - std::unique_ptr<policy::DisplayRotationDefaultHandler> - display_rotation_handler_; + std::unique_ptr<policy::DisplaySettingsHandler> display_settings_handler_; // Initialized in PostBrowserStart in all configs: std::unique_ptr<DataPromoNotification> data_promo_notification_;
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc index efe84d3..ba8a143 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -702,8 +702,7 @@ sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference(); pref_one->set_name(prefs::kPinnedLauncherApps); pref_one->set_value(serialized); - init_sync_list.push_back( - syncer::SyncData::CreateRemoteData(1, one, base::Time())); + init_sync_list.push_back(syncer::SyncData::CreateRemoteData(1, one)); StartPrefSyncService(init_sync_list); }
diff --git a/chrome/browser/ui/ash/system_tray_client.cc b/chrome/browser/ui/ash/system_tray_client.cc index a035cfc..d4d569f6 100644 --- a/chrome/browser/ui/ash/system_tray_client.cc +++ b/chrome/browser/ui/ash/system_tray_client.cc
@@ -6,7 +6,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/public/interfaces/constants.mojom.h" -#include "ash/shell.h" +#include "ash/shell.h" // mash-ok #include "base/command_line.h" #include "base/logging.h" #include "base/memory/weak_ptr.h"
diff --git a/chrome/browser/ui/autofill/autofill_popup_layout_model.cc b/chrome/browser/ui/autofill/autofill_popup_layout_model.cc index 0261909..b9e125ad 100644 --- a/chrome/browser/ui/autofill/autofill_popup_layout_model.cc +++ b/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
@@ -181,6 +181,7 @@ case POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY: case POPUP_ITEM_ID_GENERATE_PASSWORD_ENTRY: case POPUP_ITEM_ID_GOOGLE_PAY_BRANDING: + case POPUP_ITEM_ID_SHOW_ACCOUNT_CARDS: return normal_font_list_; case POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY: case POPUP_ITEM_ID_DATALIST_ENTRY:
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index 5373afb..dd5b013 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -30,6 +30,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/page_info/page_info_dialog.h" +#include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/vr/vr_tab_helper.h" #include "chrome/browser/web_data_service_factory.h" @@ -526,9 +527,8 @@ void ChromeAutofillClient::ExecuteCommand(int id) { if (id == autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY) { #if !defined(OS_ANDROID) - chrome::ShowSettingsSubPage( - chrome::FindBrowserWithWebContents(web_contents()), - chrome::kPasswordManagerSubPage); + NavigateToManagePasswordsPage( + chrome::FindBrowserWithWebContents(web_contents())); #else chrome::android::PreferencesLauncher::ShowPasswordSettings(web_contents()); #endif
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index a54d66f4..4a39fe8 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -326,6 +326,15 @@ bool user_gesture) : type(type), profile(profile), user_gesture(user_gesture) {} +Browser::CreateParams::CreateParams(Type type, + Profile* profile, + bool user_gesture, + bool in_tab_dragging) + : type(type), + profile(profile), + user_gesture(user_gesture), + in_tab_dragging(in_tab_dragging) {} + Browser::CreateParams::CreateParams(const CreateParams& other) = default; // static @@ -490,6 +499,11 @@ new ExclusiveAccessManager(window_->GetExclusiveAccessContext())); BrowserList::AddBrowser(this); + + // SetIsInTabDragging() will set the fast resize bit for the web contents. + // It will be reset after the drag ends. + if (params.in_tab_dragging) + SetIsInTabDragging(true); } Browser::~Browser() { @@ -752,6 +766,10 @@ return unload_controller_->RunUnloadEventsHelper(web_contents); } +void Browser::SetIsInTabDragging(bool is_in_tab_dragging) { + window_->TabDraggingStatusChanged(is_in_tab_dragging); +} + void Browser::OnWindowClosing() { if (!ShouldCloseWindow()) return;
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 30324c9..c5dc61d 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -161,6 +161,10 @@ struct CreateParams { explicit CreateParams(Profile* profile, bool user_gesture); CreateParams(Type type, Profile* profile, bool user_gesture); + CreateParams(Type type, + Profile* profile, + bool user_gesture, + bool in_tab_dragging); CreateParams(const CreateParams& other); static CreateParams CreateForApp(const std::string& app_name, @@ -196,6 +200,9 @@ // programmatically created. bool user_gesture; + // Whether this browser was created specifically for dragged tab(s). + bool in_tab_dragging = false; + // Supply a custom BrowserWindow implementation, to be used instead of the // default. Intended for testing. BrowserWindow* window = nullptr; @@ -523,6 +530,11 @@ bool ShouldRunUnloadListenerBeforeClosing(content::WebContents* web_contents); bool RunUnloadListenerBeforeClosing(content::WebContents* web_contents); + // Set if the browser is currently participating in a tab dragging process. + // This information is used to decide if fast resize will be used during + // dragging. + void SetIsInTabDragging(bool is_in_tab_dragging); + private: friend class BrowserTest; friend class FullscreenControllerInteractiveTest;
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index 3c5634e9..556d378 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h
@@ -260,6 +260,9 @@ // Called from toolbar subviews during their show/hide animations. virtual void ToolbarSizeChanged(bool is_animating) = 0; + // Called when the accociated window's tab dragging status changed. + virtual void TabDraggingStatusChanged(bool is_dragging) = 0; + // Focuses the app menu like it was a menu bar. // // Not used on the Mac, which has a "normal" menu bar.
diff --git a/chrome/browser/ui/cocoa/notifications/message_center_bridge.h b/chrome/browser/ui/cocoa/notifications/message_center_bridge.h deleted file mode 100644 index cee2e03e..0000000 --- a/chrome/browser/ui/cocoa/notifications/message_center_bridge.h +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright (c) 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 CHROME_BROWSER_UI_COCOA_NOTIFICATIONS_MESSAGE_CENTER_BRIDGE_H_ -#define CHROME_BROWSER_UI_COCOA_NOTIFICATIONS_MESSAGE_CENTER_BRIDGE_H_ - -#import <AppKit/AppKit.h> - -#include <memory> - -#include "base/mac/scoped_nsobject.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/notifications/popups_only_ui_controller.h" -#include "components/prefs/pref_member.h" -#include "ui/message_center/message_center.h" - -@class MCPopupCollection; - -namespace message_center { -class MessageCenter; -} // namespace message_center - -// MessageCenterBridge is the owner of all the Cocoa UI objects for the -// message_center. It bridges C++ notifications from the PoupsOnlyUiController -// to the various UI objects. -class MessageCenterBridge : public PopupsOnlyUiController::Delegate { - public: - explicit MessageCenterBridge(message_center::MessageCenter* message_center); - ~MessageCenterBridge() override; - - // PopupsUiController::Delegate: - void ShowPopups() override; - void HidePopups() override; - - private: - friend class MessageCenterBridgeTest; - - // The global, singleton message center model object. Weak. - message_center::MessageCenter* const message_center_; - - // Obj-C controller for the on-screen popup notifications. - base::scoped_nsobject<MCPopupCollection> popup_collection_; - - DISALLOW_COPY_AND_ASSIGN(MessageCenterBridge); -}; - -#endif // CHROME_BROWSER_UI_COCOA_NOTIFICATIONS_MESSAGE_CENTER_BRIDGE_H_
diff --git a/chrome/browser/ui/cocoa/notifications/message_center_bridge.mm b/chrome/browser/ui/cocoa/notifications/message_center_bridge.mm deleted file mode 100644 index 5a659f0e..0000000 --- a/chrome/browser/ui/cocoa/notifications/message_center_bridge.mm +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright (c) 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 "chrome/browser/ui/cocoa/notifications/message_center_bridge.h" - -#include "base/bind.h" -#include "base/i18n/number_formatting.h" -#include "chrome/common/pref_names.h" -#include "components/prefs/pref_service.h" -#import "ui/message_center/cocoa/popup_collection.h" -#include "ui/message_center/message_center.h" - -// static -std::unique_ptr<PopupsOnlyUiController::Delegate> -PopupsOnlyUiController::CreateDelegate() { - return std::make_unique<MessageCenterBridge>( - message_center::MessageCenter::Get()); -} - -MessageCenterBridge::MessageCenterBridge( - message_center::MessageCenter* message_center) - : message_center_(message_center) {} - -MessageCenterBridge::~MessageCenterBridge() {} - -void MessageCenterBridge::ShowPopups() { - popup_collection_.reset( - [[MCPopupCollection alloc] initWithMessageCenter:message_center_]); -} - -void MessageCenterBridge::HidePopups() { - popup_collection_.reset(); -}
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index 45e95d9..e3ac112 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -77,6 +77,37 @@ namespace { +// Returns a boolean indicating whether the setting should be managed by the +// user (i.e. it is not controlled by policy). Also takes a (nullable) out-param +// which is populated by the actual setting for the given URL. +bool GetSettingManagedByUser(const GURL& url, + ContentSettingsType type, + Profile* profile, + ContentSetting* out_setting) { + HostContentSettingsMap* map = + HostContentSettingsMapFactory::GetForProfile(profile); + SettingSource source; + ContentSetting setting; + if (type == CONTENT_SETTINGS_TYPE_COOKIES) { + CookieSettingsFactory::GetForProfile(profile)->GetCookieSetting( + url, url, &source, &setting); + } else { + SettingInfo info; + std::unique_ptr<base::Value> value = + map->GetWebsiteSetting(url, url, type, std::string(), &info); + setting = content_settings::ValueToContentSetting(value.get()); + source = info.source; + } + + if (out_setting) + *out_setting = setting; + + // Prevent creation of content settings for illegal urls like about:blank by + // disallowing user management. + return source == SETTING_SOURCE_USER && + map->CanSetNarrowestContentSetting(url, url, type); +} + ContentSettingBubbleModel::ListItem CreateUrlListItem(int32_t id, const GURL& url) { // Empty URLs should get a placeholder. @@ -665,26 +696,25 @@ web_contents, profile, CONTENT_SETTINGS_TYPE_PLUGINS) { - SettingInfo info; + const GURL& url = web_contents->GetURL(); + bool managed_by_user = + GetSettingManagedByUser(url, content_type(), profile, nullptr); HostContentSettingsMap* map = HostContentSettingsMapFactory::GetForProfile(profile); - GURL url = web_contents->GetURL(); - std::unique_ptr<base::Value> value = - map->GetWebsiteSetting(url, url, content_type(), std::string(), &info); ContentSetting setting = PluginUtils::GetFlashPluginContentSetting( map, url::Origin::Create(url), url, nullptr); // If the setting is not managed by the user, hide the "Manage" button. - if (info.source != SETTING_SOURCE_USER) + if (!managed_by_user) set_manage_text_style(ContentSettingBubbleModel::ManageTextStyle::kNone); // The user cannot manually run Flash on the BLOCK setting when either holds: // - The setting is from Policy. User cannot override admin intent. // - HTML By Default is on - Flash has been hidden from the plugin list, so // it's impossible to dynamically run the nonexistent plugin. - bool run_blocked = setting == CONTENT_SETTING_BLOCK && - (info.source != SETTING_SOURCE_USER || - PluginUtils::ShouldPreferHtmlOverPlugins(map)); + bool run_blocked = + setting == CONTENT_SETTING_BLOCK && + (!managed_by_user || PluginUtils::ShouldPreferHtmlOverPlugins(map)); if (!run_blocked) { set_custom_link(l10n_util::GetStringUTF16(IDS_BLOCKED_PLUGINS_LOAD_ALL)); @@ -844,23 +874,10 @@ radio_group.radio_items.push_back(radio_allow_label); radio_group.radio_items.push_back(radio_block_label); + ContentSetting setting; - SettingSource setting_source = SETTING_SOURCE_NONE; - - if (content_type() == CONTENT_SETTINGS_TYPE_COOKIES) { - content_settings::CookieSettings* cookie_settings = - CookieSettingsFactory::GetForProfile(profile()).get(); - cookie_settings->GetCookieSetting(url, url, &setting_source, &setting); - } else { - SettingInfo info; - HostContentSettingsMap* map = - HostContentSettingsMapFactory::GetForProfile(profile()); - std::unique_ptr<base::Value> value = - map->GetWebsiteSetting(url, url, content_type(), std::string(), &info); - setting = content_settings::ValueToContentSetting(value.get()); - setting_source = info.source; - } - + bool managed_by_user = + GetSettingManagedByUser(url, content_type(), profile(), &setting); if (setting == CONTENT_SETTING_ALLOW) { radio_group.default_item = kAllowButtonIndex; // |block_setting_| is already set to |CONTENT_SETTING_BLOCK|. @@ -868,13 +885,7 @@ radio_group.default_item = 1; block_setting_ = setting; } - - const auto* map = HostContentSettingsMapFactory::GetForProfile(profile()); - // Prevent creation of content settings for illegal urls like about:blank - bool is_valid = map->CanSetNarrowestContentSetting(url, url, content_type()); - - set_radio_group_enabled(is_valid && setting_source == SETTING_SOURCE_USER); - + set_radio_group_enabled(managed_by_user); set_radio_group(radio_group); } @@ -1511,18 +1522,8 @@ return; } set_radio_group(radio_group); - - SettingInfo info; - HostContentSettingsMap* map = - HostContentSettingsMapFactory::GetForProfile(profile()); - map->GetWebsiteSetting(url, url, CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, - std::string(), &info); - - // Prevent creation of content settings for illegal urls like about:blank - bool is_valid = map->CanSetNarrowestContentSetting( - url, url, CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS); - - set_radio_group_enabled(is_valid && info.source == SETTING_SOURCE_USER); + set_radio_group_enabled(GetSettingManagedByUser( + url, CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, profile(), nullptr)); } void ContentSettingDownloadsBubbleModel::SetTitle() {
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc index a12e0f7..18ac1de 100644 --- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc +++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -47,7 +47,6 @@ #include "chrome/common/web_application_info.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/ui_test_utils.h" -#include "components/security_interstitials/content/security_interstitial_tab_helper.h" #include "components/security_interstitials/core/controller_client.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/interstitial_page.h" @@ -126,28 +125,14 @@ if (!proceed_through_interstitial) return; + content::InterstitialPage* interstitial = web_contents->GetInterstitialPage(); { // Need a second TestNavigationObserver; the above one is spent. content::TestNavigationObserver observer( web_contents, content::MessageLoopRunner::QuitMode::DEFERRED); - if (base::FeatureList::IsEnabled(features::kSSLCommittedInterstitials)) { - security_interstitials::SecurityInterstitialTabHelper* helper = - security_interstitials::SecurityInterstitialTabHelper:: - FromWebContents( - browser->tab_strip_model()->GetActiveWebContents()); - ASSERT_TRUE( - helper && - helper->GetBlockingPageForCurrentlyCommittedNavigationForTesting()); - std::string javascript = - "window.certificateErrorPageController.proceed();"; - ASSERT_TRUE(content::ExecuteScript(web_contents, javascript)); - } else { - content::InterstitialPage* interstitial = - web_contents->GetInterstitialPage(); - ASSERT_TRUE(interstitial); - interstitial->GetDelegateForTesting()->CommandReceived( - base::IntToString(security_interstitials::CMD_PROCEED)); - } + ASSERT_TRUE(interstitial); + interstitial->GetDelegateForTesting()->CommandReceived( + base::IntToString(security_interstitials::CMD_PROCEED)); observer.Wait(); } } @@ -798,19 +783,9 @@ // There should be no interstitial shown because we previously proceeded // through it. - if (base::FeatureList::IsEnabled(features::kSSLCommittedInterstitials)) { - security_interstitials::SecurityInterstitialTabHelper* helper = - security_interstitials::SecurityInterstitialTabHelper:: - FromWebContents( - browser()->tab_strip_model()->GetActiveWebContents()); - ASSERT_FALSE( - helper && - helper->GetBlockingPageForCurrentlyCommittedNavigationForTesting()); - } else { - ASSERT_FALSE(app_browser_->tab_strip_model() - ->GetActiveWebContents() - ->GetInterstitialPage()); - } + ASSERT_FALSE(app_browser_->tab_strip_model() + ->GetActiveWebContents() + ->GetInterstitialPage()); proceed_through_interstitial = false; }
diff --git a/chrome/browser/ui/libgtkui/BUILD.gn b/chrome/browser/ui/libgtkui/BUILD.gn index ffe7eb80..3a53a45 100644 --- a/chrome/browser/ui/libgtkui/BUILD.gn +++ b/chrome/browser/ui/libgtkui/BUILD.gn
@@ -14,8 +14,6 @@ "app_indicator_icon.h", "app_indicator_icon_menu.cc", "app_indicator_icon_menu.h", - "chrome_gtk_menu_subclasses.cc", - "chrome_gtk_menu_subclasses.h", "gtk_background_painter.cc", "gtk_background_painter.h", "gtk_event_loop.cc",
diff --git a/chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.cc b/chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.cc deleted file mode 100644 index 33944bb..0000000 --- a/chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.cc +++ /dev/null
@@ -1,29 +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 "chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h" - -G_DEFINE_TYPE(GtkCustomMenu, gtk_custom_menu, GTK_TYPE_MENU) - -static void gtk_custom_menu_init(GtkCustomMenu* menu) { -} - -static void gtk_custom_menu_class_init(GtkCustomMenuClass* klass) { -} - -GtkWidget* gtk_custom_menu_new() { - return GTK_WIDGET(g_object_new(gtk_custom_menu_get_type(), nullptr)); -} - -G_DEFINE_TYPE(GtkCustomMenuItem, gtk_custom_menu_item, GTK_TYPE_MENU_ITEM) - -static void gtk_custom_menu_item_init(GtkCustomMenuItem* item) { -} - -static void gtk_custom_menu_item_class_init(GtkCustomMenuItemClass* klass) { -} - -GtkWidget* gtk_custom_menu_item_new() { - return GTK_WIDGET(g_object_new(gtk_custom_menu_item_get_type(), nullptr)); -}
diff --git a/chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h b/chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h deleted file mode 100644 index fd999576..0000000 --- a/chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h +++ /dev/null
@@ -1,47 +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 CHROME_BROWSER_UI_LIBGTKUI_CHROME_GTK_MENU_SUBCLASSES_H_ -#define CHROME_BROWSER_UI_LIBGTKUI_CHROME_GTK_MENU_SUBCLASSES_H_ - -#include <gtk/gtk.h> - -// This file declares two subclasses of Gtk's menu classes. We do this because -// when we were a GTK app proper, we had classes with the same names, and gtk -// theme authors started writing themes and styling chrome's menus by targeting -// these classes. We have to fetch our colors from these theme classes in -// specific because several newer GTK+2 themes are pixmap based and they -// specifically give real colors only to these classes. - -G_BEGIN_DECLS - -typedef struct _GtkCustomMenu GtkCustomMenu; -typedef struct _GtkCustomMenuClass GtkCustomMenuClass; - -struct _GtkCustomMenu { - GtkMenu menu; -}; - -struct _GtkCustomMenuClass { - GtkMenuClass parent_class; -}; - -GtkWidget* gtk_custom_menu_new(); - -typedef struct _GtkCustomMenuItem GtkCustomMenuItem; -typedef struct _GtkCustomMenuItemClass GtkCustomMenuItemClass; - -struct _GtkCustomMenuItem { - GtkMenuItem menu_item; -}; - -struct _GtkCustomMenuItemClass { - GtkMenuItemClass parent_class; -}; - -GtkWidget* gtk_custom_menu_item_new(); - -G_END_DECLS - -#endif // CHROME_BROWSER_UI_LIBGTKUI_CHROME_GTK_MENU_SUBCLASSES_H_
diff --git a/chrome/browser/ui/libgtkui/native_theme_gtk.cc b/chrome/browser/ui/libgtkui/native_theme_gtk.cc index e9147f2..14ca0b6e 100644 --- a/chrome/browser/ui/libgtkui/native_theme_gtk.cc +++ b/chrome/browser/ui/libgtkui/native_theme_gtk.cc
@@ -6,7 +6,6 @@ #include <gtk/gtk.h> -#include "chrome/browser/ui/libgtkui/chrome_gtk_menu_subclasses.h" #include "chrome/browser/ui/libgtkui/gtk_util.h" #include "chrome/browser/ui/libgtkui/skia_utils_gtk.h" #include "ui/gfx/color_palette.h"
diff --git a/chrome/browser/ui/login/login_handler_browsertest.cc b/chrome/browser/ui/login/login_handler_browsertest.cc index 48da8ed..51be03f 100644 --- a/chrome/browser/ui/login/login_handler_browsertest.cc +++ b/chrome/browser/ui/login/login_handler_browsertest.cc
@@ -21,12 +21,10 @@ #include "chrome/browser/ui/login/login_handler_test_utils.h" #include "chrome/browser/ui/login/login_interstitial_delegate.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_features.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/prefs/pref_service.h" -#include "components/security_interstitials/content/security_interstitial_tab_helper.h" #include "content/public/browser/interstitial_page.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_source.h" @@ -46,26 +44,6 @@ namespace { -bool AreCommittedInterstitialsEnabled() { - return base::FeatureList::IsEnabled(features::kSSLCommittedInterstitials); -} - -content::InterstitialPageDelegate* GetInterstitialDelegate( - content::WebContents* tab) { - if (AreCommittedInterstitialsEnabled()) { - security_interstitials::SecurityInterstitialTabHelper* helper = - security_interstitials::SecurityInterstitialTabHelper::FromWebContents( - tab); - if (!helper) - return nullptr; - return helper->GetBlockingPageForCurrentlyCommittedNavigationForTesting(); - } - content::InterstitialPage* interstitial_page = tab->GetInterstitialPage(); - if (!interstitial_page) - return nullptr; - return interstitial_page->GetDelegateForTesting(); -} - class LoginPromptBrowserTest : public InProcessBrowserTest { public: LoginPromptBrowserTest() @@ -1438,9 +1416,7 @@ // the navigation at (2) isn't (navigations ending up in interstitials don't // immediately commit). So just checking for cross origin navigation before // prompting the auth interstitial is not sufficient, must also check if there -// is any other interstitial being displayed. With committed SSL interstitials, -// the navigation is actually cross domain since the interstitial is actually -// a committed navigation, but we still expect the same behavior. +// is any other interstitial being displayed. IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, ShouldReplaceExistingInterstitialWhenNavigated) { ASSERT_TRUE(embedded_test_server()->Start()); @@ -1461,7 +1437,9 @@ // Navigate to an auth url and wait for the login prompt. { WindowedAuthNeededObserver auth_needed_waiter(controller); - ui_test_utils::NavigateToURL(browser(), auth_url); + browser()->OpenURL(OpenURLParams(auth_url, Referrer(), + WindowOpenDisposition::CURRENT_TAB, + ui::PAGE_TRANSITION_TYPED, false)); ASSERT_EQ("127.0.0.1", contents->GetURL().host()); ASSERT_TRUE(contents->GetURL().SchemeIs("http")); auth_needed_waiter.Wait(); @@ -1485,33 +1463,29 @@ // schemes don't match (http vs https). { ASSERT_EQ("127.0.0.1", broken_ssl_page.host()); - ui_test_utils::NavigateToURL(browser(), broken_ssl_page); + browser()->OpenURL(OpenURLParams(broken_ssl_page, Referrer(), + WindowOpenDisposition::CURRENT_TAB, + ui::PAGE_TRANSITION_TYPED, false)); ASSERT_EQ("127.0.0.1", contents->GetURL().host()); ASSERT_TRUE(contents->GetURL().SchemeIs("https")); - if (AreCommittedInterstitialsEnabled()) { - ASSERT_TRUE(WaitForRenderFrameReady(contents->GetMainFrame())); - } else { - content::WaitForInterstitialAttach(contents); - EXPECT_TRUE(contents->ShowingInterstitialPage()); - EXPECT_EQ(SSLBlockingPage::kTypeForTesting, - contents->GetInterstitialPage() - ->GetDelegateForTesting() - ->GetTypeForTesting()); - EXPECT_EQ(auth_url, contents->GetLastCommittedURL()); - } + content::WaitForInterstitialAttach(contents); + EXPECT_TRUE(contents->ShowingInterstitialPage()); + EXPECT_EQ(SSLBlockingPage::kTypeForTesting, contents->GetInterstitialPage() + ->GetDelegateForTesting() + ->GetTypeForTesting()); + EXPECT_EQ(auth_url, contents->GetLastCommittedURL()); } // An overrideable SSL interstitial is now being displayed. Navigate to the // auth URL again. This is again a cross origin navigation, but last committed // URL is the same as the auth URL (since SSL navigation never committed). // Should still replace SSL interstitial with an auth interstitial even though - // last committed URL and the new URL is the same. With committed SSL - // interstitials enabled we still check for the behavior, but the - // SSL interstitial will be a committed navigation so it will be handled as a - // cross origin navigation. + // last committed URL and the new URL is the same. { WindowedAuthNeededObserver auth_needed_waiter(controller); - ui_test_utils::NavigateToURL(browser(), auth_url); + browser()->OpenURL(OpenURLParams(auth_url, Referrer(), + WindowOpenDisposition::CURRENT_TAB, + ui::PAGE_TRANSITION_TYPED, false)); ASSERT_EQ("127.0.0.1", contents->GetURL().host()); ASSERT_TRUE(contents->GetURL().SchemeIs("http")); ASSERT_TRUE(contents->ShowingInterstitialPage()); @@ -1561,30 +1535,21 @@ // Redirect to a broken SSL page. This redirect should not accidentally // proceed through the SSL interstitial. - if (AreCommittedInterstitialsEnabled()) { - content::TestNavigationObserver observer(contents); - EXPECT_TRUE(content::ExecuteScript( - browser()->tab_strip_model()->GetActiveWebContents(), - std::string("window.location = '") + broken_ssl_page.spec() + "'")); - observer.Wait(); - } else { - WindowedAuthCancelledObserver auth_cancelled_waiter(controller); - EXPECT_TRUE(content::ExecuteScript( - browser()->tab_strip_model()->GetActiveWebContents(), - std::string("window.location = '") + broken_ssl_page.spec() + "'")); - content::WaitForInterstitialAttach(contents); - auth_cancelled_waiter.Wait(); - // If the interstitial was accidentally clicked through, this wait may time - // out. - EXPECT_TRUE(WaitForRenderFrameReady( - contents->GetInterstitialPage()->GetMainFrame())); - } + WindowedAuthCancelledObserver auth_cancelled_waiter(controller); + EXPECT_TRUE(content::ExecuteScript( + browser()->tab_strip_model()->GetActiveWebContents(), + std::string("window.location = '") + broken_ssl_page.spec() + "'")); + content::WaitForInterstitialAttach(contents); + auth_cancelled_waiter.Wait(); - content::InterstitialPageDelegate* delegate = - GetInterstitialDelegate(contents); - - EXPECT_TRUE(delegate); - EXPECT_EQ(SSLBlockingPage::kTypeForTesting, delegate->GetTypeForTesting()); + // If the interstitial was accidentally clicked through, this wait may time + // out. + EXPECT_TRUE( + WaitForRenderFrameReady(contents->GetInterstitialPage()->GetMainFrame())); + EXPECT_TRUE(contents->ShowingInterstitialPage()); + EXPECT_EQ(SSLBlockingPage::kTypeForTesting, contents->GetInterstitialPage() + ->GetDelegateForTesting() + ->GetTypeForTesting()); } // Test where Basic HTTP authentication is disabled.
diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer_unittest.cc b/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer_unittest.cc index 501cd2b3..23e0f814 100644 --- a/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer_unittest.cc +++ b/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer_unittest.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/search_engines/template_url_service_factory_test_util.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" #include "components/search_engines/template_url.h" #include "components/search_engines/template_url_data.h" @@ -25,8 +26,6 @@ #include "content/public/browser/notification_source.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/web_contents.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "content/public/test/web_contents_tester.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" #include "net/url_request/test_url_fetcher_factory.h" @@ -36,7 +35,6 @@ #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" #include "services/network/test/test_utils.h" -#include "testing/gtest/include/gtest/gtest.h" using network::TestURLLoaderFactory; @@ -72,18 +70,18 @@ DISALLOW_COPY_AND_ASSIGN(MockChromeOmniboxNavigationObserver); }; -class ChromeOmniboxNavigationObserverTest : public testing::Test { +class ChromeOmniboxNavigationObserverTest + : public ChromeRenderViewHostTestHarness { protected: ChromeOmniboxNavigationObserverTest() {} ~ChromeOmniboxNavigationObserverTest() override {} content::NavigationController* navigation_controller() { - return &(web_contents_->GetController()); + return &(web_contents()->GetController()); } - TestingProfile* profile() { return &profile_; } TemplateURLService* model() { - return TemplateURLServiceFactory::GetForProfile(&profile_); + return TemplateURLServiceFactory::GetForProfile(profile()); } // Functions that return the name of certain search keywords that are part @@ -105,21 +103,15 @@ } private: - // testing::Test: + // ChromeRenderViewHostTestHarness: void SetUp() override; - content::TestBrowserThreadBundle test_browser_thread_bundle_; - TestingProfile profile_; - std::unique_ptr<content::WebContents> web_contents_; - DISALLOW_COPY_AND_ASSIGN(ChromeOmniboxNavigationObserverTest); }; void ChromeOmniboxNavigationObserverTest::SetUp() { - web_contents_ = content::WebContentsTester::CreateTestWebContents( - profile(), content::SiteInstance::Create(profile())); - - InfoBarService::CreateForWebContents(web_contents_.get()); + ChromeRenderViewHostTestHarness::SetUp(); + InfoBarService::CreateForWebContents(web_contents()); // Set up a series of search engines for later testing. TemplateURLServiceFactoryTestUtil factory_util(profile());
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc index 06985ea7..9f64969 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -24,6 +24,7 @@ #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/location_bar/location_bar.h" #include "chrome/browser/ui/passwords/manage_passwords_icon_view.h" +#include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" #include "chrome/browser/ui/passwords/password_dialog_controller_impl.h" #include "chrome/browser/ui/passwords/password_dialog_prompts.h" #include "chrome/browser/ui/tab_dialogs.h" @@ -450,17 +451,13 @@ } void ManagePasswordsUIController::NavigateToPasswordManagerSettingsPage() { - chrome::ShowSettingsSubPage( - chrome::FindBrowserWithWebContents(web_contents()), - chrome::kPasswordManagerSubPage); + NavigateToManagePasswordsPage( + chrome::FindBrowserWithWebContents(web_contents())); } void ManagePasswordsUIController::NavigateToPasswordManagerAccountDashboard() { - GURL dashboard_link(l10n_util::GetStringUTF16(IDS_PASSWORDS_WEB_LINK)); - NavigateParams params(chrome::FindBrowserWithWebContents(web_contents()), - dashboard_link, ui::PAGE_TRANSITION_LINK); - params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; - Navigate(¶ms); + NavigateToGooglePasswordManager( + Profile::FromBrowserContext(web_contents()->GetBrowserContext())); } void ManagePasswordsUIController::EnableSync(const AccountInfo& account,
diff --git a/chrome/browser/ui/passwords/manage_passwords_view_utils.cc b/chrome/browser/ui/passwords/manage_passwords_view_utils.cc index c96451c..315cda0 100644 --- a/chrome/browser/ui/passwords/manage_passwords_view_utils.cc +++ b/chrome/browser/ui/passwords/manage_passwords_view_utils.cc
@@ -8,18 +8,30 @@ #include <algorithm> +#include "base/feature_list.h" #include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/profile_sync_service_factory.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/browser_navigator_params.h" +#include "chrome/browser/ui/chrome_pages.h" +#include "chrome/common/webui_url_constants.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/autofill/core/common/password_form.h" #include "components/browser_sync/profile_sync_service.h" #include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h" +#include "components/password_manager/core/browser/password_manager_client.h" +#include "components/password_manager/core/browser/password_manager_util.h" +#include "components/password_manager/core/common/password_manager_features.h" #include "components/strings/grit/components_strings.h" #include "components/url_formatter/elide_url.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/page_transition_types.h" +#include "ui/base/window_open_disposition.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/image/image_skia.h" @@ -142,3 +154,26 @@ sync_service->IsSyncFeatureActive() && sync_service->GetActiveDataTypes().Has(syncer::PRIORITY_PREFERENCES)); } + +// Navigation is handled differently on Android. +#if !defined(OS_ANDROID) +void NavigateToGooglePasswordManager(Profile* profile) { + NavigateParams params(profile, + GURL(l10n_util::GetStringUTF16(IDS_PASSWORDS_WEB_LINK)), + ui::PAGE_TRANSITION_LINK); + params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; + Navigate(¶ms); +} + +void NavigateToManagePasswordsPage(Browser* browser) { + if (base::FeatureList::IsEnabled( + password_manager::features::kGooglePasswordManager) && + password_manager_util::GetPasswordSyncState( + ProfileSyncServiceFactory::GetForProfile(browser->profile())) == + password_manager::SYNCING_NORMAL_ENCRYPTION) { + NavigateToGooglePasswordManager(browser->profile()); + } else { + chrome::ShowPasswordManager(browser); + } +} +#endif // !defined(OS_ANDROID)
diff --git a/chrome/browser/ui/passwords/manage_passwords_view_utils.h b/chrome/browser/ui/passwords/manage_passwords_view_utils.h index 3af5e27..d222303 100644 --- a/chrome/browser/ui/passwords/manage_passwords_view_utils.h +++ b/chrome/browser/ui/passwords/manage_passwords_view_utils.h
@@ -23,6 +23,7 @@ UPDATE_PASSWORD, // update plain password }; +class Browser; class Profile; // The desired width and height in pixels for an account avatar. @@ -72,4 +73,12 @@ // syncs the PRIORITY_PREFERENCE). The view appearance might depend on it. bool IsSyncingAutosignSetting(Profile* profile); +// Navigates to the Google Password Manager, i.e. passwords.google.com. +void NavigateToGooglePasswordManager(Profile* profile); + +// Navigates to either the Google Password Manager or the Chrome Password +// Settings page, depending on the user's password syncing state and whether the +// corresponding feature flag is enabled. +void NavigateToManagePasswordsPage(Browser* browser); + #endif // CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_VIEW_UTILS_H_
diff --git a/chrome/browser/ui/passwords/password_manager_porter_unittest.cc b/chrome/browser/ui/passwords/password_manager_porter_unittest.cc index 4c2ae0b..f84e503 100644 --- a/chrome/browser/ui/passwords/password_manager_porter_unittest.cc +++ b/chrome/browser/ui/passwords/password_manager_porter_unittest.cc
@@ -12,12 +12,11 @@ #include "base/files/file_util.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" -#include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "chrome/browser/ui/chrome_select_file_policy.h" #include "chrome/browser/ui/passwords/password_manager_presenter.h" #include "chrome/browser/ui/passwords/password_ui_view.h" -#include "chrome/test/base/testing_profile.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "components/password_manager/core/browser/export/password_manager_exporter.h" #include "components/password_manager/core/browser/ui/credential_provider_interface.h" #include "content/public/browser/web_contents.h" @@ -181,18 +180,14 @@ DISALLOW_COPY_AND_ASSIGN(MockPasswordManagerExporter); }; -class PasswordManagerPorterTest : public testing::Test { +class PasswordManagerPorterTest : public ChromeRenderViewHostTestHarness { protected: - PasswordManagerPorterTest() - : scoped_task_environment_( - base::test::ScopedTaskEnvironment::MainThreadType::UI) {} + PasswordManagerPorterTest() = default; ~PasswordManagerPorterTest() override = default; void SetUp() override { + ChromeRenderViewHostTestHarness::SetUp(); password_manager_porter_.reset(new TestPasswordManagerPorter()); - profile_.reset(new TestingProfile()); - web_contents_ = content::WebContentsTester::CreateTestWebContents( - profile_.get(), nullptr); // SelectFileDialog::SetFactory is responsible for freeing the memory // associated with a new factory. selected_file_ = base::FilePath(kNullFileName); @@ -200,25 +195,16 @@ new TestSelectFileDialogFactory(selected_file_)); } - void TearDown() override {} - TestPasswordManagerPorter* password_manager_porter() const { return password_manager_porter_.get(); } - content::WebContents* web_contents() const { return web_contents_.get(); } - - base::test::ScopedTaskEnvironment scoped_task_environment_; // The file that our fake file selector returns. // This file should not actually be used by the test. base::FilePath selected_file_; private: - // TODO(crbug.com/689520) This is needed for mojo not to crash on destruction. - content::TestBrowserThreadBundle thread_bundle_; std::unique_ptr<TestPasswordManagerPorter> password_manager_porter_; - std::unique_ptr<TestingProfile> profile_; - std::unique_ptr<content::WebContents> web_contents_; DISALLOW_COPY_AND_ASSIGN(PasswordManagerPorterTest); };
diff --git a/chrome/browser/ui/search/local_ntp_browsertest.cc b/chrome/browser/ui/search/local_ntp_browsertest.cc index 42ed70d..14f9956 100644 --- a/chrome/browser/ui/search/local_ntp_browsertest.cc +++ b/chrome/browser/ui/search/local_ntp_browsertest.cc
@@ -626,9 +626,8 @@ EXPECT_TRUE(has_add_button); } -// Flaky on Windows, https://crbug.com/903265 IN_PROC_BROWSER_TEST_F(LocalNTPCustomLinksTest, - DISABLED_DontShowAddCustomLinkButtonWhenMaxLinks) { + DontShowAddCustomLinkButtonWhenMaxLinks) { content::WebContents* active_tab = local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank")); @@ -640,7 +639,6 @@ // Get the iframe and add to maximum number of tiles. content::RenderFrameHost* iframe = GetMostVisitedIframe(active_tab); - for (int i = kDefaultMostVisitedItemCount; i < kDefaultCustomLinkMaxCount; ++i) { std::string rid = std::to_string(i + 100); @@ -648,29 +646,25 @@ std::string title = "url for " + rid; // Add most visited tiles via the EmbeddedSearch API. rid = -1 means add new // most visited tile. - EXPECT_TRUE(content::ExecuteScript( + local_ntp_test_utils::ExecuteScriptOnNTPAndWaitUntilLoaded( iframe, "window.chrome.embeddedSearch.newTabPage.updateCustomLink(-1, '" + url + - "', '" + title + "')")); + "', '" + title + "')"); } // Confirm that there are max number of custom link tiles. observer.WaitForNumberOfItems(kDefaultCustomLinkMaxCount); - // Open a new tab and check if the add button still exists - active_tab = local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank")); - local_ntp_test_utils::NavigateToNTPAndWaitUntilLoaded(browser()); - iframe = GetMostVisitedIframe(active_tab); - - // Check there is no add button in the iframe. + // Check there is no add button in the iframe. Make sure not to select from + // old tiles that are in the process of being deleted. bool no_add_button = false; ASSERT_TRUE(instant_test_utils::GetBoolFromJS( - iframe, "document.querySelectorAll('.md-add-icon').length === 0", + iframe, + "document.querySelectorAll('#mv-tiles .md-add-icon').length === 0", &no_add_button)); EXPECT_TRUE(no_add_button); } -// Flaky on Windows, https://crbug.com/903265 -IN_PROC_BROWSER_TEST_F(LocalNTPCustomLinksTest, DISABLED_Reorder) { +IN_PROC_BROWSER_TEST_F(LocalNTPCustomLinksTest, Reorder) { content::WebContents* active_tab = local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank")); @@ -687,42 +681,36 @@ std::string rid = std::to_string(i + 100); std::string url = "https://" + rid + ".com"; std::string title = "url for " + rid; - ASSERT_TRUE(content::ExecuteScript( + local_ntp_test_utils::ExecuteScriptOnNTPAndWaitUntilLoaded( iframe, "window.chrome.embeddedSearch.newTabPage.updateCustomLink(-1, '" + url + - "', '" + title + "')")); + "', '" + title + "')"); } // Confirm that there are max number of custom link tiles. observer.WaitForNumberOfItems(kDefaultCustomLinkMaxCount); - // Open a new tab to get the updated links. - active_tab = local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank")); - local_ntp_test_utils::NavigateToNTPAndWaitUntilLoaded(browser()); - iframe = GetMostVisitedIframe(active_tab); - // Get the title of the tile at index 1. + // Get the title of the tile at index 1. Make sure not to select from old + // tiles that are in the process of being deleted. std::string title; ASSERT_TRUE(instant_test_utils::GetStringFromJS( - iframe, "document.querySelectorAll('.md-tile .md-title')[1].innerText", + iframe, "document.querySelectorAll('#mv-tiles .md-title')[1].innerText", &title)); // Move the tile to the front. std::string tid; ASSERT_TRUE(instant_test_utils::GetStringFromJS( iframe, - "document.querySelectorAll('.md-tile')[1].getAttribute('data-tid')", + "document.querySelectorAll('#mv-tiles " + ".md-tile')[1].getAttribute('data-tid')", &tid)); - EXPECT_TRUE(content::ExecuteScript( + local_ntp_test_utils::ExecuteScriptOnNTPAndWaitUntilLoaded( iframe, "window.chrome.embeddedSearch.newTabPage.reorderCustomLink(" + - tid + ", 0)")); - // Open a new tab to get the updated links. - active_tab = local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank")); - local_ntp_test_utils::NavigateToNTPAndWaitUntilLoaded(browser()); - iframe = GetMostVisitedIframe(active_tab); + tid + ", 0)"); // Check that the first tile is the tile that was moved. std::string new_title; ASSERT_TRUE(instant_test_utils::GetStringFromJS( - iframe, "document.querySelectorAll('.md-tile .md-title')[0].innerText", + iframe, "document.querySelectorAll('#mv-tiles .md-title')[0].innerText", &new_title)); EXPECT_EQ(new_title, title); @@ -730,21 +718,18 @@ std::string end_index = std::to_string(kDefaultCustomLinkMaxCount - 1); ASSERT_TRUE(instant_test_utils::GetStringFromJS( iframe, - "document.querySelectorAll('.md-tile')[0].getAttribute('data-tid')", + "document.querySelectorAll('#mv-tiles " + ".md-tile')[0].getAttribute('data-tid')", &tid)); - EXPECT_TRUE(content::ExecuteScript( + local_ntp_test_utils::ExecuteScriptOnNTPAndWaitUntilLoaded( iframe, "window.chrome.embeddedSearch.newTabPage.reorderCustomLink(" + - tid + ", " + end_index + ")")); - // Open a new tab to get the updated links. - active_tab = local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank")); - local_ntp_test_utils::NavigateToNTPAndWaitUntilLoaded(browser()); - iframe = GetMostVisitedIframe(active_tab); + tid + ", " + end_index + ")"); // Check that the last tile is the tile that was moved. new_title = std::string(); ASSERT_TRUE(instant_test_utils::GetStringFromJS( iframe, - "document.querySelectorAll('.md-tile .md-title')[" + end_index + + "document.querySelectorAll('#mv-tiles .md-title')[" + end_index + "].innerText", &new_title)); EXPECT_EQ(new_title, title);
diff --git a/chrome/browser/ui/search/local_ntp_test_utils.cc b/chrome/browser/ui/search/local_ntp_test_utils.cc index fd28a10..8c6de31 100644 --- a/chrome/browser/ui/search/local_ntp_test_utils.cc +++ b/chrome/browser/ui/search/local_ntp_test_utils.cc
@@ -30,6 +30,57 @@ namespace local_ntp_test_utils { +namespace { + +void WaitUntilTilesLoaded(content::WebContents* active_tab, + content::DOMMessageQueue* msg_queue, + int delay) { + // At this point, the MV iframe may or may not have been fully loaded. Once + // it loads, it sends a 'loaded' postMessage to the page. Check if the page + // has already received that, and if not start listening for it. It's + // important that these two things happen in the same JS invocation, since + // otherwise we might miss the message. + bool mv_tiles_loaded = false; + ASSERT_TRUE(instant_test_utils::GetBoolFromJS( + active_tab, base::StringPrintf(R"js( + (function() { + if (tilesAreLoaded) { + tilesAreLoaded = false; + return true; + } + const loaded = (event) => { + if (event.data.cmd == 'loaded') { + window.removeEventListener('message', loaded); + setTimeout(() => { + tilesAreLoaded = false; + domAutomationController.send('WaitUntilTilesLoaded'); + }, %d); + } + }; + window.addEventListener('message', loaded); + return false; + })() + )js", delay), &mv_tiles_loaded)); + + std::string message; + // Get rid of the message that the GetBoolFromJS call produces. + ASSERT_TRUE(msg_queue->PopMessage(&message)); + + if (mv_tiles_loaded) { + // The tiles are already loaded, i.e. we missed the 'loaded' message. All + // is well. + return; + } + + // Not loaded yet. Wait for the "WaitUntilTilesLoaded" message. + ASSERT_TRUE(msg_queue->WaitForMessage(&message)); + ASSERT_EQ("\"WaitUntilTilesLoaded\"", message); + // There shouldn't be any other messages. + ASSERT_FALSE(msg_queue->PopMessage(&message)); +} + +} // namespace + content::WebContents* OpenNewTab(Browser* browser, const GURL& url) { ui_test_utils::NavigateToURLWithDisposition( browser, url, WindowOpenDisposition::NEW_FOREGROUND_TAB, @@ -54,45 +105,27 @@ ASSERT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), active_tab->GetController().GetVisibleEntry()->GetURL()); - // At this point, the MV iframe may or may not have been fully loaded. Once - // it loads, it sends a 'loaded' postMessage to the page. Check if the page - // has already received that, and if not start listening for it. It's - // important that these two things happen in the same JS invocation, since - // otherwise we might miss the message. - bool mv_tiles_loaded = false; - ASSERT_TRUE(instant_test_utils::GetBoolFromJS( - active_tab, base::StringPrintf(R"js( - (function() { - if (tilesAreLoaded) { - return true; - } - let loaded = window.addEventListener('message', function(event) { - if (event.data.cmd == 'loaded') { - window.removeEventListener('message', loaded); - setTimeout(() => { - domAutomationController.send('NavigateToNTPAndWaitUntilLoaded'); - }, %d); - } - }); - return false; - })() - )js", delay), &mv_tiles_loaded)); + WaitUntilTilesLoaded(active_tab, &msg_queue, delay); +} +void ExecuteScriptOnNTPAndWaitUntilLoaded(content::RenderFrameHost* host, + const std::string& script) { + content::WebContents* contents = + content::WebContents::FromRenderFrameHost(host); + + ASSERT_TRUE(search::IsInstantNTP(contents)); + + // Attach a message queue *before* executing the script, to make sure we don't + // miss the 'loaded' message due to some race condition. + content::DOMMessageQueue msg_queue(contents); + + // Execute the script, and get rid of the message that the ExecuteScript call + // produces. + EXPECT_TRUE(content::ExecuteScript(host, script)); std::string message; - // Get rid of the message that the GetBoolFromJS call produces. ASSERT_TRUE(msg_queue.PopMessage(&message)); - if (mv_tiles_loaded) { - // The tiles are already loaded, i.e. we missed the 'loaded' message. All - // is well. - return; - } - - // Not loaded yet. Wait for the "NavigateToNTPAndWaitUntilLoaded" message. - ASSERT_TRUE(msg_queue.WaitForMessage(&message)); - ASSERT_EQ("\"NavigateToNTPAndWaitUntilLoaded\"", message); - // There shouldn't be any other messages. - ASSERT_FALSE(msg_queue.PopMessage(&message)); + WaitUntilTilesLoaded(contents, &msg_queue, /*delay=*/0); } bool SwitchBrowserLanguageToFrench() {
diff --git a/chrome/browser/ui/search/local_ntp_test_utils.h b/chrome/browser/ui/search/local_ntp_test_utils.h index 97f1a45..d9f0391 100644 --- a/chrome/browser/ui/search/local_ntp_test_utils.h +++ b/chrome/browser/ui/search/local_ntp_test_utils.h
@@ -12,6 +12,7 @@ class Profile; namespace content { +class RenderFrameHost; class WebContents; } // namespace content @@ -26,6 +27,13 @@ // additional amount of time after the page reports as loaded. void NavigateToNTPAndWaitUntilLoaded(Browser* browser, int delay = 0); +// Executes a script on the NTP, verifies it executes successfully, and waits +// until the NTP tiles are reloaded. Note that simply waiting for the script +// execution to complete is not enough, since the MV iframe receives the tiles +// asynchronously. +void ExecuteScriptOnNTPAndWaitUntilLoaded(content::RenderFrameHost* host, + const std::string& script); + // Switches the browser language to French, and returns true iff successful. bool SwitchBrowserLanguageToFrench();
diff --git a/chrome/browser/ui/startup/OWNERS b/chrome/browser/ui/startup/OWNERS index 9a9eaea2..c8eeb1c 100644 --- a/chrome/browser/ui/startup/OWNERS +++ b/chrome/browser/ui/startup/OWNERS
@@ -1 +1,3 @@ -tmartino@chromium.org \ No newline at end of file +tmartino@chromium.org + +per-file credential_provider*=rogerta@chromium.org \ No newline at end of file
diff --git a/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc b/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc index a94b0b0..daca056 100644 --- a/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc +++ b/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc
@@ -8,6 +8,7 @@ #include "base/command_line.h" #include "base/json/json_writer.h" #include "base/strings/string16.h" +#include "base/syslog_logging.h" #include "chrome/browser/signin/signin_promo.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/webui/chrome_web_contents_handler.h" @@ -19,6 +20,7 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h" #include "content/public/browser/web_ui_message_handler.h" +#include "net/base/url_util.h" #include "ui/views/controls/webview/web_dialog_view.h" #include "ui/views/widget/widget.h" #include "ui/web_dialogs/web_dialog_delegate.h" @@ -40,8 +42,19 @@ signin_result.MergeDictionary(&fetch_result); if (base::JSONWriter::Write(signin_result, &json_result) && !json_result.empty()) { - // TODO(crbug.com/887444) output to the correct pipe the JSON result of - // the user sign in. + // The caller of this Chrome process must provide a stdout handle to + // which Chrome can output the results, otherwise by default the call to + // ::GetStdHandle(STD_OUTPUT_HANDLE) will result in an invalid or null + // handle if Chrome was started without providing a console. + HANDLE output_handle = ::GetStdHandle(STD_OUTPUT_HANDLE); + if (output_handle != nullptr && output_handle != INVALID_HANDLE_VALUE) { + DWORD written; + if (!::WriteFile(output_handle, json_result.c_str(), + json_result.length(), &written, nullptr)) { + SYSLOG(ERROR) + << "Failed to write result of GCPW signin to inherited handle."; + } + } } } @@ -161,10 +174,14 @@ // |reauth_email| is used to pre fill in the sign in dialog with the user's // e-mail during a reauthorize sign in. This type of sign in is used to update // the user's password. + // |email_domain| is used to pre fill the email domain on Gaia's signin page + // so that the user only needs to enter their user name. CredentialProviderWebDialogDelegate( const std::string& reauth_email, + const std::string& email_domain, HandleGcpwSigninCompleteResult signin_callback) : reauth_email_(reauth_email), + email_domain_(email_domain), signin_callback_(std::move(signin_callback)) {} GURL GetDialogContentURL() const override { @@ -172,10 +189,19 @@ signin_metrics::AccessPoint::ACCESS_POINT_MACHINE_LOGON; signin_metrics::Reason reason = signin_metrics::Reason::REASON_FETCH_LST_ONLY; - return reauth_email_.empty() - ? signin::GetPromoURLForDialog(access_point, reason, false) - : signin::GetReauthURLWithEmailForDialog(access_point, reason, - reauth_email_); + + auto base_url = + reauth_email_.empty() + ? signin::GetPromoURLForDialog(access_point, reason, false) + : signin::GetReauthURLWithEmailForDialog(access_point, reason, + reauth_email_); + + if (email_domain_.empty()) + return base_url; + + return net::AppendQueryParameter( + base_url, credential_provider::kEmailDomainSigninPromoParameter, + email_domain_); } ui::ModalType GetDialogModalType() const override { @@ -231,7 +257,10 @@ protected: // E-mail used to pre-fill the e-mail field when a reauth signin is required. - std::string reauth_email_; + const std::string reauth_email_; + + // Default domain used for all sign in requests. + const std::string email_domain_; // Callback that will be called when a valid sign in has been completed // through the dialog. @@ -273,11 +302,13 @@ // page. std::string reauth_email = command_line.GetSwitchValueASCII(credential_provider::kGcpwSigninSwitch); + std::string email_domain = + command_line.GetSwitchValueASCII(credential_provider::kEmailDomainSwitch); // Delegate to handle the result of the sign in request. This will // delete itself eventually when it receives the OnDialogClosed call. auto delegate = std::make_unique<CredentialProviderWebDialogDelegate>( - reauth_email, std::move(signin_complete_handler)); + reauth_email, email_domain, std::move(signin_complete_handler)); // The web dialog view that will contain the web ui for the login screen. // This view will be automatically deleted by the widget that owns it when it
diff --git a/chrome/browser/ui/startup/credential_provider_signin_dialog_win_test_data.cc b/chrome/browser/ui/startup/credential_provider_signin_dialog_win_test_data.cc index 22215b6..74b950b 100644 --- a/chrome/browser/ui/startup/credential_provider_signin_dialog_win_test_data.cc +++ b/chrome/browser/ui/startup/credential_provider_signin_dialog_win_test_data.cc
@@ -6,13 +6,40 @@ #include <string> +#include "base/json/json_writer.h" + +const char + CredentialProviderSigninDialogTestDataStorage::kInvalidTokenInfoResponse[] = + "{" + " \"error\": \"invalid_token\"" + "}"; +const char + CredentialProviderSigninDialogTestDataStorage::kInvalidUserInfoResponse[] = + "{" + " \"error\": \"invalid_token\"" + "}"; +const char CredentialProviderSigninDialogTestDataStorage:: + kInvalidTokenFetchResponse[] = + "{" + " \"error\": \"invalid_token\"" + "}"; + +const char + CredentialProviderSigninDialogTestDataStorage::kInvalidEmailForSignin[] = + "foo_bar@example.com"; CredentialProviderSigninDialogTestDataStorage:: CredentialProviderSigninDialogTestDataStorage() : expected_success_signin_result_(base::Value::Type::DICTIONARY), expected_success_fetch_result_(base::Value::Type::DICTIONARY) { + SetSigninPassword("password"); +} + +void CredentialProviderSigninDialogTestDataStorage::SetSigninPassword( + const std::string& password) { expected_success_signin_result_.SetKey("id", base::Value("gaia_user_id")); - expected_success_signin_result_.SetKey("password", base::Value("password")); - expected_success_signin_result_.SetKey("email", base::Value("foo@xyz.com")); + expected_success_signin_result_.SetKey("password", base::Value(password)); + expected_success_signin_result_.SetKey("email", + base::Value("foo_bar@gmail.com")); expected_success_signin_result_.SetKey("access_token", base::Value("access_token")); expected_success_signin_result_.SetKey("refresh_token", @@ -58,3 +85,60 @@ GetSuccessEmail(), GetSuccessAccessToken(), GetSuccessRefreshToken()); } + +std::string +CredentialProviderSigninDialogTestDataStorage::GetSuccessfulSigninResult() + const { + std::string json; + base::JSONWriter::Write(expected_success_signin_result_, &json); + return json; +} + +std::string CredentialProviderSigninDialogTestDataStorage:: + GetSuccessfulSigninTokenFetchResult() const { + return "{" + " \"access_token\": \"" + + GetSuccessAccessToken() + + "\"," + " \"refresh_token\": \"" + + GetSuccessRefreshToken() + + "\"," + " \"id_token\": \"signin_id_token\"," + " \"expires_in\": 1800" + "}"; +} + +std::string CredentialProviderSigninDialogTestDataStorage:: + GetSuccessfulMdmTokenFetchResult() const { + return "{" + " \"access_token\": \"123456789\"," + " \"refresh_token\": \"mdm_refresh_token\"," + " \"id_token\": \"" + + GetSuccessMdmIdToken() + + "\"," + " \"expires_in\": 1800" + "}"; +} + +std::string CredentialProviderSigninDialogTestDataStorage:: + GetSuccessfulTokenInfoFetchResult() const { + return "{" + " \"audience\": \"blah.apps.googleusercontent.blah.com\"," + " \"used_id\": \"1234567890\"," + " \"scope\": \"all the things\"," + " \"expires_in\": 1800," + " \"token_type\": \"Bearer\"," + " \"token_handle\": \"" + + GetSuccessTokenHandle() + + "\"" + "}"; +} + +std::string CredentialProviderSigninDialogTestDataStorage:: + GetSuccessfulUserInfoFetchResult() const { + return "{" + " \"name\": \"" + + GetSuccessFullName() + + "\"" + "}"; +}
diff --git a/chrome/browser/ui/startup/credential_provider_signin_dialog_win_test_data.h b/chrome/browser/ui/startup/credential_provider_signin_dialog_win_test_data.h index ed1d4bc..a479a214 100644 --- a/chrome/browser/ui/startup/credential_provider_signin_dialog_win_test_data.h +++ b/chrome/browser/ui/startup/credential_provider_signin_dialog_win_test_data.h
@@ -29,6 +29,8 @@ const std::string& refresh_token = std::string()); base::Value MakeValidSignInResponseValue() const; + void SetSigninPassword(const std::string& password); + std::string GetSuccessId() const { return expected_success_signin_result_.FindKey("id")->GetString(); } @@ -74,6 +76,17 @@ return EqualsEncodedValue(expected_success_fetch_result(), result_value); } + std::string GetSuccessfulSigninResult() const; + std::string GetSuccessfulSigninTokenFetchResult() const; + std::string GetSuccessfulMdmTokenFetchResult() const; + std::string GetSuccessfulTokenInfoFetchResult() const; + std::string GetSuccessfulUserInfoFetchResult() const; + + static const char kInvalidTokenInfoResponse[]; + static const char kInvalidUserInfoResponse[]; + static const char kInvalidTokenFetchResponse[]; + static const char kInvalidEmailForSignin[]; + private: bool EqualsEncodedValue(const base::Value& success_value, const base::Value& result_value) const {
diff --git a/chrome/browser/ui/startup/credential_provider_signin_info_fetcher_win_unittest.cc b/chrome/browser/ui/startup/credential_provider_signin_info_fetcher_win_unittest.cc index 0a4f2893..95a5bb7 100644 --- a/chrome/browser/ui/startup/credential_provider_signin_info_fetcher_win_unittest.cc +++ b/chrome/browser/ui/startup/credential_provider_signin_info_fetcher_win_unittest.cc
@@ -22,18 +22,7 @@ constexpr char kAccessTokenValue[] = "test_access_token_value"; constexpr char kRefreshTokenValue[] = "test_refresh_token_value"; -constexpr char kInvalidTokenInfoResponse[] = - "{" - " \"error\": \"invalid_token\"" - "}"; -constexpr char kInvalidUserInfoResponse[] = - "{" - " \"error\": \"invalid_token\"" - "}"; -constexpr char kInvalidAccessTokenFetchResponse[] = - "{" - " \"error\": \"invalid_token\"" - "}"; + } // namespace // Provides base functionality for the AccessTokenFetcher Tests below. The @@ -86,30 +75,11 @@ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_)) { valid_token_info_response_ = - "{" - " \"audience\": \"blah.apps.googleusercontent.blah.com\"," - " \"used_id\": \"1234567890\"," - " \"scope\": \"all the things\"," - " \"expires_in\": 1800," - " \"token_type\": \"Bearer\"," - " \"token_handle\": \"" + - test_data_storage_.GetSuccessTokenHandle() + - "\"" - "}"; + test_data_storage_.GetSuccessfulTokenInfoFetchResult(); valid_user_info_response_ = - "{" - " \"name\": \"" + - test_data_storage_.GetSuccessFullName() + - "\"" - "}"; + test_data_storage_.GetSuccessfulUserInfoFetchResult(); valid_access_token_fetch_response_ = - "{" - " \"access_token\": \"123456789\"," - " \"id_token\": \"" + - test_data_storage_.GetSuccessMdmIdToken() + - "\"," - " \"expires_in\": 1800" - "}"; + test_data_storage_.GetSuccessfulMdmTokenFetchResult(); } CredentialProviderFetcherTest::~CredentialProviderFetcherTest() = default; @@ -195,36 +165,44 @@ } TEST_F(CredentialProviderFetcherTest, InvalidAccessTokenFetch) { - SetFakeResponses(kInvalidAccessTokenFetchResponse, net::HTTP_OK, net::OK, - valid_user_info_response_, net::HTTP_OK, net::OK, - valid_token_info_response_, net::HTTP_OK, net::OK); + SetFakeResponses( + CredentialProviderSigninDialogTestDataStorage::kInvalidTokenFetchResponse, + net::HTTP_OK, net::OK, valid_user_info_response_, net::HTTP_OK, net::OK, + valid_token_info_response_, net::HTTP_OK, net::OK); RunFetcher(); EXPECT_TRUE(fetch_result_.DictEmpty()); } TEST_F(CredentialProviderFetcherTest, InvalidUserInfoFetch) { - SetFakeResponses(valid_access_token_fetch_response_, net::HTTP_OK, net::OK, - kInvalidUserInfoResponse, net::HTTP_OK, net::OK, - valid_token_info_response_, net::HTTP_OK, net::OK); + SetFakeResponses( + valid_access_token_fetch_response_, net::HTTP_OK, net::OK, + CredentialProviderSigninDialogTestDataStorage::kInvalidUserInfoResponse, + net::HTTP_OK, net::OK, valid_token_info_response_, net::HTTP_OK, net::OK); RunFetcher(); EXPECT_TRUE(fetch_result_.DictEmpty()); } TEST_F(CredentialProviderFetcherTest, InvalidTokenInfoFetch) { - SetFakeResponses(valid_access_token_fetch_response_, net::HTTP_OK, net::OK, - valid_user_info_response_, net::HTTP_OK, net::OK, - kInvalidTokenInfoResponse, net::HTTP_OK, net::OK); + SetFakeResponses( + valid_access_token_fetch_response_, net::HTTP_OK, net::OK, + valid_user_info_response_, net::HTTP_OK, net::OK, + CredentialProviderSigninDialogTestDataStorage::kInvalidTokenInfoResponse, + net::HTTP_OK, net::OK); RunFetcher(); EXPECT_TRUE(fetch_result_.DictEmpty()); } TEST_F(CredentialProviderFetcherTest, InvalidFetchResult) { - SetFakeResponses(kInvalidAccessTokenFetchResponse, net::HTTP_OK, net::OK, - kInvalidUserInfoResponse, net::HTTP_OK, net::OK, - kInvalidTokenInfoResponse, net::HTTP_OK, net::OK); + SetFakeResponses( + CredentialProviderSigninDialogTestDataStorage::kInvalidTokenFetchResponse, + net::HTTP_OK, net::OK, + CredentialProviderSigninDialogTestDataStorage::kInvalidUserInfoResponse, + net::HTTP_OK, net::OK, + CredentialProviderSigninDialogTestDataStorage::kInvalidTokenInfoResponse, + net::HTTP_OK, net::OK); RunFetcher(); EXPECT_TRUE(fetch_result_.DictEmpty());
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc index 8c21095..90067933 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -83,30 +83,6 @@ // side with two line display. }; -// By default, this returns kLeadingIcon for passwords and kTrailingIcon for all -// other contexts. When a study parameter is present for -// kAutofillDropdownLayoutExperiment, this will return the layout type which -// corresponds to that parameter. -PopupItemLayoutType GetLayoutType(int frontend_id) { - switch (GetForcedPopupLayoutState()) { - case ForcedPopupLayoutState::kLeadingIcon: - return PopupItemLayoutType::kLeadingIcon; - case ForcedPopupLayoutState::kTrailingIcon: - return PopupItemLayoutType::kTrailingIcon; - case ForcedPopupLayoutState::kTwoLinesLeadingIcon: - return PopupItemLayoutType::kTwoLinesLeadingIcon; - case ForcedPopupLayoutState::kDefault: - switch (frontend_id) { - case autofill::PopupItemId::POPUP_ITEM_ID_USERNAME_ENTRY: - case autofill::PopupItemId::POPUP_ITEM_ID_PASSWORD_ENTRY: - case autofill::PopupItemId::POPUP_ITEM_ID_GENERATE_PASSWORD_ENTRY: - return PopupItemLayoutType::kLeadingIcon; - default: - return PopupItemLayoutType::kTrailingIcon; - } - } -} - // Container view that holds one child view and limits its width to the // specified maximum. class ConstrainedWidthView : public views::View { @@ -152,26 +128,21 @@ protected: AutofillPopupItemView(AutofillPopupViewNativeViews* popup_view, int line_number, + int frontend_id, int extra_height = 0) : AutofillPopupRowView(popup_view, line_number), - layout_type_(GetLayoutType(popup_view_->controller() - ->GetSuggestionAt(line_number_) - .frontend_id)), - extra_height_(extra_height) {} - - AutofillPopupItemView(AutofillPopupViewNativeViews* popup_view, - int line_number, - PopupItemLayoutType override_layout_type, - int extra_height = 0) - : AutofillPopupRowView(popup_view, line_number), - layout_type_(override_layout_type), + frontend_id_(frontend_id), extra_height_(extra_height) {} // AutofillPopupRowView: void CreateContent() override; void RefreshStyle() override; - PopupItemLayoutType layout_type() const { return layout_type_; } + int frontend_id() const { return frontend_id_; } + + // Returns the appropriate PopupItemLayoutType to be used when creating + // content. + virtual PopupItemLayoutType GetLayoutType() const = 0; virtual int GetPrimaryTextStyle() = 0; virtual views::View* CreateValueLabel(); // Creates an optional label below the value. @@ -197,7 +168,7 @@ bool resize, views::BoxLayout* layout); - const PopupItemLayoutType layout_type_; + const int frontend_id_; const int extra_height_; DISALLOW_COPY_AND_ASSIGN(AutofillPopupItemView); @@ -211,11 +182,13 @@ static AutofillPopupSuggestionView* Create( AutofillPopupViewNativeViews* popup_view, - int line_number); + int line_number, + int frontend_id); protected: // AutofillPopupItemView: std::unique_ptr<views::Background> CreateBackground() override; + PopupItemLayoutType GetLayoutType() const override; int GetPrimaryTextStyle() override; bool ShouldUseCustomFontWeightForPrimaryInfo( gfx::Font::Weight* font_weight) const override; @@ -223,7 +196,8 @@ views::View* CreateDescriptionLabel() override; AutofillPopupSuggestionView(AutofillPopupViewNativeViews* popup_view, - int line_number); + int line_number, + int frontend_id); DISALLOW_COPY_AND_ASSIGN(AutofillPopupSuggestionView); }; @@ -235,7 +209,8 @@ static PasswordPopupSuggestionView* Create( AutofillPopupViewNativeViews* popup_view, - int line_number); + int line_number, + int frontend_id); protected: // AutofillPopupItemView: @@ -247,7 +222,8 @@ private: PasswordPopupSuggestionView(AutofillPopupViewNativeViews* popup_view, - int line_number); + int line_number, + int frontend_id); base::string16 origin_; base::string16 masked_password_; @@ -262,10 +238,12 @@ static AutofillPopupFooterView* Create( AutofillPopupViewNativeViews* popup_view, - int line_number); + int line_number, + int frontend_id); protected: // AutofillPopupItemView: + PopupItemLayoutType GetLayoutType() const override; void CreateContent() override; std::unique_ptr<views::Background> CreateBackground() override; int GetPrimaryTextStyle() override; @@ -274,7 +252,8 @@ private: AutofillPopupFooterView(AutofillPopupViewNativeViews* popup_view, - int line_number); + int line_number, + int frontend_id); DISALLOW_COPY_AND_ASSIGN(AutofillPopupFooterView); }; @@ -363,7 +342,9 @@ node_data->AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, is_selected_); - // Compute set size and position in set, which must not include separators. + // Compute set size and position in set, by checking the frontend_id of each + // row, summing the number of non-separator rows, and subtracting the number + // of separators found before this row from its |pos_in_set|. int set_size = 0; int pos_in_set = line_number_ + 1; for (int i = 0; i < controller->GetLineCount(); ++i) { @@ -412,8 +393,8 @@ controller->layout_model().GetIconImage(line_number_); if (!icon.isNull() && - (layout_type_ == PopupItemLayoutType::kLeadingIcon || - layout_type_ == PopupItemLayoutType::kTwoLinesLeadingIcon)) { + (GetLayoutType() == PopupItemLayoutType::kLeadingIcon || + GetLayoutType() == PopupItemLayoutType::kTwoLinesLeadingIcon)) { AddIcon(icon); AddSpacerWithSize(views::MenuConfig::instance().item_horizontal_padding, /*resize=*/false, layout_manager); @@ -451,7 +432,7 @@ if (description_label) AddChildView(description_label); - if (!icon.isNull() && layout_type_ == PopupItemLayoutType::kTrailingIcon) { + if (!icon.isNull() && GetLayoutType() == PopupItemLayoutType::kTrailingIcon) { AddSpacerWithSize(views::MenuConfig::instance().item_horizontal_padding, /*resize=*/false, layout_manager); AddIcon(icon); @@ -536,9 +517,10 @@ // static AutofillPopupSuggestionView* AutofillPopupSuggestionView::Create( AutofillPopupViewNativeViews* popup_view, - int line_number) { + int line_number, + int frontend_id) { AutofillPopupSuggestionView* result = - new AutofillPopupSuggestionView(popup_view, line_number); + new AutofillPopupSuggestionView(popup_view, line_number, frontend_id); result->Init(); return result; } @@ -550,6 +532,30 @@ : AutofillPopupBaseView::kBackgroundColor); } +// By default, this returns kLeadingIcon for passwords and kTrailingIcon for all +// other contexts. When a study parameter is present for +// kAutofillDropdownLayoutExperiment, this will return the layout type which +// corresponds to that parameter. +PopupItemLayoutType AutofillPopupSuggestionView::GetLayoutType() const { + switch (GetForcedPopupLayoutState()) { + case ForcedPopupLayoutState::kLeadingIcon: + return PopupItemLayoutType::kLeadingIcon; + case ForcedPopupLayoutState::kTrailingIcon: + return PopupItemLayoutType::kTrailingIcon; + case ForcedPopupLayoutState::kTwoLinesLeadingIcon: + return PopupItemLayoutType::kTwoLinesLeadingIcon; + case ForcedPopupLayoutState::kDefault: + switch (frontend_id()) { + case autofill::PopupItemId::POPUP_ITEM_ID_USERNAME_ENTRY: + case autofill::PopupItemId::POPUP_ITEM_ID_PASSWORD_ENTRY: + case autofill::PopupItemId::POPUP_ITEM_ID_GENERATE_PASSWORD_ENTRY: + return PopupItemLayoutType::kLeadingIcon; + default: + return PopupItemLayoutType::kTrailingIcon; + } + } +} + int AutofillPopupSuggestionView::GetPrimaryTextStyle() { return views::style::TextStyle::STYLE_PRIMARY; } @@ -572,14 +578,15 @@ AutofillPopupSuggestionView::AutofillPopupSuggestionView( AutofillPopupViewNativeViews* popup_view, - int line_number) - : AutofillPopupItemView(popup_view, line_number) { + int line_number, + int frontend_id) + : AutofillPopupItemView(popup_view, line_number, frontend_id) { SetFocusBehavior(FocusBehavior::ALWAYS); } views::View* AutofillPopupSuggestionView::CreateDescriptionLabel() { // When two-line display is enabled, don't display the description. - if (layout_type() == PopupItemLayoutType::kTwoLinesLeadingIcon) + if (GetLayoutType() == PopupItemLayoutType::kTwoLinesLeadingIcon) return nullptr; return AutofillPopupItemView::CreateDescriptionLabel(); } @@ -587,7 +594,7 @@ views::View* AutofillPopupSuggestionView::CreateSubtextLabel() { // When two-line display is disabled, use the default behavior for the popup // item. - if (layout_type() != PopupItemLayoutType::kTwoLinesLeadingIcon) + if (GetLayoutType() != PopupItemLayoutType::kTwoLinesLeadingIcon) return AutofillPopupItemView::CreateSubtextLabel(); base::string16 label_text = @@ -605,9 +612,10 @@ PasswordPopupSuggestionView* PasswordPopupSuggestionView::Create( AutofillPopupViewNativeViews* popup_view, - int line_number) { + int line_number, + int frontend_id) { PasswordPopupSuggestionView* result = - new PasswordPopupSuggestionView(popup_view, line_number); + new PasswordPopupSuggestionView(popup_view, line_number, frontend_id); result->Init(); return result; } @@ -622,7 +630,7 @@ if (!origin_.empty()) { // Always use the origin if it's available. text_to_use = origin_; - } else if (layout_type() == PopupItemLayoutType::kTwoLinesLeadingIcon) { + } else if (GetLayoutType() == PopupItemLayoutType::kTwoLinesLeadingIcon) { // In the two-line layout only, the masked password can be used. text_to_use = masked_password_; } @@ -639,7 +647,7 @@ // When no origin text is available, the two-line layout will use the masked // password in the subtext label, so it should not be reused here. if ((origin_.empty() && - layout_type() == PopupItemLayoutType::kTwoLinesLeadingIcon) || + GetLayoutType() == PopupItemLayoutType::kTwoLinesLeadingIcon) || masked_password_.empty()) { return nullptr; } @@ -656,8 +664,9 @@ PasswordPopupSuggestionView::PasswordPopupSuggestionView( AutofillPopupViewNativeViews* popup_view, - int line_number) - : AutofillPopupSuggestionView(popup_view, line_number) { + int line_number, + int frontend_id) + : AutofillPopupSuggestionView(popup_view, line_number, frontend_id) { origin_ = popup_view_->controller()->GetElidedLabelAt(line_number_); masked_password_ = popup_view_->controller()->GetSuggestionAt(line_number_).additional_label; @@ -668,13 +677,24 @@ // static AutofillPopupFooterView* AutofillPopupFooterView::Create( AutofillPopupViewNativeViews* popup_view, - int line_number) { + int line_number, + int frontend_id) { AutofillPopupFooterView* result = - new AutofillPopupFooterView(popup_view, line_number); + new AutofillPopupFooterView(popup_view, line_number, frontend_id); result->Init(); return result; } +// Returns kTrailingIcon for all contexts except the Show Account Cards prompt, +// when kLeadingIcon is returned. Unlike non-footer rows, footer rows are never +// changed by layout experiments. +PopupItemLayoutType AutofillPopupFooterView::GetLayoutType() const { + return frontend_id() == + autofill::PopupItemId::POPUP_ITEM_ID_SHOW_ACCOUNT_CARDS + ? PopupItemLayoutType::kLeadingIcon + : PopupItemLayoutType::kTrailingIcon; +} + void AutofillPopupFooterView::CreateContent() { SetBorder(views::CreateSolidSidedBorder( /*top=*/views::MenuConfig::instance().separator_thickness, @@ -702,10 +722,11 @@ AutofillPopupFooterView::AutofillPopupFooterView( AutofillPopupViewNativeViews* popup_view, - int line_number) + int line_number, + int frontend_id) : AutofillPopupItemView(popup_view, line_number, - PopupItemLayoutType::kTrailingIcon, + frontend_id, AutofillPopupBaseView::GetCornerRadius()) { SetFocusBehavior(FocusBehavior::ALWAYS); } @@ -849,6 +870,8 @@ RefreshStyle(); } +/************** AutofillPopupViewNativeViews **************/ + AutofillPopupViewNativeViews::AutofillPopupViewNativeViews( AutofillPopupController* controller, views::Widget* parent_widget) @@ -908,12 +931,14 @@ // Process and add all the suggestions which are in the primary container. // Stop once the first footer item is found, or there are no more items. while (line_number < controller_->GetLineCount()) { - switch (controller_->GetSuggestionAt(line_number).frontend_id) { + int frontend_id = controller_->GetSuggestionAt(line_number).frontend_id; + switch (frontend_id) { case autofill::PopupItemId::POPUP_ITEM_ID_CLEAR_FORM: case autofill::PopupItemId::POPUP_ITEM_ID_AUTOFILL_OPTIONS: case autofill::PopupItemId::POPUP_ITEM_ID_SCAN_CREDIT_CARD: case autofill::PopupItemId::POPUP_ITEM_ID_CREDIT_CARD_SIGNIN_PROMO: case autofill::PopupItemId::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY: + case autofill::PopupItemId::POPUP_ITEM_ID_SHOW_ACCOUNT_CARDS: // This is a footer, so this suggestion will be processed later. Don't // increment |line_number|, or else it will be skipped when adding // footer rows below. @@ -931,11 +956,13 @@ case autofill::PopupItemId::POPUP_ITEM_ID_USERNAME_ENTRY: case autofill::PopupItemId::POPUP_ITEM_ID_PASSWORD_ENTRY: - rows_.push_back(PasswordPopupSuggestionView::Create(this, line_number)); + rows_.push_back(PasswordPopupSuggestionView::Create(this, line_number, + frontend_id)); break; default: - rows_.push_back(AutofillPopupSuggestionView::Create(this, line_number)); + rows_.push_back(AutofillPopupSuggestionView::Create(this, line_number, + frontend_id)); } if (has_footer) @@ -979,7 +1006,9 @@ views::BoxLayout::MAIN_AXIS_ALIGNMENT_START); while (line_number < controller_->GetLineCount()) { - rows_.push_back(AutofillPopupFooterView::Create(this, line_number)); + rows_.push_back(AutofillPopupFooterView::Create( + this, line_number, + controller_->GetSuggestionAt(line_number).frontend_id)); footer_container->AddChildView(rows_.back()); line_number++; }
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc index cac0c11..c2aec31 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
@@ -19,9 +19,9 @@ #include "ash/public/cpp/window_properties.h" #include "ash/public/interfaces/constants.mojom.h" #include "ash/public/interfaces/shell_test_api.mojom.h" -#include "ash/shell.h" -#include "ash/wm/overview/window_selector_controller.h" -#include "ash/wm/splitview/split_view_controller.h" +#include "ash/shell.h" // mash-ok +#include "ash/wm/overview/window_selector_controller.h" // mash-ok +#include "ash/wm/splitview/split_view_controller.h" // mash-ok #include "ash/wm/tablet_mode/tablet_mode_controller.h" // mash-ok #include "base/run_loop.h" #include "base/scoped_observer.h" @@ -132,6 +132,20 @@ waiter.Wait(); } +void ToggleOverview() { + if (features::IsUsingWindowService()) { + ash::mojom::ShellTestApiPtr shell_test_api; + content::ServiceManagerConnection::GetForProcess() + ->GetConnector() + ->BindInterface(ash::mojom::kServiceName, &shell_test_api); + base::RunLoop run_loop; + shell_test_api->ToggleOverviewMode(run_loop.QuitClosure()); + run_loop.Run(); + } else { + ash::Shell::Get()->window_selector_controller()->ToggleOverview(); + } +} + BrowserNonClientFrameViewAsh* GetFrameViewAsh(BrowserView* browser_view) { // We know we're using Ash, so static cast. auto* frame_view = static_cast<BrowserNonClientFrameViewAsh*>( @@ -1140,9 +1154,8 @@ EXPECT_EQ(0, window->GetProperty(aura::client::kTopViewInset)); } -// Disabled due to high flake rate; https://crbug.com/818170. IN_PROC_BROWSER_TEST_P(BrowserNonClientFrameViewAshTest, - DISABLED_HeaderVisibilityInOverviewAndSplitview) { + HeaderVisibilityInOverviewAndSplitview) { BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); Widget* widget = browser_view->GetWidget(); BrowserNonClientFrameViewAsh* frame_view = GetFrameViewAsh(browser_view); @@ -1154,10 +1167,9 @@ // Test that the header is invisible for the browser window in overview mode // and visible when not in overview mode. - frame_view->GetFrameWindow()->SetProperty(ash::kIsShowingInOverviewKey, true); + ToggleOverview(); EXPECT_FALSE(frame_view->caption_button_container_->visible()); - frame_view->GetFrameWindow()->SetProperty(ash::kIsShowingInOverviewKey, - false); + ToggleOverview(); EXPECT_TRUE(frame_view->caption_button_container_->visible()); // Create another browser window. @@ -1169,61 +1181,96 @@ AddBlankTabAndShow(browser2); BrowserView* browser_view2 = BrowserView::GetBrowserViewForBrowser(browser2); Widget* widget2 = browser_view2->GetWidget(); - BrowserNonClientFrameViewAsh* frame_view2 = - static_cast<BrowserNonClientFrameViewAsh*>( - widget2->non_client_view()->frame_view()); + BrowserNonClientFrameViewAsh* frame_view2 = GetFrameViewAsh(browser_view2); widget2->GetNativeWindow()->SetProperty( aura::client::kResizeBehaviorKey, ws::mojom::kResizeBehaviorCanMaximize | ws::mojom::kResizeBehaviorCanResize); - // Test that when one browser window is snapped, the header is visible for the - // snapped browser window, but invisible for the browser window still in - // overview mode. - ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(true)); - ash::Shell* shell = ash::Shell::Get(); - ash::SplitViewController* split_view_controller = - shell->split_view_controller(); - split_view_controller->BindRequest( - mojo::MakeRequest(&frame_view->split_view_controller_)); - split_view_controller->BindRequest( - mojo::MakeRequest(&frame_view2->split_view_controller_)); - split_view_controller->AddObserver( - frame_view->CreateInterfacePtrForTesting()); - split_view_controller->AddObserver( - frame_view2->CreateInterfacePtrForTesting()); - frame_view->split_view_controller_.FlushForTesting(); - frame_view2->split_view_controller_.FlushForTesting(); + if (features::IsUsingWindowService()) { + // Test that when one browser window is snapped, the header is visible for + // the snapped browser window, but invisible for the browser window still in + // overview mode. + ToggleOverview(); - frame_view->GetFrameWindow()->SetProperty(ash::kIsShowingInOverviewKey, true); - frame_view2->GetFrameWindow()->SetProperty(ash::kIsShowingInOverviewKey, - true); - split_view_controller->SnapWindow(widget->GetNativeWindow(), - ash::SplitViewController::LEFT); - frame_view->split_view_controller_.FlushForTesting(); - frame_view2->split_view_controller_.FlushForTesting(); - EXPECT_TRUE(frame_view->caption_button_container_->visible()); - EXPECT_FALSE(frame_view2->caption_button_container_->visible()); + ash::mojom::ShellTestApiPtr shell_test_api; + content::ServiceManagerConnection::GetForProcess() + ->GetConnector() + ->BindInterface(ash::mojom::kServiceName, &shell_test_api); - // When both browser windows are snapped, the headers are both visible. - split_view_controller->SnapWindow(widget2->GetNativeWindow(), - ash::SplitViewController::RIGHT); - frame_view->split_view_controller_.FlushForTesting(); - frame_view2->split_view_controller_.FlushForTesting(); - EXPECT_TRUE(frame_view->caption_button_container_->visible()); - EXPECT_TRUE(frame_view2->caption_button_container_->visible()); + { + base::RunLoop run_loop; + shell_test_api->SnapWindowInSplitView(content::mojom::kBrowserServiceName, + frame_view->GetServerWindowId(), + true, run_loop.QuitClosure()); + run_loop.Run(); + } - // Toggle overview mode while splitview mode is active. Test that the header - // is visible for the snapped browser window but not for the other browser - // window in overview mode. - frame_view->GetFrameWindow()->SetProperty(ash::kIsShowingInOverviewKey, - false); - frame_view2->GetFrameWindow()->SetProperty(ash::kIsShowingInOverviewKey, - true); - frame_view->split_view_controller_.FlushForTesting(); - frame_view2->split_view_controller_.FlushForTesting(); - EXPECT_TRUE(frame_view->caption_button_container_->visible()); - EXPECT_FALSE(frame_view2->caption_button_container_->visible()); + EXPECT_TRUE(frame_view->caption_button_container_->visible()); + EXPECT_FALSE(frame_view2->caption_button_container_->visible()); + + // When both browser windows are snapped, the headers are both visible. + { + base::RunLoop run_loop; + shell_test_api->SnapWindowInSplitView(content::mojom::kBrowserServiceName, + frame_view2->GetServerWindowId(), + false, run_loop.QuitClosure()); + run_loop.Run(); + } + + EXPECT_TRUE(frame_view->caption_button_container_->visible()); + EXPECT_TRUE(frame_view2->caption_button_container_->visible()); + + // Toggle overview mode while splitview mode is active. Test that the header + // is visible for the snapped browser window but not for the other browser + // window in overview mode. + ToggleOverview(); + EXPECT_TRUE(frame_view->caption_button_container_->visible()); + EXPECT_FALSE(frame_view2->caption_button_container_->visible()); + } else { + // Test that when one browser window is snapped, the header is visible for + // the snapped browser window, but invisible for the browser window still in + // overview mode. + ash::Shell* shell = ash::Shell::Get(); + ash::SplitViewController* split_view_controller = + shell->split_view_controller(); + split_view_controller->BindRequest( + mojo::MakeRequest(&frame_view->split_view_controller_)); + split_view_controller->BindRequest( + mojo::MakeRequest(&frame_view2->split_view_controller_)); + split_view_controller->AddObserver( + frame_view->CreateInterfacePtrForTesting()); + split_view_controller->AddObserver( + frame_view2->CreateInterfacePtrForTesting()); + frame_view->split_view_controller_.FlushForTesting(); + frame_view2->split_view_controller_.FlushForTesting(); + + ToggleOverview(); + split_view_controller->SnapWindow(widget->GetNativeWindow(), + ash::SplitViewController::LEFT); + frame_view->split_view_controller_.FlushForTesting(); + frame_view2->split_view_controller_.FlushForTesting(); + EXPECT_TRUE(frame_view->caption_button_container_->visible()); + EXPECT_FALSE(frame_view2->caption_button_container_->visible()); + + // When both browser windows are snapped, the headers are both visible. + split_view_controller->SnapWindow(widget2->GetNativeWindow(), + ash::SplitViewController::RIGHT); + frame_view->split_view_controller_.FlushForTesting(); + frame_view2->split_view_controller_.FlushForTesting(); + EXPECT_TRUE(frame_view->caption_button_container_->visible()); + EXPECT_TRUE(frame_view2->caption_button_container_->visible()); + + // Toggle overview mode while splitview mode is active. Test that the header + // is visible for the snapped browser window but not for the other browser + // window in overview mode. + ToggleOverview(); + frame_view->split_view_controller_.FlushForTesting(); + frame_view2->split_view_controller_.FlushForTesting(); + + EXPECT_TRUE(frame_view->caption_button_container_->visible()); + EXPECT_FALSE(frame_view2->caption_button_container_->visible()); + } } // Regression test for https://crbug.com/879851. @@ -1257,7 +1304,6 @@ params.initial_show_state = ui::SHOW_STATE_DEFAULT; Browser* browser = new Browser(params); BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); - BrowserNonClientFrameViewAsh* frame_view = GetFrameViewAsh(browser_view); ImmersiveModeController* immersive_mode_controller = browser_view->immersive_mode_controller(); aura::Window* window = browser->window()->GetNativeWindow(); @@ -1287,7 +1333,7 @@ // The kTopViewInset is the same as in overview mode. const int inset_normal = window->GetProperty(aura::client::kTopViewInset); - frame_view->GetFrameWindow()->SetProperty(ash::kIsShowingInOverviewKey, true); + ToggleOverview(); const int inset_in_overview_mode = window->GetProperty(aura::client::kTopViewInset); EXPECT_EQ(inset_normal, inset_in_overview_mode); @@ -1356,10 +1402,9 @@ ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(true)); EXPECT_FALSE(frame_view->caption_button_container_->visible()); - frame_view->GetFrameWindow()->SetProperty(ash::kIsShowingInOverviewKey, true); + ToggleOverview(); EXPECT_FALSE(frame_view->caption_button_container_->visible()); - frame_view->GetFrameWindow()->SetProperty(ash::kIsShowingInOverviewKey, - false); + ToggleOverview(); EXPECT_FALSE(frame_view->caption_button_container_->visible()); ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(false)); @@ -1377,6 +1422,7 @@ params.initial_show_state = ui::SHOW_STATE_DEFAULT; Browser* browser = new Browser(params); ASSERT_TRUE(browser->is_app()); + browser->window()->Show(); BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); BrowserNonClientFrameViewAsh* frame_view = GetFrameViewAsh(browser_view); @@ -1387,10 +1433,9 @@ EXPECT_TRUE(frame_view->caption_button_container_->visible()); // However, overview mode does. - frame_view->GetFrameWindow()->SetProperty(ash::kIsShowingInOverviewKey, true); + ToggleOverview(); EXPECT_FALSE(frame_view->caption_button_container_->visible()); - frame_view->GetFrameWindow()->SetProperty(ash::kIsShowingInOverviewKey, - false); + ToggleOverview(); EXPECT_TRUE(frame_view->caption_button_container_->visible()); ASSERT_NO_FATAL_FAILURE(test::SetAndWaitForTabletMode(false)); @@ -1428,7 +1473,7 @@ // mode. EXPECT_EQ(expected_height, frame_view->frame_header_->GetHeaderHeight()); - frame_view->GetFrameWindow()->SetProperty(ash::kIsShowingInOverviewKey, true); + ToggleOverview(); if (features::IsUsingWindowService()) { ash::mojom::ShellTestApiPtr shell_test_api; @@ -1437,7 +1482,7 @@ ->BindInterface(ash::mojom::kServiceName, &shell_test_api); base::RunLoop run_loop; shell_test_api->SnapWindowInSplitView(content::mojom::kBrowserServiceName, - frame_view->GetServerWindowId(), + frame_view->GetServerWindowId(), true, run_loop.QuitClosure()); run_loop.Run(); } else {
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index b29e298..42034d9 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1171,6 +1171,13 @@ if (is_animating) contents_web_view_->SetFastResize(true); UpdateUIForContents(GetActiveWebContents()); + + // Do nothing if we're currently participating in a tab dragging process. The + // fast resize bit will be reset and the web contents will get re-layed out + // after the tab dragging ends. + if (in_tab_dragging_) + return; + if (is_animating) contents_web_view_->SetFastResize(false); @@ -1184,6 +1191,24 @@ } } +void BrowserView::TabDraggingStatusChanged(bool is_dragging) { + if (in_tab_dragging_ == is_dragging) + return; + + in_tab_dragging_ = is_dragging; + if (in_tab_dragging_) { + contents_web_view_->SetFastResize(true); + } else { + contents_web_view_->SetFastResize(false); + + // When tab dragging is ended, we need to make sure the web contents get + // re-layed out. Otherwise we may see web contents get clipped to the window + // size that was used during dragging. + contents_web_view_->InvalidateLayout(); + contents_container_->Layout(); + } +} + void BrowserView::FocusBookmarksToolbar() { DCHECK(!immersive_mode_controller_->IsEnabled()); if (bookmark_bar_view_ && bookmark_bar_view_->visible() &&
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index f5aa356..f4cba3e 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -343,6 +343,7 @@ void FocusToolbar() override; ToolbarActionsBar* GetToolbarActionsBar() override; void ToolbarSizeChanged(bool is_animating) override; + void TabDraggingStatusChanged(bool is_dragging) override; void FocusAppMenu() override; void FocusBookmarksToolbar() override; void FocusInactivePopupForAccessibility() override; @@ -771,6 +772,13 @@ // jankiness. bool in_process_fullscreen_ = false; + // True if we're participating in a tab dragging process. The value can be + // true if the accociated browser is the dragged browser or the source browser + // that the drag tab(s) originates from. During tab dragging process, the + // dragged browser or the source browser's bounds may change, the fast resize + // strategy will be used to resize its web contents for smoother dragging. + bool in_tab_dragging_ = false; + std::unique_ptr<ExclusiveAccessBubbleViews> exclusive_access_bubble_; #if defined(OS_WIN)
diff --git a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc index 66e54e8..308cd34 100644 --- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc +++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc
@@ -185,10 +185,6 @@ return ShouldShowLabel(); } -bool IconLabelBubbleView::ShouldShowExtraEndSpace() const { - return false; -} - double IconLabelBubbleView::WidthMultiplier() const { if (!slide_animation_.is_animating() && !is_animation_paused_) return 1.0; @@ -455,15 +451,13 @@ } int IconLabelBubbleView::GetWidthBetweenIconAndSeparator() const { - return ShouldShowSeparator() || ShouldShowExtraEndSpace() - ? kIconLabelBubbleSpaceBesideSeparator - : 0; + return ShouldShowSeparator() ? kIconLabelBubbleSpaceBesideSeparator : 0; } int IconLabelBubbleView::GetEndPaddingWithSeparator() const { int end_padding = ShouldShowSeparator() ? kIconLabelBubbleSpaceBesideSeparator : GetInsets().right(); - if (ShouldShowSeparator() || ShouldShowExtraEndSpace()) + if (ShouldShowSeparator()) end_padding += kIconLabelBubbleSeparatorWidth; return end_padding; }
diff --git a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h index e0b3005..95e2681 100644 --- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h +++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h
@@ -109,12 +109,6 @@ // Returns true when the separator should be visible. virtual bool ShouldShowSeparator() const; - // Returns true when additional padding equal to - // GetWidthBetweenIconAndSeparator() should be added to the end of the view. - // This is useful in the case where it's required to layout subsequent views - // in the same position regardless of whether the separator is shown or not. - virtual bool ShouldShowExtraEndSpace() const; - // Returns a multiplier used to calculate the actual width of the view based // on its desired width. This ranges from 0 for a zero-width view to 1 for a // full-width view and can be used to animate the width of the view.
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index 6455ef6..ed1284e 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -421,35 +421,34 @@ const int edge_padding = GetLayoutConstant(LOCATION_BAR_ELEMENT_PADDING); int leading_edit_item_padding = edge_padding; - if (OmniboxFieldTrial::IsJogTextfieldOnPopupEnabled()) { - // With jog enabled, the text should be indented only if these are all true: - // - The popup is open. - // - The location icon view does *not* have a label. - // - The selected keyword view is *not* shown. - // - // In most cases, we only care that the popup is open, in which case we - // indent to align with the text in the popup. But there's two edge cases: - // - If there is text in the location icon view (which can happen with zero - // suggest, which continues to show security or EV cert text at the same - // time as the popup is open), the text in the omnibox can't align with - // the text of the suggestions, so the indent just moves the text for no - // apparent reason. - // - If there is a selected keyword label (i.e. "Search Google") shown, we - // already indent this label to align with the suggestions text, so - // further indenting the textfield just moves the text for no apparent - // reason. - // - // TODO(jdonnelly): The better solution may be to remove the location icon - // text when zero suggest triggers. - const bool should_indent = GetOmniboxPopupView()->IsOpen() && - !location_icon_view_->ShouldShowLabel() && - !ShouldShowKeywordBubble(); - // We have an odd indent value because this is what matches the odd text - // indent value in OmniboxMatchCellView. - constexpr int kTextJogIndentDp = 11; - leading_edit_item_padding = should_indent ? kTextJogIndentDp : 0; - } + // The text should be indented only if these are all true: + // - The popup is open. + // - The location icon view does *not* have a label. + // - The selected keyword view is *not* shown. + // + // In most cases, we only care that the popup is open, in which case we + // indent to align with the text in the popup. But there's two edge cases: + // - If there is text in the location icon view (which can happen with zero + // suggest, which continues to show security or EV cert text at the same + // time as the popup is open), the text in the omnibox can't align with + // the text of the suggestions, so the indent just moves the text for no + // apparent reason. + // - If there is a selected keyword label (i.e. "Search Google") shown, we + // already indent this label to align with the suggestions text, so + // further indenting the textfield just moves the text for no apparent + // reason. + // + // TODO(jdonnelly): The better solution may be to remove the location icon + // text when zero suggest triggers. + const bool should_indent = GetOmniboxPopupView()->IsOpen() && + !location_icon_view_->ShouldShowLabel() && + !ShouldShowKeywordBubble(); + + // We have an odd indent value because this is what matches the odd text + // indent value in OmniboxMatchCellView. + constexpr int kTextJogIndentDp = 11; + leading_edit_item_padding = should_indent ? kTextJogIndentDp : 0; // We always subtract the left padding of the OmniboxView itself to allow for // an extended I-beam click target without affecting actual layout. @@ -1100,10 +1099,9 @@ if (focus_ring_) focus_ring_->SchedulePaint(); - if (OmniboxFieldTrial::IsJogTextfieldOnPopupEnabled()) { - Layout(); - SchedulePaint(); - } + // We indent the textfield when the popup is open to align to suggestions. + Layout(); + SchedulePaint(); } const LocationBarModel* LocationBarView::GetLocationBarModel() const {
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view.cc b/chrome/browser/ui/views/location_bar/location_icon_view.cc index 9ab6da65..877d2253 100644 --- a/chrome/browser/ui/views/location_bar/location_icon_view.cc +++ b/chrome/browser/ui/views/location_bar/location_icon_view.cc
@@ -58,20 +58,7 @@ } bool LocationIconView::ShouldShowSeparator() const { - if (ShouldShowLabel()) - return true; - - if (OmniboxFieldTrial::IsJogTextfieldOnPopupEnabled()) - return false; - - return !delegate_->IsEditingOrEmpty(); -} - -bool LocationIconView::ShouldShowExtraEndSpace() const { - if (OmniboxFieldTrial::IsJogTextfieldOnPopupEnabled()) - return false; - - return delegate_->IsEditingOrEmpty(); + return ShouldShowLabel(); } bool LocationIconView::ShowBubble(const ui::Event& event) {
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view.h b/chrome/browser/ui/views/location_bar/location_icon_view.h index e2c96f84..1d35276 100644 --- a/chrome/browser/ui/views/location_bar/location_icon_view.h +++ b/chrome/browser/ui/views/location_bar/location_icon_view.h
@@ -73,7 +73,6 @@ bool OnMouseDragged(const ui::MouseEvent& event) override; SkColor GetTextColor() const override; bool ShouldShowSeparator() const override; - bool ShouldShowExtraEndSpace() const override; bool ShowBubble(const ui::Event& event) override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; bool IsBubbleShowing() const override;
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc index 2554bf0..b01e51cad 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.cc +++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -110,17 +110,19 @@ // The media controls should take and handle user interaction. OverlayWindowViews* window = static_cast<OverlayWindowViews*>(widget_); - if (window->GetCloseControlsBounds().Contains(point) || - window->GetFirstCustomControlsBounds().Contains(point) || - window->GetSecondCustomControlsBounds().Contains(point) || - window->GetPlayPauseControlsBounds().Contains(point)) { + if (window->AreControlsVisible() && + (window->GetCloseControlsBounds().Contains(point) || + window->GetFirstCustomControlsBounds().Contains(point) || + window->GetSecondCustomControlsBounds().Contains(point) || + window->GetPlayPauseControlsBounds().Contains(point))) { return window_component; } #if defined(OS_CHROMEOS) // If the resize handle is clicked on, we want to force the hit test to // force a resize drag. - if (window->GetResizeHandleControlsBounds().Contains(point)) + if (window->AreControlsVisible() && + window->GetResizeHandleControlsBounds().Contains(point)) return window->GetResizeHTComponent(); #endif @@ -782,7 +784,7 @@ // layers are expected to have the same visibility. // TODO(apacible): This placeholder logic should be updated with touchscreen // specific investigation. https://crbug/854373 - if (!GetControlsScrimLayer()->visible()) { + if (!AreControlsVisible()) { UpdateControlsVisibility(true); return; } @@ -841,6 +843,10 @@ return resize_handle_view_->GetHTComponent(); } +bool OverlayWindowViews::AreControlsVisible() const { + return controls_scrim_view_->layer()->visible(); +} + ui::Layer* OverlayWindowViews::GetControlsScrimLayer() { return controls_scrim_view_->layer(); }
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.h b/chrome/browser/ui/views/overlay/overlay_window_views.h index df2914b..3abbcc77 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.h +++ b/chrome/browser/ui/views/overlay/overlay_window_views.h
@@ -74,6 +74,10 @@ // handle in order to force a drag-to-resize. int GetResizeHTComponent() const; + // Returns true if the controls (e.g. close button, play/pause button) are + // visible. + bool AreControlsVisible() const; + views::ToggleImageButton* play_pause_controls_view_for_testing() const; gfx::Point close_image_position_for_testing() const; gfx::Point resize_handle_position_for_testing() const;
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index fef1e043..622e37fb 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -39,6 +39,7 @@ #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" #include "chrome/browser/ui/profile_chooser_constants.h" #include "chrome/browser/ui/singleton_tabs.h" #include "chrome/browser/ui/sync/sync_promo_ui.h" @@ -59,7 +60,6 @@ #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" #include "components/browser_sync/profile_sync_service.h" -#include "components/password_manager/core/common/password_manager_features.h" #include "components/prefs/pref_service.h" #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/gaia_cookie_manager_service.h" @@ -624,7 +624,7 @@ if (sender == passwords_button_) { base::RecordAction( base::UserMetricsAction("ProfileChooser_PasswordsClicked")); - chrome::ShowSettingsSubPage(browser_, chrome::kPasswordManagerSubPage); + NavigateToManagePasswordsPage(browser_); } else if (sender == credit_cards_button_) { base::RecordAction( base::UserMetricsAction("ProfileChooser_PaymentsClicked"));
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.cc b/chrome/browser/ui/views/select_file_dialog_extension.cc index 4a1deb6..7acbb09 100644 --- a/chrome/browser/ui/views/select_file_dialog_extension.cc +++ b/chrome/browser/ui/views/select_file_dialog_extension.cc
@@ -157,8 +157,6 @@ if (!*web_contents) *web_contents = GetLoginWebContents(); #endif - - CHECK(*web_contents); } } // namespace @@ -353,18 +351,18 @@ // The web contents to associate the dialog with. content::WebContents* web_contents = NULL; FindRuntimeContext(owner_window, &base_window, &web_contents); - CHECK(web_contents); - profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext()); - CHECK(profile_); + if (web_contents) + profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext()); #if defined(OS_CHROMEOS) - // Handle the case when |web_contents| is associated with Default profile. - if (chromeos::ProfileHelper::IsSigninProfile(profile_)) { + // Handle the cases where |web_contents| is not available or |web_contents| is + // associated with Default profile. + if (!web_contents || chromeos::ProfileHelper::IsSigninProfile(profile_)) profile_ = ProfileManager::GetActiveUserProfile(); - CHECK(profile_); - } #endif + DCHECK(profile_); + // Check if we have another dialog opened for the contents. It's unlikely, but // possible. In such situation, discard this request. RoutingID routing_id = GetRoutingIDFromWebContents(web_contents);
diff --git a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc index 7d6c4a4..5ca8088d 100644 --- a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc +++ b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
@@ -312,7 +312,8 @@ listener_->WaitForCalled(); // Dialog no longer believes it is running. - ASSERT_FALSE(dialog_->IsRunning(owning_window)); + if (owning_window) + ASSERT_FALSE(dialog_->IsRunning(owning_window)); } base::ScopedTempDir tmp_dir_; @@ -545,3 +546,20 @@ // Wait for file dialog's "ready" message. EXPECT_TRUE(listener.WaitUntilSatisfied()); } + +#if defined(OS_CHROMEOS) +IN_PROC_BROWSER_TEST_F(SelectFileDialogExtensionBrowserTest, + OpenDialogWithoutOwningWindow) { + // Open the file dialog with no |owning_window|. + ASSERT_NO_FATAL_FAILURE(OpenDialog(ui::SelectFileDialog::SELECT_OPEN_FILE, + base::FilePath(), + nullptr /* owning_window */, "")); + + // Click the "Cancel" button. + CloseDialog(DIALOG_BTN_CANCEL, nullptr /* owning_window */); + + // Listener should have been informed of the cancellation. + ASSERT_TRUE(listener_->canceled()); + ASSERT_EQ(this, listener_->params()); +} +#endif
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc index 4d47754..9335735 100644 --- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc +++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h" #include "chrome/browser/ui/tabs/tab_utils.h" #include "chrome/browser/ui/views/tabs/tab.h" +#include "chrome/browser/ui/views/tabs/tab_drag_controller.h" #include "chrome/browser/ui/views/tabs/tab_renderer_data.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/common/chrome_switches.h" @@ -73,6 +74,19 @@ #endif } +// Gets the source browser view during a tab dragging. Returns nullptr if there +// is none. +BrowserView* GetSourceBrowserViewInTabDragging() { + TabStrip* source_tabstrip = TabDragController::GetSourceTabStrip(); + if (source_tabstrip) { + gfx::NativeWindow source_window = + source_tabstrip->GetWidget()->GetNativeWindow(); + if (source_window) + return BrowserView::GetBrowserViewForNativeWindow(source_window); + } + return nullptr; +} + } // namespace class BrowserTabStripController::TabContextMenuContents @@ -380,10 +394,25 @@ browser_view_->immersive_mode_controller()->GetRevealedLock( ImmersiveModeController::ANIMATE_REVEAL_NO)); } + + browser_view_->TabDraggingStatusChanged(/*is_dragging=*/true); + // We also use fast resize for the source browser window as the source browser + // window may also change bounds during dragging. + BrowserView* source_browser_view = GetSourceBrowserViewInTabDragging(); + if (source_browser_view && source_browser_view != browser_view_) + source_browser_view->TabDraggingStatusChanged(/*is_dragging=*/true); } void BrowserTabStripController::OnStoppedDraggingTabs() { immersive_reveal_lock_.reset(); + + BrowserView* source_browser_view = GetSourceBrowserViewInTabDragging(); + // Only reset the source window's fast resize bit after the entire drag + // ends. + if (browser_view_ != source_browser_view) + browser_view_->TabDraggingStatusChanged(/*is_dragging=*/false); + if (source_browser_view && !TabDragController::IsActive()) + source_browser_view->TabDraggingStatusChanged(/*is_dragging=*/false); } bool BrowserTabStripController::IsFrameCondensed() const {
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc index 0680096..ddf58b2 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -455,6 +455,12 @@ return g_tab_drag_controller && g_tab_drag_controller->active(); } +// static +TabStrip* TabDragController::GetSourceTabStrip() { + return g_tab_drag_controller ? g_tab_drag_controller->source_tabstrip_ + : nullptr; +} + void TabDragController::SetMoveBehavior(MoveBehavior behavior) { if (started_drag()) return; @@ -1885,7 +1891,9 @@ Profile* profile = Profile::FromBrowserContext(drag_data_[0].contents->GetBrowserContext()); - Browser::CreateParams create_params(Browser::TYPE_TABBED, profile, true); + Browser::CreateParams create_params(Browser::TYPE_TABBED, profile, + /*user_gesture=*/true, + /*in_tab_dragging=*/true); create_params.initial_bounds = new_bounds; Browser* browser = new Browser(create_params); is_dragging_new_browser_ = true;
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.h b/chrome/browser/ui/views/tabs/tab_drag_controller.h index e5bc98d..54a579e 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.h +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.h
@@ -104,6 +104,9 @@ // Returns true if there is a drag underway. static bool IsActive(); + // Returns the pointer of |source_tabstrip_|. + static TabStrip* GetSourceTabStrip(); + // Sets the move behavior. Has no effect if started_drag() is true. void SetMoveBehavior(MoveBehavior behavior); MoveBehavior move_behavior() const { return move_behavior_; }
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc index 6b9c6f5..7a47217 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -49,6 +49,7 @@ #include "ui/base/test/ui_controls.h" #include "ui/display/display.h" #include "ui/display/screen.h" +#include "ui/views/controls/native/native_view_host.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" @@ -3016,6 +3017,75 @@ EXPECT_EQ(2u, browser_list->size()); } +namespace { + +// Returns true if the web contents that's accociated with |browser| is using +// fast resize. +bool WebContentsIsFastResized(Browser* browser) { + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); + ContentsWebView* contents_web_view = + static_cast<ContentsWebView*>(browser_view->GetContentsView()); + return contents_web_view->holder()->fast_resize(); +} + +void FastResizeDuringDraggingStep2(DetachToBrowserTabDragControllerTest* test, + TabStrip* not_attached_tab_strip, + TabStrip* target_tab_strip) { + // There should be three browser windows, incluing the newly created one for + // the dragged tab. + EXPECT_EQ(3u, test->browser_list->size()); + + // Get this new created window for the drag. It should have fast resize set. + Browser* new_browser = test->browser_list->get(2); + EXPECT_TRUE(WebContentsIsFastResized(new_browser)); + // The source window should also have fast resize set. + EXPECT_TRUE(WebContentsIsFastResized(test->browser())); + + // Now drag to target_tab_strip. + gfx::Point target_point(target_tab_strip->width() / 2, + target_tab_strip->height() / 2); + views::View::ConvertPointToScreen(target_tab_strip, &target_point); + ASSERT_TRUE(test->DragInputTo(target_point)); + + if (test->input_source() == INPUT_SOURCE_TOUCH) + ASSERT_TRUE(test->ReleaseInput()); + else + ASSERT_TRUE(test->ReleaseMouseAsync()); +} + +} // namespace + +// Tests that we use fast resize to resize the web contents of the dragged +// window and the source window during tab dragging process, and don't use fast +// resize after tab dragging ends. +IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, + FastResizeDuringDragging) { + TabStrip* tab_strip = GetTabStripForBrowser(browser()); + // Add another tab to browser(). + AddTabAndResetBrowser(browser()); + + // Create another browser. + Browser* browser2 = CreateAnotherWindowBrowserAndRelayout(); + TabStrip* tab_strip2 = GetTabStripForBrowser(browser2); + EXPECT_EQ(2u, browser_list->size()); + + EXPECT_FALSE(WebContentsIsFastResized(browser())); + EXPECT_FALSE(WebContentsIsFastResized(browser2)); + + // Move to the first tab and drag it enough so that it detaches, but not + // enough that it attaches to browser2. + gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); + ASSERT_TRUE(PressInput(tab_0_center)); + ASSERT_TRUE(DragInputToNotifyWhenDone( + tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), + base::BindOnce(&FastResizeDuringDraggingStep2, this, tab_strip, + tab_strip2))); + QuitWhenNotDragging(); + + EXPECT_FALSE(WebContentsIsFastResized(browser())); + EXPECT_FALSE(WebContentsIsFastResized(browser2)); +} + #endif // OS_CHROMEOS #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc b/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc index 56eef30ab..2a22a9e 100644 --- a/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc +++ b/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc
@@ -33,7 +33,7 @@ AuthenticatorTransport::kNearFieldCommunication, AuthenticatorTransport::kInternal, AuthenticatorTransport::kCloudAssistedBluetoothLowEnergy}; - model->StartFlow(std::move(transport_availability), base::nullopt); + model->StartFlow(std::move(transport_availability), base::nullopt, nullptr); // The dialog should immediately close as soon as it is displayed. if (name == "closed") {
diff --git a/chrome/browser/ui/webauthn/other_transports_menu_model.cc b/chrome/browser/ui/webauthn/other_transports_menu_model.cc index 2d07b69..9a9fdf4 100644 --- a/chrome/browser/ui/webauthn/other_transports_menu_model.cc +++ b/chrome/browser/ui/webauthn/other_transports_menu_model.cc
@@ -74,7 +74,14 @@ static_cast<AuthenticatorTransport>(command_id); DCHECK(dialog_model_); - dialog_model_->StartGuidedFlowForTransport(selected_transport); + bool pair_with_new_bluetooth_device = false; + if (selected_transport == AuthenticatorTransport::kBluetoothLowEnergy && + dialog_model_->current_step() == + AuthenticatorRequestDialogModel::Step::kBleActivate) { + pair_with_new_bluetooth_device = true; + } + dialog_model_->StartGuidedFlowForTransport(selected_transport, + pair_with_new_bluetooth_device); } void OtherTransportsMenuModel::OnModelDestroyed() {
diff --git a/chrome/browser/ui/webauthn/sheet_models.cc b/chrome/browser/ui/webauthn/sheet_models.cc index 9ea87ca7..f193ab2 100644 --- a/chrome/browser/ui/webauthn/sheet_models.cc +++ b/chrome/browser/ui/webauthn/sheet_models.cc
@@ -491,8 +491,10 @@ base::string16 AuthenticatorBlePinEntrySheetModel::GetStepTitle() const { const auto& authenticator_id = dialog_model()->selected_authenticator_id(); + DCHECK(authenticator_id); const auto* ble_authenticator = - dialog_model()->saved_authenticators().GetAuthenticator(authenticator_id); + dialog_model()->saved_authenticators().GetAuthenticator( + *authenticator_id); DCHECK(ble_authenticator); return l10n_util::GetStringFUTF16( IDS_WEBAUTHN_BLE_PIN_ENTRY_TITLE,
diff --git a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc index 22ee611..439b6fe 100644 --- a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
@@ -78,7 +78,14 @@ crostini::CrostiniSharePath::GetForProfile(profile_)->UnsharePath( crostini::kCrostiniDefaultVmName, base::FilePath(path), - base::DoNothing()); + base::BindOnce( + [](const std::string& path, bool result, std::string failure_reason) { + if (!result) { + LOG(ERROR) << "Error unsharing " << path << ": " + << failure_reason; + } + }, + path)); } } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index dfccf0d..c13e5a4 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -1174,6 +1174,7 @@ IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_MENU_FORGET}, {"networkAllowDataRoaming", IDS_SETTINGS_SETTINGS_NETWORK_ALLOW_DATA_ROAMING}, + {"networkAlwaysOnVpn", IDS_SETTINGS_INTERNET_NETWORK_ALWAYS_ON_VPN}, {"networkAutoConnect", IDS_SETTINGS_INTERNET_NETWORK_AUTO_CONNECT}, {"networkButtonActivate", IDS_SETTINGS_INTERNET_BUTTON_ACTIVATE}, {"networkButtonConfigure", IDS_SETTINGS_INTERNET_BUTTON_CONFIGURE}, @@ -1699,8 +1700,6 @@ {"syncSignInPromptWithNoAccount", IDS_SETTINGS_SYNC_SIGN_IN_PROMPT_WITH_NO_ACCOUNT}, #endif - {"syncUnifiedConsentToggleTitle", - IDS_SETTINGS_PEOPLE_SYNC_UNIFIED_CONSENT_TOGGLE_TITLE}, {"syncOverview", IDS_SETTINGS_SYNC_OVERVIEW}, {"syncDisabled", IDS_PROFILES_DICE_SYNC_DISABLED_TITLE}, {"syncDisabledByAdministrator", IDS_SIGNED_IN_WITH_SYNC_DISABLED},
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index 55c013d..1d85eee 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -266,10 +266,6 @@ "SyncSetupManageOtherPeople", base::BindRepeating(&PeopleHandler::HandleManageOtherPeople, base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "UnifiedConsentToggleChanged", - base::BindRepeating(&PeopleHandler::OnUnifiedConsentToggleChanged, - base::Unretained(this))); #if defined(OS_CHROMEOS) web_ui()->RegisterMessageCallback( "AttemptUserExit", @@ -841,15 +837,6 @@ #endif // !defined(OS_CHROMEOS) } -void PeopleHandler::OnUnifiedConsentToggleChanged(const base::ListValue* args) { - bool is_toggle_checked = args->GetList()[0].GetBool(); - if (!is_toggle_checked) { - unified_consent::metrics::RecordUnifiedConsentRevoked( - unified_consent::metrics::UnifiedConsentRevokeReason:: - kUserDisabledSettingsToggle); - } -} - void PeopleHandler::CloseSyncSetup() { // Stop a timer to handle timeout in waiting for checking network connection. engine_start_timer_.reset();
diff --git a/chrome/browser/ui/webui/settings/people_handler.h b/chrome/browser/ui/webui/settings/people_handler.h index 5cdcf65..dbf9e84 100644 --- a/chrome/browser/ui/webui/settings/people_handler.h +++ b/chrome/browser/ui/webui/settings/people_handler.h
@@ -179,7 +179,6 @@ #endif void HandleGetSyncStatus(const base::ListValue* args); void HandleManageOtherPeople(const base::ListValue* args); - void OnUnifiedConsentToggleChanged(const base::ListValue* args); #if !defined(OS_CHROMEOS) // Displays the GAIA login form.
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc index 6ad2734..ed0e79f 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -255,8 +255,8 @@ // Prime the account tracker with this combination of gaia id/display email. std::string account_id = - AccountTrackerServiceFactory::GetForProfile(profile_) - ->SeedAccountInfo(gaia_id_, email_); + AccountTrackerServiceFactory::GetForProfile(profile_)->SeedAccountInfo( + gaia_id_, email_); SigninManager* signin_manager = SigninManagerFactory::GetForProfile(profile_); std::string primary_email = @@ -324,9 +324,9 @@ } OneClickSigninSyncStarter::ConfirmationRequired confirmation_required = - confirm_untrusted_signin_ ? - OneClickSigninSyncStarter::CONFIRM_UNTRUSTED_SIGNIN : - OneClickSigninSyncStarter::CONFIRM_AFTER_SIGNIN; + confirm_untrusted_signin_ + ? OneClickSigninSyncStarter::CONFIRM_UNTRUSTED_SIGNIN + : OneClickSigninSyncStarter::CONFIRM_AFTER_SIGNIN; bool start_signin = !HandleCrossAccountError( result.refresh_token, confirmation_required, start_mode); @@ -421,7 +421,7 @@ } void InlineSigninHelper::OnClientOAuthFailure( - const GoogleServiceAuthError& error) { + const GoogleServiceAuthError& error) { if (handler_) handler_->HandleLoginError(error.ToString(), base::string16()); @@ -437,17 +437,14 @@ } InlineLoginHandlerImpl::InlineLoginHandlerImpl() - : confirm_untrusted_signin_(false), - weak_factory_(this) { -} + : confirm_untrusted_signin_(false), weak_factory_(this) {} InlineLoginHandlerImpl::~InlineLoginHandlerImpl() {} // This method is not called with webview sign in enabled. void InlineLoginHandlerImpl::DidFinishNavigation( content::NavigationHandle* navigation_handle) { - if (!web_contents() || - !navigation_handle->HasCommitted() || + if (!web_contents() || !navigation_handle->HasCommitted() || navigation_handle->IsErrorPage()) { return; } @@ -465,8 +462,7 @@ if (!navigation_handle->GetURL().is_empty()) { GURL origin(navigation_handle->GetURL().GetOrigin()); if (navigation_handle->GetURL().spec() != url::kAboutBlankURL && - origin != kGaiaExtOrigin && - !gaia::IsGaiaSignonRealm(origin)) { + origin != kGaiaExtOrigin && !gaia::IsGaiaSignonRealm(origin)) { confirm_untrusted_signin_ = true; } } @@ -487,29 +483,40 @@ signin_metrics::Reason reason = signin::GetSigninReasonForPromoURL(current_url); - const GURL& url = GaiaUrls::GetInstance()->embedded_signin_url(); - params.SetBoolean("isNewGaiaFlow", true); - params.SetString("clientId", - GaiaUrls::GetInstance()->oauth2_chrome_client_id()); - params.SetString("gaiaPath", url.path().substr(1)); - - std::string flow; - switch (reason) { - case signin_metrics::Reason::REASON_ADD_SECONDARY_ACCOUNT: - flow = "addaccount"; - break; - case signin_metrics::Reason::REASON_REAUTHENTICATION: - case signin_metrics::Reason::REASON_UNLOCK: - flow = "reauth"; - break; - case signin_metrics::Reason::REASON_FORCED_SIGNIN_PRIMARY_ACCOUNT: - flow = "enterprisefsi"; - break; - default: - flow = "signin"; - break; +#if defined(OS_WIN) + if (reason == signin_metrics::Reason::REASON_FETCH_LST_ONLY) { + std::string email_domain; + if (net::GetValueForKeyInQuery( + current_url, credential_provider::kEmailDomainSigninPromoParameter, + &email_domain)) { + params.SetString("emailDomain", email_domain); } - params.SetString("flow", flow); + } +#endif + + const GURL& url = GaiaUrls::GetInstance()->embedded_signin_url(); + params.SetBoolean("isNewGaiaFlow", true); + params.SetString("clientId", + GaiaUrls::GetInstance()->oauth2_chrome_client_id()); + params.SetString("gaiaPath", url.path().substr(1)); + + std::string flow; + switch (reason) { + case signin_metrics::Reason::REASON_ADD_SECONDARY_ACCOUNT: + flow = "addaccount"; + break; + case signin_metrics::Reason::REASON_REAUTHENTICATION: + case signin_metrics::Reason::REASON_UNLOCK: + flow = "reauth"; + break; + case signin_metrics::Reason::REASON_FORCED_SIGNIN_PRIMARY_ACCOUNT: + flow = "enterprisefsi"; + break; + default: + flow = "signin"; + break; + } + params.SetString("flow", flow); content::WebContentsObserver::Observe(contents); LogHistogramValue(signin_metrics::HISTOGRAM_SHOWN); @@ -629,8 +636,8 @@ InlineLoginHandlerImpl::FinishCompleteLoginParams::FinishCompleteLoginParams( const FinishCompleteLoginParams& other) = default; -InlineLoginHandlerImpl:: - FinishCompleteLoginParams::~FinishCompleteLoginParams() {} +InlineLoginHandlerImpl::FinishCompleteLoginParams:: + ~FinishCompleteLoginParams() {} // static void InlineLoginHandlerImpl::FinishCompleteLogin( @@ -666,9 +673,9 @@ bool switch_to_advanced = params.choose_what_to_sync && (access_point != signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS); - LogHistogramValue( - switch_to_advanced ? signin_metrics::HISTOGRAM_WITH_ADVANCED : - signin_metrics::HISTOGRAM_WITH_DEFAULTS); + LogHistogramValue(switch_to_advanced + ? signin_metrics::HISTOGRAM_WITH_ADVANCED + : signin_metrics::HISTOGRAM_WITH_DEFAULTS); CanOfferSigninType can_offer_for = CAN_OFFER_SIGNIN_FOR_ALL_ACCOUNTS; switch (reason) { @@ -762,8 +769,8 @@ } Browser* InlineLoginHandlerImpl::GetDesktopBrowser() { - Browser* browser = chrome::FindBrowserWithWebContents( - web_ui()->GetWebContents()); + Browser* browser = + chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()); if (!browser) browser = chrome::FindLastActiveWithProfile(Profile::FromWebUI(web_ui())); return browser;
diff --git a/chrome/browser/web_applications/extensions/BUILD.gn b/chrome/browser/web_applications/extensions/BUILD.gn index 920160c..0db631c 100644 --- a/chrome/browser/web_applications/extensions/BUILD.gn +++ b/chrome/browser/web_applications/extensions/BUILD.gn
@@ -12,8 +12,6 @@ "bookmark_app_installation_task.h", "bookmark_app_installer.cc", "bookmark_app_installer.h", - "bookmark_app_shortcut_installation_task.cc", - "bookmark_app_shortcut_installation_task.h", "bookmark_app_util.cc", "bookmark_app_util.h", "pending_bookmark_app_manager.cc",
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_installation_task_unittest.cc b/chrome/browser/web_applications/extensions/bookmark_app_installation_task_unittest.cc index 17dab74e..2580959 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_installation_task_unittest.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_installation_task_unittest.cc
@@ -24,7 +24,6 @@ #include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/components/web_app_data_retriever.h" #include "chrome/browser/web_applications/extensions/bookmark_app_installer.h" -#include "chrome/browser/web_applications/extensions/bookmark_app_shortcut_installation_task.h" #include "chrome/browser/web_applications/test/test_data_retriever.h" #include "chrome/common/web_application_info.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" @@ -180,91 +179,6 @@ DISALLOW_COPY_AND_ASSIGN(TestInstaller); }; -TEST_F(BookmarkAppInstallationTaskTest, ShortcutFromContents_Delete) { - auto task = std::make_unique<BookmarkAppShortcutInstallationTask>(profile()); - task->SetDataRetrieverForTesting( - std::make_unique<web_app::TestDataRetriever>(nullptr)); - - base::RunLoop run_loop; - task->InstallFromWebContents( - web_contents(), - base::BindOnce(&BookmarkAppInstallationTaskTest::OnInstallationTaskResult, - base::Unretained(this), run_loop.QuitClosure())); - task.reset(); - run_loop.RunUntilIdle(); - - // Shouldn't crash. -} - -TEST_F(BookmarkAppInstallationTaskTest, ShortcutFromContents_NoWebAppInfo) { - auto task = std::make_unique<BookmarkAppShortcutInstallationTask>(profile()); - task->SetDataRetrieverForTesting( - std::make_unique<web_app::TestDataRetriever>(nullptr)); - - base::RunLoop run_loop; - task->InstallFromWebContents( - web_contents(), - base::BindOnce(&BookmarkAppInstallationTaskTest::OnInstallationTaskResult, - base::Unretained(this), run_loop.QuitClosure())); - run_loop.Run(); - - EXPECT_FALSE(app_installed()); - EXPECT_EQ(web_app::InstallResultCode::kGetWebApplicationInfoFailed, - app_installation_result().code); -} - -TEST_F(BookmarkAppInstallationTaskTest, ShortcutFromContents_NoManifest) { - auto task = std::make_unique<BookmarkAppShortcutInstallationTask>(profile()); - - WebApplicationInfo info; - info.app_url = GURL(kWebAppUrl); - info.title = base::UTF8ToUTF16(kWebAppTitle); - task->SetDataRetrieverForTesting(std::make_unique<web_app::TestDataRetriever>( - std::make_unique<WebApplicationInfo>(std::move(info)))); - - auto installer = - std::make_unique<TestInstaller>(profile(), true /* succeeds */); - auto* installer_ptr = installer.get(); - task->SetInstallerForTesting(std::move(installer)); - - base::RunLoop run_loop; - task->InstallFromWebContents( - web_contents(), - base::BindOnce(&BookmarkAppInstallationTaskTest::OnInstallationTaskResult, - base::Unretained(this), run_loop.QuitClosure())); - run_loop.Run(); - - EXPECT_TRUE(app_installed()); - - const auto& installed_info = installer_ptr->web_app_info(); - EXPECT_EQ(info.app_url, installed_info.app_url); - EXPECT_EQ(info.title, installed_info.title); -} - -TEST_F(BookmarkAppInstallationTaskTest, - ShortcutFromContents_InstallationFails) { - auto task = std::make_unique<BookmarkAppShortcutInstallationTask>(profile()); - - WebApplicationInfo info; - info.app_url = GURL(kWebAppUrl); - info.title = base::UTF8ToUTF16(kWebAppTitle); - task->SetDataRetrieverForTesting(std::make_unique<web_app::TestDataRetriever>( - std::make_unique<WebApplicationInfo>(std::move(info)))); - task->SetInstallerForTesting( - std::make_unique<TestInstaller>(profile(), false /* succeeds */)); - - base::RunLoop run_loop; - task->InstallFromWebContents( - web_contents(), - base::BindOnce(&BookmarkAppInstallationTaskTest::OnInstallationTaskResult, - base::Unretained(this), run_loop.QuitClosure())); - run_loop.Run(); - - EXPECT_FALSE(app_installed()); - EXPECT_EQ(web_app::InstallResultCode::kFailedUnknownReason, - app_installation_result().code); -} - TEST_F(BookmarkAppInstallationTaskTest, WebAppOrShortcutFromContents_InstallationSucceeds) { const GURL app_url(kWebAppUrl);
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_shortcut_installation_task.cc b/chrome/browser/web_applications/extensions/bookmark_app_shortcut_installation_task.cc deleted file mode 100644 index b6d24133..0000000 --- a/chrome/browser/web_applications/extensions/bookmark_app_shortcut_installation_task.cc +++ /dev/null
@@ -1,103 +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/web_applications/extensions/bookmark_app_shortcut_installation_task.h" - -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/callback.h" -#include "chrome/browser/web_applications/components/web_app_constants.h" -#include "chrome/browser/web_applications/components/web_app_data_retriever.h" -#include "chrome/browser/web_applications/extensions/bookmark_app_installer.h" -#include "chrome/common/web_application_info.h" -#include "content/public/browser/browser_thread.h" - -namespace extensions { - -BookmarkAppShortcutInstallationTask::BookmarkAppShortcutInstallationTask( - Profile* profile) - : BookmarkAppInstallationTask( - profile, - // Pass an empty AppInfo since it doesn't influence the installation - // right now. - // TODO(crbug.com/864904): Take an AppInfo object once the installer - // can use the information. - web_app::PendingAppManager::AppInfo( - GURL(), - web_app::LaunchContainer::kTab, - web_app::InstallSource::kInternal)) {} - -BookmarkAppShortcutInstallationTask::~BookmarkAppShortcutInstallationTask() = - default; - -void BookmarkAppShortcutInstallationTask::InstallFromWebContents( - content::WebContents* web_contents, - ResultCallback callback) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - data_retriever().GetWebApplicationInfo( - web_contents, - base::BindOnce( - &BookmarkAppShortcutInstallationTask::OnGetWebApplicationInfo, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); -} - -void BookmarkAppShortcutInstallationTask::OnGetWebApplicationInfo( - ResultCallback result_callback, - std::unique_ptr<WebApplicationInfo> web_app_info) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!web_app_info) { - std::move(result_callback) - .Run(Result(web_app::InstallResultCode::kGetWebApplicationInfoFailed, - base::nullopt)); - return; - } - - // TODO(crbug.com/864904): Retrieve the Manifest before downloading icons. - - std::vector<GURL> icon_urls; - for (const auto& icon : web_app_info->icons) { - icon_urls.push_back(icon.url); - } - - data_retriever().GetIcons( - web_app_info->app_url, icon_urls, - base::BindOnce(&BookmarkAppShortcutInstallationTask::OnGetIcons, - weak_ptr_factory_.GetWeakPtr(), std::move(result_callback), - std::move(web_app_info))); -} - -void BookmarkAppShortcutInstallationTask::OnGetIcons( - ResultCallback result_callback, - std::unique_ptr<WebApplicationInfo> web_app_info, - std::vector<WebApplicationInfo::IconInfo> icons) { - web_app_info->icons = std::move(icons); - - // TODO(crbug.com/864904): Make this a WebContents observer and cancel the - // task if the WebContents has been destroyed. - installer().Install( - *web_app_info, - base::BindOnce(&BookmarkAppShortcutInstallationTask::OnInstalled, - weak_ptr_factory_.GetWeakPtr(), - std::move(result_callback))); -} - -void BookmarkAppShortcutInstallationTask::OnInstalled( - ResultCallback result_callback, - const std::string& app_id) { - if (app_id.empty()) { - std::move(result_callback) - .Run(Result(web_app::InstallResultCode::kFailedUnknownReason, - base::nullopt)); - return; - } - std::move(result_callback) - .Run(Result(web_app::InstallResultCode::kSuccess, app_id)); -} - -} // namespace extensions
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_shortcut_installation_task.h b/chrome/browser/web_applications/extensions/bookmark_app_shortcut_installation_task.h deleted file mode 100644 index 88646e9..0000000 --- a/chrome/browser/web_applications/extensions/bookmark_app_shortcut_installation_task.h +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_WEB_APPLICATIONS_EXTENSIONS_BOOKMARK_APP_SHORTCUT_INSTALLATION_TASK_H_ -#define CHROME_BROWSER_WEB_APPLICATIONS_EXTENSIONS_BOOKMARK_APP_SHORTCUT_INSTALLATION_TASK_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "base/callback.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/web_applications/extensions/bookmark_app_installation_task.h" -#include "chrome/common/web_application_info.h" - -class Profile; - -namespace content { -class WebContents; -} - -namespace extensions { - -// Subclass of BookmarkAppInstallationTask that exclusively installs -// BookmarkApp-based shortcuts. -class BookmarkAppShortcutInstallationTask : public BookmarkAppInstallationTask { - public: - // Constructs a task that will install a BookmarkApp-based shortcut for - // |profile|. - explicit BookmarkAppShortcutInstallationTask(Profile* profile); - ~BookmarkAppShortcutInstallationTask() override; - - virtual void InstallFromWebContents(content::WebContents* web_contents, - ResultCallback callback); - - private: - void OnGetWebApplicationInfo( - ResultCallback result_callback, - std::unique_ptr<WebApplicationInfo> web_app_info); - void OnGetIcons(ResultCallback result_callback, - std::unique_ptr<WebApplicationInfo> web_app_info, - std::vector<WebApplicationInfo::IconInfo> icons); - void OnInstalled(ResultCallback result_callback, const std::string& app_id); - - base::WeakPtrFactory<BookmarkAppShortcutInstallationTask> weak_ptr_factory_{ - this}; - - DISALLOW_COPY_AND_ASSIGN(BookmarkAppShortcutInstallationTask); -}; - -} // namespace extensions - -#endif // CHROME_BROWSER_WEB_APPLICATIONS_EXTENSIONS_BOOKMARK_APP_SHORTCUT_INSTALLATION_TASK_H_
diff --git a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc index f5fe5f5..9c6f2d3 100644 --- a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc +++ b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc
@@ -15,7 +15,6 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/components/web_app_constants.h" -#include "chrome/browser/web_applications/extensions/bookmark_app_shortcut_installation_task.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/web_contents.h" #include "extensions/browser/extension_prefs.h" @@ -103,6 +102,8 @@ base::Optional<bool> opt = IsExtensionPresentAndInstalled(extension_id.value()); if (!opt.has_value() || !opt.value()) { + LOG(WARNING) << "Couldn't uninstall app with url " << app_to_uninstall + << "; App doesn't exist"; callback.Run(app_to_uninstall, false); continue; } @@ -232,6 +233,9 @@ void PendingBookmarkAppManager::OnWebContentsLoadTimedOut() { web_contents_->Stop(); + LOG(ERROR) << "Error installing " + << current_task_and_callback_->task->app_info().url.spec(); + LOG(ERROR) << " page took too long to load."; Observe(nullptr); CurrentInstallationFinished(base::nullopt); } @@ -269,6 +273,9 @@ } if (validated_url != current_task_and_callback_->task->app_info().url) { + LOG(ERROR) << "Error installing " + << current_task_and_callback_->task->app_info().url.spec(); + LOG(ERROR) << " page redirected to " << validated_url.spec(); CurrentInstallationFinished(base::nullopt); return; } @@ -293,6 +300,9 @@ return; } + LOG(ERROR) << "Error installing " + << current_task_and_callback_->task->app_info().url.spec(); + LOG(ERROR) << " page failed to load."; Observe(nullptr); CurrentInstallationFinished(base::nullopt); }
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.cc b/chrome/browser/webauthn/authenticator_request_dialog_model.cc index 1d04a84..26b7d60 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model.cc +++ b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
@@ -15,6 +15,15 @@ namespace { +bool ShouldShowBlePairingUI( + bool previously_paired_with_bluetooth_authenticator, + bool pair_with_new_device_for_bluetooth_low_energy) { + if (pair_with_new_device_for_bluetooth_low_energy) + return true; + + return !previously_paired_with_bluetooth_authenticator; +} + // Attempts to auto-select the most likely transport that will be used to // service this request, or returns base::nullopt if unsure. base::Optional<device::FidoTransportProtocol> SelectMostLikelyTransport( @@ -87,7 +96,8 @@ void AuthenticatorRequestDialogModel::StartFlow( TransportAvailabilityInfo transport_availability, - base::Optional<device::FidoTransportProtocol> last_used_transport) { + base::Optional<device::FidoTransportProtocol> last_used_transport, + const base::ListValue* previously_paired_bluetooth_device_list) { DCHECK_EQ(current_step(), Step::kNotStarted); DCHECK(!transport_availability.disable_embedder_ui); @@ -97,6 +107,9 @@ available_transports_.emplace_back(transport); } + previously_paired_with_bluetooth_authenticator_ = + previously_paired_bluetooth_device_list && + !previously_paired_bluetooth_device_list->GetList().empty(); StartGuidedFlowForMostLikelyTransportOrShowTransportSelection(); } @@ -117,7 +130,8 @@ } void AuthenticatorRequestDialogModel::StartGuidedFlowForTransport( - AuthenticatorTransport transport) { + AuthenticatorTransport transport, + bool pair_with_new_device_for_bluetooth_low_energy) { DCHECK(current_step() == Step::kTransportSelection || current_step() == Step::kWelcomeScreen || current_step() == Step::kUsbInsertAndActivate || @@ -135,9 +149,15 @@ case AuthenticatorTransport::kInternal: StartTouchIdFlow(); break; - case AuthenticatorTransport::kBluetoothLowEnergy: - EnsureBleAdapterIsPoweredBeforeContinuingWithStep(Step::kBleActivate); + case AuthenticatorTransport::kBluetoothLowEnergy: { + Step next_step = ShouldShowBlePairingUI( + previously_paired_with_bluetooth_authenticator_, + pair_with_new_device_for_bluetooth_low_energy) + ? Step::kBleDeviceSelection + : Step::kBleActivate; + EnsureBleAdapterIsPoweredBeforeContinuingWithStep(next_step); break; + } case AuthenticatorTransport::kCloudAssistedBluetoothLowEnergy: EnsureBleAdapterIsPoweredBeforeContinuingWithStep(Step::kCableActivate); break; @@ -209,8 +229,9 @@ void AuthenticatorRequestDialogModel::FinishPairingWithPin( const base::string16& pin) { DCHECK_EQ(current_step(), Step::kBlePinEntry); + DCHECK(selected_authenticator_id_); const auto* selected_authenticator = - saved_authenticators_.GetAuthenticator(selected_authenticator_id_); + saved_authenticators_.GetAuthenticator(*selected_authenticator_id_); if (!selected_authenticator) { // TODO(hongjunchoi): Implement an error screen for error encountered when // pairing. @@ -221,28 +242,32 @@ DCHECK_EQ(device::FidoTransportProtocol::kBluetoothLowEnergy, selected_authenticator->transport()); ble_pairing_callback_.Run( - selected_authenticator_id_, base::UTF16ToUTF8(pin), + *selected_authenticator_id_, base::UTF16ToUTF8(pin), base::BindOnce(&AuthenticatorRequestDialogModel::OnPairingSuccess, - weak_factory_.GetWeakPtr(), selected_authenticator_id_), + weak_factory_.GetWeakPtr()), base::BindOnce(&AuthenticatorRequestDialogModel::OnPairingFailure, weak_factory_.GetWeakPtr())); SetCurrentStep(Step::kBleVerifying); } -void AuthenticatorRequestDialogModel::OnPairingSuccess( - base::StringPiece authenticator_id) { +void AuthenticatorRequestDialogModel::OnPairingSuccess() { DCHECK_EQ(current_step(), Step::kBleVerifying); + DCHECK(selected_authenticator_id_); auto* authenticator = - saved_authenticators_.GetAuthenticator(authenticator_id); - if (authenticator) + saved_authenticators_.GetAuthenticator(*selected_authenticator_id_); + if (!authenticator) return; authenticator->SetIsPaired(true /* is_paired */); + DCHECK(ble_device_paired_callback_); + ble_device_paired_callback_.Run(*selected_authenticator_id_); + DispatchRequestAsync(authenticator, base::TimeDelta()); } void AuthenticatorRequestDialogModel::OnPairingFailure() { DCHECK_EQ(current_step(), Step::kBleVerifying); + selected_authenticator_id_.reset(); SetCurrentStep(Step::kBleDeviceSelection); } @@ -357,10 +382,22 @@ void AuthenticatorRequestDialogModel::UpdateAuthenticatorReferenceId( base::StringPiece old_authenticator_id, std::string new_authenticator_id) { + // Bluetooth authenticator address may be changed during pairing process after + // the user chose device to pair during device selection UI. Thus, change + // |selected_authenticator_id_| as well. + if (selected_authenticator_id_ && + *selected_authenticator_id_ == old_authenticator_id) + selected_authenticator_id_ = new_authenticator_id; + saved_authenticators_.ChangeAuthenticatorId(old_authenticator_id, std::move(new_authenticator_id)); } +void AuthenticatorRequestDialogModel::SetBleDevicePairedCallback( + BleDevicePairedCallback ble_device_paired_callback) { + ble_device_paired_callback_ = std::move(ble_device_paired_callback); +} + void AuthenticatorRequestDialogModel::AddAuthenticator( const device::FidoAuthenticator& authenticator) { if (!authenticator.AuthenticatorTransport()) { @@ -369,10 +406,18 @@ // suppressed for this authenticator, so we can simply ignore it here. return; } - saved_authenticators_.AddAuthenticator(AuthenticatorReference( + + AuthenticatorReference authenticator_reference( authenticator.GetId(), authenticator.GetDisplayName(), *authenticator.AuthenticatorTransport(), authenticator.IsInPairingMode(), - authenticator.IsPaired())); + authenticator.IsPaired()); + + if (authenticator_reference.is_paired() && + authenticator_reference.transport() == + AuthenticatorTransport::kBluetoothLowEnergy) { + DispatchRequestAsync(&authenticator_reference, base::TimeDelta()); + } + saved_authenticators_.AddAuthenticator(std::move(authenticator_reference)); } void AuthenticatorRequestDialogModel::RemoveAuthenticator(
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.h b/chrome/browser/webauthn/authenticator_request_dialog_model.h index 1e42cd2..46b5226 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model.h +++ b/chrome/browser/webauthn/authenticator_request_dialog_model.h
@@ -14,6 +14,7 @@ #include "base/optional.h" #include "base/strings/string16.h" #include "base/strings/string_piece.h" +#include "base/values.h" #include "chrome/browser/webauthn/authenticator_reference.h" #include "chrome/browser/webauthn/authenticator_transport.h" #include "chrome/browser/webauthn/observable_authenticator_list.h" @@ -31,6 +32,7 @@ public: using RequestCallback = device::FidoRequestHandlerBase::RequestCallback; using BlePairingCallback = device::FidoRequestHandlerBase::BlePairingCallback; + using BleDevicePairedCallback = base::RepeatingCallback<void(std::string)>; using TransportAvailabilityInfo = device::FidoRequestHandlerBase::TransportAvailabilityInfo; @@ -128,8 +130,7 @@ return transport_availability()->is_ble_powered; } - const std::string& selected_authenticator_id() const { - DCHECK_EQ(Step::kBlePinEntry, current_step()); + const base::Optional<std::string>& selected_authenticator_id() const { return selected_authenticator_id_; } @@ -139,7 +140,8 @@ // Valid action when at step: kNotStarted. void StartFlow( TransportAvailabilityInfo transport_availability, - base::Optional<device::FidoTransportProtocol> last_used_transport); + base::Optional<device::FidoTransportProtocol> last_used_transport, + const base::ListValue* previously_paired_bluetooth_device_list); // Starts the UX flow. Tries to figure out the most likely transport to be // used, and starts the guided flow for that transport; or shows the manual @@ -155,7 +157,9 @@ // Valid action when at step: kNotStarted, kWelcomeScreen, // kTransportSelection, and steps where the other transports menu is shown, // namely, kUsbInsertAndActivate, kTouchId, kBleActivate, kCableActivate. - void StartGuidedFlowForTransport(AuthenticatorTransport transport); + void StartGuidedFlowForTransport( + AuthenticatorTransport transport, + bool pair_with_new_device_for_bluetooth_low_energy = false); // Ensures that the Bluetooth adapter is powered before proceeding to |step|. // -- If the adapter is powered, advanced directly to |step|. @@ -198,7 +202,7 @@ // Dispatches WebAuthN request to successfully paired Bluetooth authenticator. // // Valid action when at step: kBleVerifying. - void OnPairingSuccess(base::StringPiece authenticator_id); + void OnPairingSuccess(); // Returns to Bluetooth device selection modal. // @@ -259,6 +263,9 @@ void SetBluetoothAdapterPowerOnCallback( base::RepeatingClosure bluetooth_adapter_power_on_callback); + void SetBleDevicePairedCallback( + BleDevicePairedCallback ble_device_paired_callback); + void UpdateAuthenticatorReferenceId(base::StringPiece old_authenticator_id, std::string new_authenticator_id); void AddAuthenticator(const device::FidoAuthenticator& authenticator); @@ -290,6 +297,11 @@ // kBlePowerOnAutomatic. base::Optional<Step> next_step_once_ble_powered_; + // Determines whether Bluetooth device selection UI and pin pairing UI should + // be shown. We proceed directly to Step::kBleVerifying if the user has paired + // with a bluetooth authenticator previously. + bool previously_paired_with_bluetooth_authenticator_ = false; + base::ObserverList<Observer>::Unchecked observers_; // These fields are only filled out when the UX flow is started. @@ -304,11 +316,12 @@ // Represents the id of the Bluetooth authenticator that the user is trying to // connect to or conduct WebAuthN request to via the WebAuthN UI. - std::string selected_authenticator_id_; + base::Optional<std::string> selected_authenticator_id_; RequestCallback request_callback_; BlePairingCallback ble_pairing_callback_; base::RepeatingClosure bluetooth_adapter_power_on_callback_; + BleDevicePairedCallback ble_device_paired_callback_; base::WeakPtrFactory<AuthenticatorRequestDialogModel> weak_factory_;
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc index 53e6620..23253efe 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc +++ b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
@@ -20,6 +20,8 @@ namespace { +constexpr char kTestPairedAuthenticatorId[] = "ble:11-22-33-44"; + const base::flat_set<AuthenticatorTransport> kAllTransports = { AuthenticatorTransport::kUsbHumanInterfaceDevice, AuthenticatorTransport::kNearFieldCommunication, @@ -82,12 +84,17 @@ using Step = AuthenticatorRequestDialogModel::Step; using RequestType = ::device::FidoRequestHandlerBase::RequestType; - AuthenticatorRequestDialogModelTest() {} + AuthenticatorRequestDialogModelTest() { + test_paired_device_list_.Append( + std::make_unique<base::Value>(kTestPairedAuthenticatorId)); + } + ~AuthenticatorRequestDialogModelTest() override {} protected: base::test::ScopedTaskEnvironment task_environment_{ base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME}; + base::ListValue test_paired_device_list_; private: DISALLOW_COPY_AND_ASSIGN(AuthenticatorRequestDialogModelTest); @@ -264,7 +271,8 @@ test_case.has_touch_id_credential; AuthenticatorRequestDialogModel model; - model.StartFlow(std::move(transports_info), test_case.last_used_transport); + model.StartFlow(std::move(transports_info), test_case.last_used_transport, + &test_paired_device_list_); EXPECT_EQ(test_case.expected_first_step, model.current_step()); if (model.current_step() == Step::kTransportSelection) @@ -280,7 +288,8 @@ transports_info.available_transports = kAllTransports; AuthenticatorRequestDialogModel model; - model.StartFlow(std::move(transports_info), base::nullopt); + model.StartFlow(std::move(transports_info), base::nullopt, + &test_paired_device_list_); EXPECT_THAT(model.available_transports(), ::testing::UnorderedElementsAre( AuthenticatorTransport::kUsbHumanInterfaceDevice, @@ -297,7 +306,7 @@ EXPECT_CALL(mock_observer, OnStepTransition()); model.StartFlow(TransportAvailabilityInfo(), - AuthenticatorTransport::kInternal); + AuthenticatorTransport::kInternal, &test_paired_device_list_); EXPECT_EQ(Step::kErrorNoAvailableTransports, model.current_step()); testing::Mock::VerifyAndClearExpectations(&mock_observer); @@ -335,7 +344,8 @@ transports_info.available_transports = kAllTransportsWithoutCable; EXPECT_CALL(mock_observer, OnStepTransition()); - model.StartFlow(std::move(transports_info), base::nullopt); + model.StartFlow(std::move(transports_info), base::nullopt, + &test_paired_device_list_); EXPECT_EQ(Step::kTransportSelection, model.current_step()); testing::Mock::VerifyAndClearExpectations(&mock_observer); @@ -354,6 +364,35 @@ } } +TEST_F(AuthenticatorRequestDialogModelTest, BlePairingFlow) { + const struct { + AuthenticatorTransport transport; + const base::ListValue* paired_device_address_list; + Step expected_final_step; + } kTestCases[] = { + {AuthenticatorTransport::kBluetoothLowEnergy, nullptr, + Step::kBleDeviceSelection}, + {AuthenticatorTransport::kBluetoothLowEnergy, &test_paired_device_list_, + Step::kBleActivate}, + }; + + for (const auto test_case : kTestCases) { + TransportAvailabilityInfo transports_info; + transports_info.available_transports = {test_case.transport}; + transports_info.can_power_on_ble_adapter = true; + transports_info.is_ble_powered = true; + + BluetoothAdapterPowerOnCallbackReceiver power_receiver; + AuthenticatorRequestDialogModel model; + model.SetBluetoothAdapterPowerOnCallback(power_receiver.GetCallback()); + model.StartFlow(std::move(transports_info), base::nullopt, + test_case.paired_device_address_list); + EXPECT_EQ(test_case.expected_final_step, model.current_step()); + EXPECT_TRUE(model.ble_adapter_is_powered()); + EXPECT_FALSE(power_receiver.was_called()); + } +} + TEST_F(AuthenticatorRequestDialogModelTest, BleAdapaterAlreadyPowered) { const struct { AuthenticatorTransport transport; @@ -373,7 +412,8 @@ BluetoothAdapterPowerOnCallbackReceiver power_receiver; AuthenticatorRequestDialogModel model; model.SetBluetoothAdapterPowerOnCallback(power_receiver.GetCallback()); - model.StartFlow(std::move(transports_info), base::nullopt); + model.StartFlow(std::move(transports_info), base::nullopt, + &test_paired_device_list_); EXPECT_EQ(test_case.expected_final_step, model.current_step()); EXPECT_TRUE(model.ble_adapter_is_powered()); EXPECT_FALSE(power_receiver.was_called()); @@ -402,7 +442,8 @@ AuthenticatorRequestDialogModel model; model.AddObserver(&mock_observer); model.SetBluetoothAdapterPowerOnCallback(power_receiver.GetCallback()); - model.StartFlow(std::move(transports_info), base::nullopt); + model.StartFlow(std::move(transports_info), base::nullopt, + &test_paired_device_list_); EXPECT_EQ(Step::kBlePowerOnManual, model.current_step()); EXPECT_FALSE(model.ble_adapter_is_powered()); @@ -441,7 +482,8 @@ BluetoothAdapterPowerOnCallbackReceiver power_receiver; AuthenticatorRequestDialogModel model; model.SetBluetoothAdapterPowerOnCallback(power_receiver.GetCallback()); - model.StartFlow(std::move(transports_info), base::nullopt); + model.StartFlow(std::move(transports_info), base::nullopt, + &test_paired_device_list_); EXPECT_EQ(Step::kBlePowerOnAutomatic, model.current_step()); @@ -478,7 +520,8 @@ AuthenticatorTransport::kInternal, false /* is_in_pairing_mode */, false /* is_paired */)); - model.StartFlow(std::move(transports_info), base::nullopt); + model.StartFlow(std::move(transports_info), base::nullopt, + &test_paired_device_list_); EXPECT_EQ(AuthenticatorRequestDialogModel::Step::kTransportSelection, model.current_step()); EXPECT_EQ(0, num_called);
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc index bd66107..e19347319d 100644 --- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc +++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -150,6 +150,10 @@ transient_dialog_model_holder_->SetBluetoothAdapterPowerOnCallback( bluetooth_adapter_power_on_callback); transient_dialog_model_holder_->SetBlePairingCallback(ble_pairing_callback); + transient_dialog_model_holder_->SetBleDevicePairedCallback( + base::BindRepeating( + &ChromeAuthenticatorRequestDelegate::AddFidoBleDeviceToPairedList, + weak_ptr_factory_.GetWeakPtr())); weak_dialog_model_ = transient_dialog_model_holder_.get(); weak_dialog_model_->AddObserver(this); @@ -258,6 +262,22 @@ Profile::FromBrowserContext(browser_context())->GetPrefs(); prefs->SetString(kWebAuthnLastTransportUsedPrefName, device::ToString(transport)); + + if (!weak_dialog_model_) + return; + + // We already invoke AddFidoBleDeviceToPairedList() on + // AuthenticatorRequestDialogModel::OnPairingSuccess(). We invoke the function + // here once more to take into account the case when user pairs Bluetooth + // authenticator separately via system OS rather than using Chrome WebAuthn + // UI. AddFidoBleDeviceToPairedList() handles the case when duplicate + // authenticator id is being stored. + const auto& selected_bluetooth_authenticator_id = + weak_dialog_model_->selected_authenticator_id(); + if (transport == device::FidoTransportProtocol::kBluetoothLowEnergy && + selected_bluetooth_authenticator_id) { + AddFidoBleDeviceToPairedList(*selected_bluetooth_authenticator_id); + } } void ChromeAuthenticatorRequestDelegate::OnTransportAvailabilityEnumerated( @@ -272,7 +292,8 @@ return; DCHECK(weak_dialog_model_); - weak_dialog_model_->StartFlow(std::move(data), GetLastTransportUsed()); + weak_dialog_model_->StartFlow(std::move(data), GetLastTransportUsed(), + GetPreviouslyPairedFidoBleDeviceIds()); DCHECK(transient_dialog_model_holder_); ShowAuthenticatorRequestDialog( @@ -283,17 +304,18 @@ bool ChromeAuthenticatorRequestDelegate::EmbedderControlsAuthenticatorDispatch( const device::FidoAuthenticator& authenticator) { - // TODO(hongjunchoi): Change this so that requests for BLE authenticators - // are not dispatched immediately if WebAuthN UI is enabled. if (!IsWebAuthnUiEnabled()) return false; - // On macOS, a native dialog is shown for the Touch ID authenticator // immediately after dispatch to that authenticator. This dialog must not // be triggered before Chrome's WebAuthn UI has advanced accordingly. - return authenticator.AuthenticatorTransport() && - *authenticator.AuthenticatorTransport() == - device::FidoTransportProtocol::kInternal; + // Also, connection to Bluetooth authenticators should not be established + // before user explicitly chooses to use a BLE device as it can trigger + // OS native pairing UI. + const auto& transport = authenticator.AuthenticatorTransport(); + return transport && + (*transport == device::FidoTransportProtocol::kInternal || + *transport == device::FidoTransportProtocol::kBluetoothLowEnergy); } void ChromeAuthenticatorRequestDelegate::FidoAuthenticatorAdded( @@ -358,19 +380,21 @@ } void ChromeAuthenticatorRequestDelegate::AddFidoBleDeviceToPairedList( - std::string device_address) { + std::string ble_authenticator_id) { ListPrefUpdate update( Profile::FromBrowserContext(browser_context())->GetPrefs(), kWebAuthnBlePairedMacAddressesPrefName); bool already_contains_address = std::any_of( - update->begin(), update->end(), [&device_address](const auto& value) { - return value.is_string() && value.GetString() == device_address; + update->begin(), update->end(), + [&ble_authenticator_id](const auto& value) { + return value.is_string() && value.GetString() == ble_authenticator_id; }); if (already_contains_address) return; - update->Append(std::make_unique<base::Value>(std::move(device_address))); + update->Append( + std::make_unique<base::Value>(std::move(ble_authenticator_id))); } base::Optional<device::FidoTransportProtocol> @@ -382,7 +406,7 @@ } const base::ListValue* -ChromeAuthenticatorRequestDelegate::GetPreviouslyPairedFidoBleDeviceAddresses() +ChromeAuthenticatorRequestDelegate::GetPreviouslyPairedFidoBleDeviceIds() const { PrefService* prefs = Profile::FromBrowserContext(browser_context())->GetPrefs();
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h index 680c8be..10cce970 100644 --- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h +++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
@@ -103,9 +103,9 @@ void OnModelDestroyed() override; void OnCancelRequest() override; - void AddFidoBleDeviceToPairedList(std::string device_address); + void AddFidoBleDeviceToPairedList(std::string ble_authenticator_id); base::Optional<device::FidoTransportProtocol> GetLastTransportUsed() const; - const base::ListValue* GetPreviouslyPairedFidoBleDeviceAddresses() const; + const base::ListValue* GetPreviouslyPairedFidoBleDeviceIds() const; bool IsWebAuthnUiEnabled() const; content::RenderFrameHost* const render_frame_host_;
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate_unittest.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate_unittest.cc index b05df348..c724749 100644 --- a/chrome/browser/webauthn/chrome_authenticator_request_delegate_unittest.cc +++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate_unittest.cc
@@ -31,14 +31,13 @@ ChromeAuthenticatorRequestDelegate delegate(main_rfh()); - auto* const address_list = - delegate.GetPreviouslyPairedFidoBleDeviceAddresses(); + auto* const address_list = delegate.GetPreviouslyPairedFidoBleDeviceIds(); ASSERT_TRUE(address_list); EXPECT_TRUE(address_list->empty()); delegate.AddFidoBleDeviceToPairedList(kTestPairedDeviceAddress); const auto* updated_address_list = - delegate.GetPreviouslyPairedFidoBleDeviceAddresses(); + delegate.GetPreviouslyPairedFidoBleDeviceIds(); ASSERT_TRUE(updated_address_list); ASSERT_EQ(1u, updated_address_list->GetSize()); @@ -48,13 +47,13 @@ delegate.AddFidoBleDeviceToPairedList(kTestPairedDeviceAddress); const auto* address_list_with_duplicate_address_added = - delegate.GetPreviouslyPairedFidoBleDeviceAddresses(); + delegate.GetPreviouslyPairedFidoBleDeviceIds(); ASSERT_TRUE(address_list_with_duplicate_address_added); EXPECT_EQ(1u, address_list_with_duplicate_address_added->GetSize()); delegate.AddFidoBleDeviceToPairedList(kTestPairedDeviceAddress2); const auto* address_list_with_two_addresses = - delegate.GetPreviouslyPairedFidoBleDeviceAddresses(); + delegate.GetPreviouslyPairedFidoBleDeviceIds(); ASSERT_TRUE(address_list_with_two_addresses); ASSERT_EQ(2u, address_list_with_two_addresses->GetSize());
diff --git a/chrome/chrome_cleaner/components/system_report_component.cc b/chrome/chrome_cleaner/components/system_report_component.cc index 8fab3a6..fcdb5e8 100644 --- a/chrome/chrome_cleaner/components/system_report_component.cc +++ b/chrome/chrome_cleaner/components/system_report_component.cc
@@ -32,7 +32,7 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/synchronization/waitable_event.h" -#include "base/threading/thread_restrictions.h" +#include "base/threading/scoped_blocking_call.h" #include "base/time/time.h" #include "base/values.h" #include "base/win/registry.h" @@ -698,9 +698,8 @@ DCHECK(json_parser); // TODO(proberge): Temporarily allowing syncing to avoid crashes in debug // mode. This isn't catastrophic since the cleanup tool doesn't have a UI and - // the system report is collected at the end of the process. We also assert - // blocking is allowed here since it will block the thread. - base::AssertBlockingAllowedDeprecated(); + // the system report is collected at the end of the process. + base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK); base::ScopedAllowBaseSyncPrimitivesForTesting allow_sync; ReportForcelistExtensions();
diff --git a/chrome/common/available_offline_content.mojom b/chrome/common/available_offline_content.mojom index b50e636..d14cd7f 100644 --- a/chrome/common/available_offline_content.mojom +++ b/chrome/common/available_offline_content.mojom
@@ -67,7 +67,7 @@ // Returns some available pieces of content from downloads. If not there's not // enough available content deemed interesting, the returned array will be // empty. - List() => (array<AvailableOfflineContent> out); + List() => (bool list_visible_by_prefs, array<AvailableOfflineContent> out); // Returns a summary of available offline content. If not there's not enough // available content deemed interesting, the returned summary will be empty. Summarize() => (AvailableOfflineContentSummary out); @@ -75,4 +75,7 @@ LaunchItem(string item_id, string name_space); // Opens the downloads page to view all offline content. LaunchDownloadsPage(bool open_prefetched_articles_tab); + // Communicates to the browser the user changed the visibility of the + // offline content list. + ListVisibilityChanged(bool is_visible); };
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index d189a9a..f6ec9cee 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json
@@ -461,7 +461,18 @@ }, "webcamPrivate": { "channel": "stable", - "extension_types": ["extension", "platform_app"] + "extension_types": ["extension", "platform_app"], + "whitelist": [ + "E703483CEF33DEC18B4B6DD84B5C776FB9182BDB", // http://crbug.com/891460 + "A3BC37E2148AC4E99BE4B16AF9D42DD1E592BBBE", // http://crbug.com/891460 + "1C93BD3CF875F4A73C0B2A163BB8FBDA8B8B3D80", // http://crbug.com/891460 + "307E96539209F95A1A8740C713E6998A73657D96", // http://crbug.com/891460 + "4F25792AF1AA7483936DE29C07806F203C7170A0", // http://crbug.com/891460 + "BD8781D757D830FC2E85470A1B6E8A718B7EE0D9", // http://crbug.com/891460 + "4AC2B6C63C6480D150DFDA13E4A5956EB1D0DDBB", // http://crbug.com/891460 + "81986D4F846CEDDDB962643FA501D1780DD441BB", // http://crbug.com/891460 + "A9A9FC0228ADF541F0334F22BEFB8F9C245B21D7" // http://crbug.com/891460 + ] }, "networking.castPrivate": { "channel": "stable",
diff --git a/chrome/common/extensions/api/automation.idl b/chrome/common/extensions/api/automation.idl index 674c0d8e..0985048e 100644 --- a/chrome/common/extensions/api/automation.idl +++ b/chrome/common/extensions/api/automation.idl
@@ -290,6 +290,7 @@ doDefault, focus, getImageData, + getTextLocation, hitTest, increment, loadInlineTextBoxes, @@ -488,6 +489,8 @@ // Callback called for actions with a response. callback PerformActionCallback = void(boolean result); callback PerformActionCallbackWithNode = void(AutomationNode node); + callback BoundsForRangeCallback = void(Rect bounds); + dictionary CustomAction { long id; @@ -514,11 +517,12 @@ // screen coordinates. Rect? location; - // Computes the bounding box of a subrange of this node in global screen - // coordinates. Returns the same as |location| if range information - // is not available. The start and end indices are zero-based offsets - // into the node's "name" string attribute. - static Rect boundsForRange(long startIndex, long endIndex); + // Determines the location of the text within the node specified by + // |startIndex| and |endIndex|, inclusively. Invokes |callback| with the + // bounding rectangle, in screen coordinates. |callback| can be invoked + // either synchronously or asynchronously. + static void boundsForRange(long startIndex, long endIndex, + BoundsForRangeCallback callback); // The location (as a bounding box) of this node in global screen // coordinates without applying any clipping from ancestors.
diff --git a/chrome/common/extensions/api/automation_internal.idl b/chrome/common/extensions/api/automation_internal.idl index 115a045..ce1eb38 100644 --- a/chrome/common/extensions/api/automation_internal.idl +++ b/chrome/common/extensions/api/automation_internal.idl
@@ -31,6 +31,17 @@ long actionRequestID; }; + dictionary AXTextLocationParams { + DOMString treeID; + long nodeID; + boolean result; + long left; + long top; + long width; + long height; + long requestID; + }; + // Actions internally used by automation. enum ActionTypePrivate { resumeMedia, @@ -101,6 +112,12 @@ DOMString eventToFire; }; + // Arguments for getTextLocation action. + dictionary GetTextLocationDataParams { + long startIndex; + long endIndex; + }; + // Returns the accessibility tree id of the web contents who's accessibility // was enabled using enableTab(). callback EnableTabCallback = void(DOMString tree_id); @@ -139,6 +156,8 @@ static void onAccessibilityTreeDestroyed(DOMString treeID); + static void onGetTextLocationResult(AXTextLocationParams params); + static void onTreeChange(long observerID, DOMString treeID, long nodeID,
diff --git a/chrome/common/extensions/api/cryptotoken_private.idl b/chrome/common/extensions/api/cryptotoken_private.idl index 99c2e3f6..e2e8571 100644 --- a/chrome/common/extensions/api/cryptotoken_private.idl +++ b/chrome/common/extensions/api/cryptotoken_private.idl
@@ -10,8 +10,7 @@ // the FIDO spec</a></p> namespace cryptotokenPrivate { - // Callback for appId check - callback AppIdCallback = void(boolean result); + callback BooleanCallback = void(boolean result); dictionary CanAppIdGetAttestationOptions { // The AppId (see definition, above) that was used in the registration @@ -33,7 +32,7 @@ // is the appId being asserted by the origin. static void canOriginAssertAppId(DOMString securityOrigin, DOMString appIdUrl, - AppIdCallback callback); + BooleanCallback callback); // Checks whether the given appId is specified in the // SecurityKeyPermitAttestation policy. This causes a signal to be sent to @@ -41,13 +40,16 @@ // certificate may be used. Without that signal, the token is required to // use its batch attestation certificate. static void isAppIdHashInEnterpriseContext(ArrayBuffer appIdHash, - AppIdCallback callback); + BooleanCallback callback); // Checks whether the given appId may receive attestation data that // identifies the token. If not, the attestation from the token must be // substituted with a randomly generated certificate since webauthn and U2F // require that some attestation be provided. static void canAppIdGetAttestation(CanAppIdGetAttestationOptions options, - AppIdCallback callback); + BooleanCallback callback); + + // Checks whether Cryptotoken can proxy the request through to WebAuthn. + static void canProxyToWebAuthn(BooleanCallback callback); }; };
diff --git a/chrome/common/extensions/docs/templates/intros/webRequest.html b/chrome/common/extensions/docs/templates/intros/webRequest.html index 9c0617d..b6e67e5 100644 --- a/chrome/common/extensions/docs/templates/intros/webRequest.html +++ b/chrome/common/extensions/docs/templates/intros/webRequest.html
@@ -1,9 +1,10 @@ <h2 id="manifest">Manifest</h2> <p>You must declare the "webRequest" permission in the <a href="manifest">extension manifest</a> to use the web request -API, along with <a href="declare_permissions">host permissions</a> -for any hosts whose network requests you want to access. If you want to -use the web request API in a blocking fashion, you need to request +API, along with the necessary +<a href="declare_permissions">host permissions</a>. To intercept a request, the +extension needs to have access to both the requested URL and its initiator. If +you want to use the web request API in a blocking fashion, you need to request the "webRequestBlocking" permission in addition. For example:</p> <pre data-filename="manifest.json"> @@ -157,6 +158,12 @@ Redirects are <b>not supported</b> for WebSocket requests. </p> +<p> +<span class="availability">Starting from Chrome 72</span>, an extension will be +able to intercept a request only if it has host permissions to both the +requested URL and the request initiator. +</p> + <h2 id="concepts">Concepts</h2> <p>As the following sections explain, events in the web request API use request
diff --git a/chrome/common/trace_event_args_whitelist.cc b/chrome/common/trace_event_args_whitelist.cc index 81dcd1f..d859dd4b 100644 --- a/chrome/common/trace_event_args_whitelist.cc +++ b/chrome/common/trace_event_args_whitelist.cc
@@ -18,13 +18,13 @@ const char* const* arg_name_filter; }; +const char* const kBaseAllowedArgs[] = {"blocking_type", nullptr}; const char* const kGPUAllowedArgs[] = {nullptr}; const char* const kInputLatencyAllowedArgs[] = {"data", nullptr}; const char* const kMemoryDumpAllowedArgs[] = {"dumps", nullptr}; const char* const kV8GCAllowedArgs[] = {"num_items", "num_tasks", nullptr}; const WhitelistEntry kEventArgsWhitelist[] = { - {"browser", "KeyedServiceFactory::GetServiceForContext", nullptr}, {"__metadata", "thread_name", nullptr}, {"__metadata", "process_name", nullptr}, {"__metadata", "process_uptime_seconds", nullptr}, @@ -32,6 +32,8 @@ {"__metadata", "chrome_library_module", nullptr}, {"__metadata", "stackFrames", nullptr}, {"__metadata", "typeNames", nullptr}, + {"base", "*", kBaseAllowedArgs}, + {"browser", "KeyedServiceFactory::GetServiceForContext", nullptr}, {"GPU", "*", kGPUAllowedArgs}, {"ipc", "GpuChannelHost::Send", nullptr}, {"ipc", "SyncChannel::Send", nullptr},
diff --git a/chrome/credential_provider/DEPS b/chrome/credential_provider/DEPS index 798ef25..4be0516a 100644 --- a/chrome/credential_provider/DEPS +++ b/chrome/credential_provider/DEPS
@@ -1,6 +1,12 @@ include_rules = [ "+chrome/common", + "+chrome/installer/launcher_support", "+chrome/installer/util", "+google_apis", ] +specific_include_rules = { + "gcp_gls_output_unittest\.cc": [ + "+chrome/browser/ui/startup/credential_provider_signin_dialog_win_test_data.h", + ] +} \ No newline at end of file
diff --git a/chrome/credential_provider/common/gcp_strings.cc b/chrome/credential_provider/common/gcp_strings.cc index bf1d7eb..dd91f6c 100644 --- a/chrome/credential_provider/common/gcp_strings.cc +++ b/chrome/credential_provider/common/gcp_strings.cc
@@ -45,5 +45,8 @@ // Chrome is being opened to show the credential provider logon page. This // page is always shown in incognito mode. const char kGcpwSigninSwitch[] = "gcpw-signin"; +const char kEmailDomainSwitch[] = "email-domain"; + +const char kEmailDomainSigninPromoParameter[] = "emailDomain"; } // namespace credential_provider
diff --git a/chrome/credential_provider/common/gcp_strings.h b/chrome/credential_provider/common/gcp_strings.h index 78ac46c..eb7f8e6 100644 --- a/chrome/credential_provider/common/gcp_strings.h +++ b/chrome/credential_provider/common/gcp_strings.h
@@ -39,7 +39,12 @@ extern const wchar_t kRegUpdaterClientStateAppPath[]; extern const wchar_t kRegUpdaterClientsAppPath[]; +// These are command line switches passed to chrome to start it as a process +// used as a logon stub. extern const char kGcpwSigninSwitch[]; +extern const char kEmailDomainSwitch[]; + +extern const char kEmailDomainSigninPromoParameter[]; } // namespace credential_provider
diff --git a/chrome/credential_provider/gaiacp/BUILD.gn b/chrome/credential_provider/gaiacp/BUILD.gn index f9e5adfc..ea557c41 100644 --- a/chrome/credential_provider/gaiacp/BUILD.gn +++ b/chrome/credential_provider/gaiacp/BUILD.gn
@@ -82,6 +82,7 @@ ":gaia_credential_provider_idl", ":resources", "//chrome/common:version_header", + "//chrome/installer/launcher_support", ] }
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base.cc b/chrome/credential_provider/gaiacp/gaia_credential_base.cc index b2c73567..f8a3ee75 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_base.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_base.cc
@@ -10,8 +10,10 @@ #include <algorithm> #include <memory> +#include "base/callback_helpers.h" #include "base/command_line.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/path_service.h" @@ -30,6 +32,7 @@ #include "chrome/credential_provider/gaiacp/reg_utils.h" #include "chrome/credential_provider/gaiacp/scoped_lsa_policy.h" #include "chrome/credential_provider/gaiacp/scoped_user_profile.h" +#include "chrome/installer/launcher_support/chrome_launcher_support.h" #include "google_apis/gaia/gaia_auth_util.h" #include "google_apis/google_api_keys.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" @@ -118,18 +121,20 @@ DCHECK(result); DCHECK(status_text); - // Buffers used to accumulate output from UI. + // Buffer used to accumulate output from UI. const int kBufferSize = 4096; - static char stdout_buffer[kBufferSize]; - static char stderr_buffer[kBufferSize]; + std::vector<char> output_buffer(kBufferSize, '\0'); + base::ScopedClosureRunner zero_buffer_on_exit( + base::BindOnce(base::IgnoreResult(&RtlSecureZeroMemory), + &output_buffer[0], kBufferSize)); DWORD exit_code; HRESULT hr = WaitForProcess(uiprocinfo->procinfo.process_handle(), uiprocinfo->parent_handles, &exit_code, - stdout_buffer, stderr_buffer, kBufferSize); - // stdout contains sensitive information like the password. Don't log it. - LOGFN(INFO) << "exit_code=" << exit_code - << " stderr: " << stderr_buffer; + &output_buffer[0], kBufferSize); + // output_buffer contains sensitive information like the password. Don't log + // it. + LOGFN(INFO) << "exit_code=" << exit_code; // If the UI process did not complete successfully, nothing more to do. if (exit_code == kUiecEMailMissmatch) { @@ -140,8 +145,8 @@ return E_ABORT; } - std::unique_ptr<base::Value> parsed( - base::JSONReader::Read(stdout_buffer, base::JSON_ALLOW_TRAILING_COMMAS)); + std::unique_ptr<base::Value> parsed(base::JSONReader::Read( + &output_buffer[0], base::JSON_ALLOW_TRAILING_COMMAS)); if (!parsed || !parsed->is_dict()) { LOGFN(ERROR) << "Could not parse data from logon UI"; *status_text = @@ -310,9 +315,9 @@ bool save_password = true; base::string16 fullname(GetStringResource(IDS_GAIA_ACCOUNT_FULLNAME)); base::string16 comment(GetStringResource(IDS_GAIA_ACCOUNT_COMMENT)); - hr = CreateNewUser(manager, kGaiaAccountName, password, fullname.c_str(), - comment.c_str(), /*add_to_users_group=*/false, - &sid_string); + hr = + CreateNewUser(manager, kGaiaAccountName, password, fullname.c_str(), + comment.c_str(), /*add_to_users_group=*/false, &sid_string); if (hr == HRESULT_FROM_WIN32(NERR_UserExists)) { // If CreateNewUser() found an existing user, the password was not changed. // Consider this a success but don't save the newly generated password @@ -476,45 +481,35 @@ DCHECK(email); DCHECK(command_line); - // Get the application name. - - base::FilePath install_path; - HRESULT hr = GetInstallDirectory(&install_path); - if (FAILED(hr)) { - LOGFN(ERROR) << "GetInstallDirectory hr=" << putHR(hr); - return hr; + base::FilePath chrome_path = + chrome_launcher_support::GetChromePathForInstallationLevel( + chrome_launcher_support::SYSTEM_LEVEL_INSTALLATION, false); + if (chrome_path.empty()) { + LOGFN(ERROR) << "No path to chrome.exe could be found."; + return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); } - // TODO(crbug.com/887444): Replace this with path to chrome. - command_line->SetProgram( - install_path.Append( - FILE_PATH_LITERAL("weblogin-win32-ia32\\weblogin.exe"))); + command_line->SetProgram(chrome_path); LOGFN(INFO) << "App exe: " << command_line->GetProgram().value(); - // Get the command line. - // If an email pattern is specified, pass it to the webui. wchar_t email_pattern[64]; ULONG length = base::size(email_pattern); - hr = GetGlobalFlag(L"ep", email_pattern, &length); + HRESULT hr = GetGlobalFlag(L"ep", email_pattern, &length); if (FAILED(hr)) email_pattern[0] = 0; + if (*email_pattern) + command_line->AppendSwitchNative(kEmailDomainSwitch, email_pattern); - // TODO: these arguments will not be needed once the electron app is replaced - // with chrome. - std::string id = google_apis::GetOAuth2ClientID(google_apis::CLIENT_MAIN); - std::string secret = - google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_MAIN); + command_line->AppendSwitchNative(kGcpwSigninSwitch, email); - if (wcslen(email_pattern) > 0) - command_line->AppendSwitchNative("pattern", email_pattern); - - if (email && wcslen(email) > 0) - command_line->AppendSwitchNative("email", email); - - command_line->AppendSwitchASCII("client-id", id); - command_line->AppendSwitchASCII("client-secret", secret); + // The gpu process will be running on an alternative desktop since it does not + // have access to the winlogon desktop. This mitigation is required merely to + // be able to start Chrome during winlogon. However, In this scenario no gpu + // rendering can be done to the screen, so all the gpu features need to be + // disabled. (crbug.com/904902) + command_line->AppendSwitch("disable-gpu"); LOGFN(INFO) << "Command line: " << command_line->GetCommandLineString(); return S_OK; @@ -637,13 +632,7 @@ HRESULT CGaiaCredentialBase::SetDeselected(void) { LOGFN(INFO); - // Terminate login UI process if started. This is best effort since it may - // have already terminated. - if (logon_ui_process_ != INVALID_HANDLE_VALUE) { - LOGFN(INFO) << "Attempting to kill logon UI process"; - ::TerminateProcess(logon_ui_process_, kUiecKilled); - logon_ui_process_ = INVALID_HANDLE_VALUE; - } + TerminateLogonProcess(); // Do not reset the internal state here, otherwise auto-logon will not work. @@ -937,8 +926,14 @@ DCHECK(uiprocinfo); ScopedStartupInfo startupinfo(kDesktopFullName); - HRESULT hr = InitializeStdHandles(CommDirection::kChildToParentOnly, - &startupinfo, &uiprocinfo->parent_handles); + + // Only create a stdout pipe for the logon stub process. On some machines + // Chrome will not startup properly when also given a stderror pipe due + // to access restrictions. For the purposes of the credential provider + // only the output of stdout matters. + HRESULT hr = + InitializeStdHandles(CommDirection::kChildToParentOnly, kStdOutput, + &startupinfo, &uiprocinfo->parent_handles); if (FAILED(hr)) { LOGFN(ERROR) << "InitializeStdHandles hr=" << putHR(hr); return hr; @@ -996,8 +991,9 @@ ScopedStartupInfo startupinfo; StdParentHandles parent_handles; - HRESULT hr = InitializeStdHandles(CommDirection::kParentToChildOnly, - &startupinfo, &parent_handles); + HRESULT hr = + InitializeStdHandles(CommDirection::kParentToChildOnly, kAllStdHandles, + &startupinfo, &parent_handles); if (FAILED(hr)) { LOGFN(ERROR) << "InitializeStdHandles hr=" << putHR(hr); *status_text = AllocErrorString(IDS_INTERNAL_ERROR); @@ -1230,6 +1226,16 @@ return S_OK; } +void CGaiaCredentialBase::TerminateLogonProcess() { + // Terminate login UI process if started. This is best effort since it may + // have already terminated. + if (logon_ui_process_ != INVALID_HANDLE_VALUE) { + LOGFN(INFO) << "Attempting to kill logon UI process"; + ::TerminateProcess(logon_ui_process_, kUiecKilled); + logon_ui_process_ = INVALID_HANDLE_VALUE; + } +} + HRESULT CGaiaCredentialBase::FinishAuthentication(BSTR username, BSTR password, BSTR fullname, @@ -1257,6 +1263,12 @@ if (status_text != nullptr) result_status_text_.assign(OLE2CW(status_text)); + // If the user cancelled out of the logon, the process may be already + // terminated, but if the handle to the process is still valid the + // credential provider will not start a new GLS process when requested so + // try to terminate the logon process now and clear the handle. + TerminateLogonProcess(); + // TODO(rogerta): for some reason the error info saved by ReportError() // never gets used because ReportResult() is never called by winlogon.exe // when the logon fails. Not sure what I'm doing wrong here. This @@ -1268,4 +1280,3 @@ } } // namespace credential_provider -
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base.h b/chrome/credential_provider/gaiacp/gaia_credential_base.h index 23668b6b..8017bc49 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_base.h +++ b/chrome/credential_provider/gaiacp/gaia_credential_base.h
@@ -208,6 +208,8 @@ LONG substatus, BSTR status_text) override; + void TerminateLogonProcess(); + CComPtr<ICredentialProviderCredentialEvents> events_; // Handle to the logon UI process.
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider.cc b/chrome/credential_provider/gaiacp/gaia_credential_provider.cc index 8cfc88d..d421fd99 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_provider.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_provider.cc
@@ -121,8 +121,7 @@ BSTR /*username*/, BSTR /*password*/, BSTR sid) { - DCHECK(credential); - DCHECK(sid); + DCHECK(!credential || sid); // |credential| should be in the |users_|. Find its index. index_ = std::numeric_limits<size_t>::max();
diff --git a/chrome/credential_provider/gaiacp/gcp_utils.cc b/chrome/credential_provider/gaiacp/gcp_utils.cc index f6dac4a..d0f9ccc 100644 --- a/chrome/credential_provider/gaiacp/gcp_utils.cc +++ b/chrome/credential_provider/gaiacp/gcp_utils.cc
@@ -112,10 +112,27 @@ return E_UNEXPECTED; } + // CreateProcessWithTokenW will fail if any of the std handles provided are + // invalid and the STARTF_USESTDHANDLES flag is set. So supply the default + // standard handle if no handle is given for some of the handles. This tells + // the process it can create its own local handles for these pipes as needed. info_.dwFlags |= STARTF_USESTDHANDLES; - info_.hStdInput = hstdin->Take(); - info_.hStdOutput = hstdout->Take(); - info_.hStdError = hstderr->Take(); + if (hstdin && hstdin->IsValid()) { + info_.hStdInput = hstdin->Take(); + } else { + info_.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + } + if (hstdout && hstdout->IsValid()) { + info_.hStdOutput = hstdout->Take(); + } else { + info_.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + } + if (hstderr && hstderr->IsValid()) { + info_.hStdError = hstderr->Take(); + } else { + info_.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + } + return S_OK; } @@ -123,57 +140,48 @@ if ((info_.dwFlags & STARTF_USESTDHANDLES) == STARTF_USESTDHANDLES) { info_.dwFlags &= ~STARTF_USESTDHANDLES; - ::CloseHandle(info_.hStdInput); - ::CloseHandle(info_.hStdOutput); - ::CloseHandle(info_.hStdError); + if (info_.hStdInput != ::GetStdHandle(STD_INPUT_HANDLE)) + ::CloseHandle(info_.hStdInput); + if (info_.hStdOutput != ::GetStdHandle(STD_OUTPUT_HANDLE)) + ::CloseHandle(info_.hStdOutput); + if (info_.hStdError != ::GetStdHandle(STD_ERROR_HANDLE)) + ::CloseHandle(info_.hStdError); info_.hStdInput = INVALID_HANDLE_VALUE; info_.hStdOutput = INVALID_HANDLE_VALUE; info_.hStdError = INVALID_HANDLE_VALUE; } } -// Waits for a process to terminate while capturing its stdout and stderr to -// the buffers |stdout_buffer| and |stderr_buffer| respectively. Both buffers -// are assumed to be of the size |buffer_size| and expected to be relatively -// small. The exit code of the process is written to |exit_code|. +// Waits for a process to terminate while capturing output from |output_handle| +// to the buffer |output_buffer| of size |buffer_size|. The buffer is expected +// to be relatively small. The exit code of the process is written to +// |exit_code|. HRESULT WaitForProcess(base::win::ScopedHandle::Handle process_handle, const StdParentHandles& parent_handles, DWORD* exit_code, - char* stdout_buffer, - char* stderr_buffer, + char* output_buffer, int buffer_size) { LOGFN(INFO); DCHECK(exit_code); DCHECK_GT(buffer_size, 0); - stdout_buffer[0] = 0; - stderr_buffer[0] = 0; + output_buffer[0] = 0; - // stdio handles to wait on. This array and count are modified by code - // below if errors are detected. - base::win::ScopedHandle::Handle handles[] = { - parent_handles.hstdout_read.Get(), parent_handles.hstderr_read.Get(), - }; - DWORD count = base::size(handles); + HANDLE output_handle = parent_handles.hstdout_read.Get(); - for (bool is_done = false; !is_done && count > 0;) { - base::win::ScopedHandle::Handle h = INVALID_HANDLE_VALUE; + for (bool is_done = false; !is_done;) { char buffer[80]; DWORD length = base::size(buffer) - 1; HRESULT hr = S_OK; const DWORD kThreeMinutesInMs = 3 * 60 * 1000; - DWORD ret = ::WaitForMultipleObjectsEx(count, handles, - FALSE, // wait all - kThreeMinutesInMs, // timeout ms - TRUE); // alertable wait + DWORD ret = ::WaitForSingleObject(output_handle, + kThreeMinutesInMs); // timeout ms switch (ret) { - case WAIT_OBJECT_0: - case WAIT_OBJECT_0 + 1: { + case WAIT_OBJECT_0: { int index = ret - WAIT_OBJECT_0; LOGFN(INFO) << "WAIT_OBJECT_" << index; - h = handles[index]; - if (!::ReadFile(h, buffer, length, &length, nullptr)) { + if (!::ReadFile(output_handle, buffer, length, &length, nullptr)) { hr = HRESULT_FROM_WIN32(::GetLastError()); if (hr != HRESULT_FROM_WIN32(ERROR_BROKEN_PIPE)) LOGFN(ERROR) << "ReadFile(" << index << ") hr=" << putHR(hr); @@ -203,24 +211,13 @@ } } - // Copy the read buffer to either the stdout or stderr, as apppropriate. - // If the pipe was broken, remove the corresponding handle from |handles| - // so that WaitForMultipleObjectsEx() above no longer waits for it. - if (h == parent_handles.hstdout_read.Get()) { - if (hr == HRESULT_FROM_WIN32(ERROR_BROKEN_PIPE)) { - LOGFN(INFO) << "Stop waiting for stdout"; - handles[0] = handles[1]; - --count; - } else { - strcat_s(stdout_buffer, buffer_size, buffer); - } - } else if (h == parent_handles.hstderr_read.Get()) { - if (hr == HRESULT_FROM_WIN32(ERROR_BROKEN_PIPE)) { - LOGFN(INFO) << "Stop waiting for stderr"; - --count; - } else { - strcat_s(stderr_buffer, buffer_size, buffer); - } + // Copy the read buffer to the output buffer. If the pipe was broken, + // we can break our loop and wait for the process to die. + if (hr == HRESULT_FROM_WIN32(ERROR_BROKEN_PIPE)) { + LOGFN(INFO) << "Stop waiting for output buffer"; + break; + } else { + strcat_s(output_buffer, buffer_size, buffer); } } @@ -351,6 +348,7 @@ } HRESULT InitializeStdHandles(CommDirection direction, + StdHandlesToCreate to_create, ScopedStartupInfo* startupinfo, StdParentHandles* parent_handles) { LOGFN(INFO); @@ -359,38 +357,45 @@ base::win::ScopedHandle hstdin_read; base::win::ScopedHandle hstdin_write; - HRESULT hr = CreatePipeForChildProcess( - true, // child reads - direction == CommDirection::kChildToParentOnly, // use nul - &hstdin_read, &hstdin_write); - if (FAILED(hr)) { - LOGFN(ERROR) << "CreatePipeForChildProcess(stdin) hr=" << putHR(hr); - return hr; + if ((to_create & kStdInput) != 0) { + HRESULT hr = CreatePipeForChildProcess( + true, // child reads + direction == CommDirection::kChildToParentOnly, // use nul + &hstdin_read, &hstdin_write); + if (FAILED(hr)) { + LOGFN(ERROR) << "CreatePipeForChildProcess(stdin) hr=" << putHR(hr); + return hr; + } } base::win::ScopedHandle hstdout_read; base::win::ScopedHandle hstdout_write; - hr = CreatePipeForChildProcess( - false, // child reads - direction == CommDirection::kParentToChildOnly, // use nul - &hstdout_read, &hstdout_write); - if (FAILED(hr)) { - LOGFN(ERROR) << "CreatePipeForChildProcess(stdout) hr=" << putHR(hr); - return hr; + if ((to_create & kStdOutput) != 0) { + HRESULT hr = CreatePipeForChildProcess( + false, // child reads + direction == CommDirection::kParentToChildOnly, // use nul + &hstdout_read, &hstdout_write); + if (FAILED(hr)) { + LOGFN(ERROR) << "CreatePipeForChildProcess(stdout) hr=" << putHR(hr); + return hr; + } } base::win::ScopedHandle hstderr_read; base::win::ScopedHandle hstderr_write; - hr = CreatePipeForChildProcess( - false, // child reads - direction == CommDirection::kParentToChildOnly, // use nul - &hstderr_read, &hstderr_write); - if (FAILED(hr)) { - LOGFN(ERROR) << "CreatePipeForChildProcess(stderr) hr=" << putHR(hr); - return hr; + if ((to_create & kStdError) != 0) { + HRESULT hr = CreatePipeForChildProcess( + false, // child reads + direction == CommDirection::kParentToChildOnly, // use nul + &hstderr_read, &hstderr_write); + if (FAILED(hr)) { + LOGFN(ERROR) << "CreatePipeForChildProcess(stderr) hr=" << putHR(hr); + return hr; + } } - hr = startupinfo->SetStdHandles(&hstdin_read, &hstdout_write, &hstderr_write); + HRESULT hr = + startupinfo->SetStdHandles(&hstdin_read, &hstdout_write, &hstderr_write); if (FAILED(hr)) { LOGFN(ERROR) << "startupinfo->SetStdHandles hr=" << putHR(hr); return hr;
diff --git a/chrome/credential_provider/gaiacp/gcp_utils.h b/chrome/credential_provider/gaiacp/gcp_utils.h index 4be982a..5f824df7 100644 --- a/chrome/credential_provider/gaiacp/gcp_utils.h +++ b/chrome/credential_provider/gaiacp/gcp_utils.h
@@ -53,6 +53,16 @@ kUiecEMailMissmatch, }; +// A bitfield indicating which standard handles are to be created. +using StdHandlesToCreate = uint32_t; + +enum : uint32_t { + kStdOutput = 1 << 0, + kStdInput = 1 << 1, + kStdError = 1 << 2, + kAllStdHandles = kStdOutput | kStdInput | kStdError +}; + // Filled in by InitializeStdHandles to return the parent side of stdin/stdout/ // stderr pipes of the login UI process. struct StdParentHandles { @@ -95,8 +105,7 @@ HRESULT WaitForProcess(base::win::ScopedHandle::Handle process_handle, const StdParentHandles& parent_handles, DWORD* exit_code, - char* stdout_buffer, - char* stderr_buffer, + char* output_buffer, int buffer_size); // Creates a restricted, batch or interactive login token for the given user. @@ -137,6 +146,7 @@ kBidirectional, }; HRESULT InitializeStdHandles(CommDirection direction, + StdHandlesToCreate to_create, ScopedStartupInfo* startupinfo, StdParentHandles* parent_handles);
diff --git a/chrome/credential_provider/gaiacp/gcp_utils_unittests.cc b/chrome/credential_provider/gaiacp/gcp_utils_unittests.cc index cd93ea23..252baad 100644 --- a/chrome/credential_provider/gaiacp/gcp_utils_unittests.cc +++ b/chrome/credential_provider/gaiacp/gcp_utils_unittests.cc
@@ -122,6 +122,25 @@ ASSERT_NE(INVALID_HANDLE_VALUE, info.GetInfo()->hStdError); } +TEST_F(GcpProcHelperTest, ScopedStartupInfo_somehandles) { + ScopedStartupInfo info; + base::win::ScopedHandle shstdin; + base::win::ScopedHandle shstdout; + CreateHandle(&shstdout); + base::win::ScopedHandle shstderr; + + // Setting handles in the info should take ownership. + ASSERT_EQ(S_OK, info.SetStdHandles(&shstdin, &shstdout, &shstderr)); + ASSERT_FALSE(shstdin.IsValid()); + ASSERT_FALSE(shstdout.IsValid()); + ASSERT_FALSE(shstderr.IsValid()); + ASSERT_EQ(static_cast<DWORD>(STARTF_USESTDHANDLES), + info.GetInfo()->dwFlags & STARTF_USESTDHANDLES); + ASSERT_EQ(::GetStdHandle(STD_INPUT_HANDLE), info.GetInfo()->hStdInput); + ASSERT_NE(INVALID_HANDLE_VALUE, info.GetInfo()->hStdOutput); + ASSERT_EQ(::GetStdHandle(STD_ERROR_HANDLE), info.GetInfo()->hStdError); +} + TEST_F(GcpProcHelperTest, CreatePipeForChildProcess_ParentReads) { base::win::ScopedHandle reading; base::win::ScopedHandle writing; @@ -191,7 +210,8 @@ StdParentHandles parent_handles; ASSERT_EQ(S_OK, InitializeStdHandles(CommDirection::kParentToChildOnly, - &startupinfo, &parent_handles)); + kAllStdHandles, &startupinfo, + &parent_handles)); // Check parent handles. ASSERT_TRUE(parent_handles.hstdin_write.IsValid()); @@ -215,7 +235,8 @@ StdParentHandles parent_handles; ASSERT_EQ(S_OK, InitializeStdHandles(CommDirection::kChildToParentOnly, - &startupinfo, &parent_handles)); + kAllStdHandles, &startupinfo, + &parent_handles)); // Check parent handles. ASSERT_FALSE(parent_handles.hstdin_write.IsValid()); @@ -238,8 +259,9 @@ ScopedStartupInfo startupinfo; StdParentHandles parent_handles; - ASSERT_EQ(S_OK, InitializeStdHandles(CommDirection::kBidirectional, - &startupinfo, &parent_handles)); + ASSERT_EQ(S_OK, + InitializeStdHandles(CommDirection::kBidirectional, kAllStdHandles, + &startupinfo, &parent_handles)); // Check parent handles. ASSERT_TRUE(parent_handles.hstdin_write.IsValid()); @@ -260,12 +282,87 @@ startupinfo.GetInfo()->hStdOutput)); } -TEST_F(GcpProcHelperTest, WaitForProcess) { +TEST_F(GcpProcHelperTest, InitializeStdHandles_SomeHandlesChildToParent) { + ScopedStartupInfo startupinfo; + StdParentHandles parent_handles; + + ASSERT_EQ(S_OK, InitializeStdHandles(CommDirection::kChildToParentOnly, + (kStdInput | kStdOutput), &startupinfo, + &parent_handles)); + + // Check parent handles. + ASSERT_FALSE(parent_handles.hstdin_write.IsValid()); + ASSERT_TRUE(parent_handles.hstdout_read.IsValid()); + ASSERT_FALSE(parent_handles.hstderr_read.IsValid()); + + // Check child handles. stderr goes to default handle. + ASSERT_NE(nullptr, startupinfo.GetInfo()->hStdInput); + ASSERT_NE(INVALID_HANDLE_VALUE, startupinfo.GetInfo()->hStdInput); + ASSERT_NE(nullptr, startupinfo.GetInfo()->hStdOutput); + ASSERT_NE(INVALID_HANDLE_VALUE, startupinfo.GetInfo()->hStdOutput); + ASSERT_EQ(::GetStdHandle(STD_ERROR_HANDLE), startupinfo.GetInfo()->hStdError); + + EXPECT_TRUE(TestPipe(parent_handles.hstdout_read.Get(), + startupinfo.GetInfo()->hStdOutput)); +} + +TEST_F(GcpProcHelperTest, InitializeStdHandles_SomeHandlesParentToChild) { + ScopedStartupInfo startupinfo; + StdParentHandles parent_handles; + + ASSERT_EQ(S_OK, InitializeStdHandles(CommDirection::kParentToChildOnly, + (kStdInput | kStdOutput), &startupinfo, + &parent_handles)); + + // Check parent handles. + ASSERT_TRUE(parent_handles.hstdin_write.IsValid()); + ASSERT_FALSE(parent_handles.hstdout_read.IsValid()); + ASSERT_FALSE(parent_handles.hstderr_read.IsValid()); + + // Check child handles. stderr goes to default handle. + ASSERT_NE(nullptr, startupinfo.GetInfo()->hStdInput); + ASSERT_NE(INVALID_HANDLE_VALUE, startupinfo.GetInfo()->hStdInput); + ASSERT_NE(nullptr, startupinfo.GetInfo()->hStdOutput); + ASSERT_NE(INVALID_HANDLE_VALUE, startupinfo.GetInfo()->hStdOutput); + ASSERT_EQ(::GetStdHandle(STD_ERROR_HANDLE), startupinfo.GetInfo()->hStdError); + + EXPECT_TRUE(TestPipe(startupinfo.GetInfo()->hStdInput, + parent_handles.hstdin_write.Get())); +} + +TEST_F(GcpProcHelperTest, InitializeStdHandles_SomeHandlesBidirectional) { ScopedStartupInfo startupinfo; StdParentHandles parent_handles; ASSERT_EQ(S_OK, InitializeStdHandles(CommDirection::kBidirectional, - &startupinfo, &parent_handles)); + (kStdInput | kStdOutput), &startupinfo, + &parent_handles)); + + // Check parent handles. + ASSERT_TRUE(parent_handles.hstdin_write.IsValid()); + ASSERT_TRUE(parent_handles.hstdout_read.IsValid()); + ASSERT_FALSE(parent_handles.hstderr_read.IsValid()); + + // Check child handles. stderr goes to default handle. + ASSERT_NE(nullptr, startupinfo.GetInfo()->hStdInput); + ASSERT_NE(INVALID_HANDLE_VALUE, startupinfo.GetInfo()->hStdInput); + ASSERT_NE(nullptr, startupinfo.GetInfo()->hStdOutput); + ASSERT_NE(INVALID_HANDLE_VALUE, startupinfo.GetInfo()->hStdOutput); + ASSERT_EQ(::GetStdHandle(STD_ERROR_HANDLE), startupinfo.GetInfo()->hStdError); + + EXPECT_TRUE(TestPipe(startupinfo.GetInfo()->hStdInput, + parent_handles.hstdin_write.Get())); + EXPECT_TRUE(TestPipe(parent_handles.hstdout_read.Get(), + startupinfo.GetInfo()->hStdOutput)); +} + +TEST_F(GcpProcHelperTest, WaitForProcess) { + ScopedStartupInfo startupinfo; + StdParentHandles parent_handles; + + ASSERT_EQ(S_OK, + InitializeStdHandles(CommDirection::kBidirectional, kAllStdHandles, + &startupinfo, &parent_handles)); base::LaunchOptions options; options.inherit_mode = base::LaunchOptions::Inherit::kAll; options.stdin_handle = startupinfo.GetInfo()->hStdInput; @@ -297,9 +394,8 @@ DWORD exit_code; char output_buffer[kBufferSize]; - char error_buffer[kBufferSize]; EXPECT_EQ(S_OK, WaitForProcess(process.Handle(), parent_handles, &exit_code, - output_buffer, error_buffer, kBufferSize)); + output_buffer, kBufferSize)); EXPECT_EQ(0u, exit_code); StripCrLf(output_buffer); EXPECT_STREQ(input_buffer, output_buffer);
diff --git a/chrome/credential_provider/test/BUILD.gn b/chrome/credential_provider/test/BUILD.gn index 9394958..b1e4b656 100644 --- a/chrome/credential_provider/test/BUILD.gn +++ b/chrome/credential_provider/test/BUILD.gn
@@ -15,6 +15,7 @@ "com_fakes.h", "gcp_fakes.cc", "gcp_fakes.h", + "gcp_gls_output_unittest.cc", "gcp_setup_unittests.cc", "gcp_test_main.cc", ] @@ -25,6 +26,7 @@ "../gaiacp:version", "../setup:common", "//base", + "//chrome/test:credential_provider_test_utils", "//net:test_support", "//testing/gmock", "//testing/gtest", @@ -34,5 +36,13 @@ "../eventlog:gcp_eventlog_provider", "../gaiacp:gaia1_0", "../setup:gcp_setup", + "//chrome", + ] + + data = [ + "//net/tools/testserver/", + "//third_party/pyftpdlib/", + "//third_party/pywebsocket/src/mod_pywebsocket/", + "//third_party/tlslite/", ] }
diff --git a/chrome/credential_provider/test/gcp_gls_output_unittest.cc b/chrome/credential_provider/test/gcp_gls_output_unittest.cc new file mode 100644 index 0000000..4d9b6f8 --- /dev/null +++ b/chrome/credential_provider/test/gcp_gls_output_unittest.cc
@@ -0,0 +1,472 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/files/scoped_temp_dir.h" +#include "base/json/json_writer.h" +#include "base/process/launch.h" +#include "base/values.h" +#include "base/win/windows_version.h" +#include "chrome/browser/ui/startup/credential_provider_signin_dialog_win_test_data.h" +#include "chrome/credential_provider/common/gcp_strings.h" +#include "chrome/credential_provider/gaiacp/gcp_utils.h" +#include "google_apis/gaia/gaia_switches.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/spawned_test_server/spawned_test_server.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace credential_provider { + +class GcpUsingChromeTest : public ::testing::Test { + protected: + struct TestGoogleApiResponse { + TestGoogleApiResponse() + : info_code_(net::HTTP_BAD_REQUEST), response_given_(false) {} + TestGoogleApiResponse(net::HttpStatusCode info_code, + const std::string& data) + : info_code_(info_code), data_(data), response_given_(false) {} + + net::HttpStatusCode info_code_; + std::string data_; + bool response_given_; + }; + + GcpUsingChromeTest(); + + void SetUp() override; + void TearDown() override; + + void SetPasswordForSignin(const std::string& password) { + test_data_storage_.SetSigninPassword(password); + } + void SetUserInfoResponse(TestGoogleApiResponse response) { + user_info_response_ = response; + } + void SetTokenInfoResponse(TestGoogleApiResponse response) { + token_info_response_ = response; + } + void SetMdmTokenResponse(TestGoogleApiResponse response) { + mdm_token_response_ = response; + } + void SetSigninTokenResponse(TestGoogleApiResponse response) { + signin_token_response_ = response; + } + + std::string MakeInlineSigninCompletionScript( + const std::string& email, + const std::string& password, + const std::string& gaia_id) const; + + std::string RunChromeAndExtractOutput() const; + base::CommandLine GetCommandLineForChromeGls( + const base::FilePath& user_data_dir) const; + std::string RunProcessAndExtractOutput( + const base::CommandLine& command_line) const; + + bool ShouldRunTestOnThisOS() const { + // TODO(crbug.com/906793). For some reason handle inheritance does not work + // correctly on Windows7 and causes all the tests to stall indefinetely. + // Since GCPW is only targeted for Windows 10 currently, disable these + // unit tests for now until the problem can be resolved. + return base::win::GetVersion() >= base::win::VERSION_WIN10; + } + std::unique_ptr<net::test_server::HttpResponse> GaiaHtmlResponseHandler( + const net::test_server::HttpRequest& request); + std::unique_ptr<net::test_server::HttpResponse> GoogleApisHtmlResponseHandler( + const net::test_server::HttpRequest& request); + + CredentialProviderSigninDialogTestDataStorage test_data_storage_; + net::test_server::EmbeddedTestServer gaia_server_; + net::test_server::EmbeddedTestServer google_apis_server_; + net::SpawnedTestServer proxy_server_; + + TestGoogleApiResponse signin_token_response_; + TestGoogleApiResponse user_info_response_; + TestGoogleApiResponse token_info_response_; + TestGoogleApiResponse mdm_token_response_; + + private: + DISALLOW_COPY_AND_ASSIGN(GcpUsingChromeTest); +}; + +GcpUsingChromeTest::GcpUsingChromeTest() + : proxy_server_(net::SpawnedTestServer::TYPE_PROXY, base::FilePath()) {} + +void GcpUsingChromeTest::SetUp() { + // Redirect connections to signin related pages to a handler that will + // generate the needed headers and content to move the signin flow + // forward automatically. + gaia_server_.RegisterRequestHandler(base::BindRepeating( + &GcpUsingChromeTest::GaiaHtmlResponseHandler, base::Unretained(this))); + EXPECT_TRUE(gaia_server_.Start()); + + google_apis_server_.RegisterRequestHandler( + base::BindRepeating(&GcpUsingChromeTest::GoogleApisHtmlResponseHandler, + base::Unretained(this))); + EXPECT_TRUE(google_apis_server_.Start()); + + // Run a proxy server to redirect all non signin related requests to a + // page showing failed connections. + proxy_server_.set_redirect_connect_to_localhost(true); + EXPECT_TRUE(proxy_server_.Start()); +} + +void GcpUsingChromeTest::TearDown() { + EXPECT_TRUE(gaia_server_.ShutdownAndWaitUntilComplete()); + EXPECT_TRUE(google_apis_server_.ShutdownAndWaitUntilComplete()); + EXPECT_TRUE(proxy_server_.Stop()); +} + +std::string GcpUsingChromeTest::RunChromeAndExtractOutput() const { + base::ScopedTempDir user_data_dir; + EXPECT_TRUE(user_data_dir.CreateUniqueTempDir()); + return RunProcessAndExtractOutput( + GetCommandLineForChromeGls(user_data_dir.GetPath())); +} + +base::CommandLine GcpUsingChromeTest::GetCommandLineForChromeGls( + const base::FilePath& user_data_dir) const { + auto* process_command_line = base::CommandLine::ForCurrentProcess(); + base::CommandLine command_line( + process_command_line->GetProgram().DirName().Append(L"chrome.exe")); + + // Redirect gaia and google api pages to the servers that are being run + // locally. + const GURL& gaia_url = gaia_server_.base_url(); + command_line.AppendSwitchASCII(::switches::kGaiaUrl, gaia_url.spec()); + command_line.AppendSwitchASCII(::switches::kLsoUrl, gaia_url.spec()); + const GURL& google_apis_url = google_apis_server_.base_url(); + command_line.AppendSwitchASCII(::switches::kGoogleApisUrl, + google_apis_url.spec()); + + command_line.AppendSwitch(kGcpwSigninSwitch); + command_line.AppendSwitchPath("user-data-dir", user_data_dir); + command_line.AppendSwitchASCII("proxy-server", + proxy_server_.host_port_pair().ToString()); + return command_line; +} + +std::string GcpUsingChromeTest::RunProcessAndExtractOutput( + const base::CommandLine& command_line) const { + base::win::ScopedHandle read_handle; + base::Process process; + // The write handle is only needed until the process starts. If it is not + // closed afterwards, it will not be possible to detect the end of the + // output from the process since there will be more than one handle held + // on the output pipe and it will not close when the process dies. + { + base::win::ScopedHandle write_handle; + EXPECT_EQ( + CreatePipeForChildProcess(false, false, &read_handle, &write_handle), + S_OK); + + base::LaunchOptions options; + options.stdin_handle = INVALID_HANDLE_VALUE; + options.stdout_handle = write_handle.Get(); + options.stderr_handle = INVALID_HANDLE_VALUE; + options.handles_to_inherit.push_back(write_handle.Get()); + + process = base::Process( + base::LaunchProcess(command_line.GetCommandLineString(), options)); + EXPECT_TRUE(process.IsValid()); + } + + constexpr DWORD kTimeout = 1000; + std::string output_from_process; + char buffer[1024]; + for (bool is_done = false; !is_done;) { + DWORD length = base::size(buffer) - 1; + + DWORD ret = ::WaitForSingleObject(read_handle.Get(), kTimeout); + if (ret == WAIT_OBJECT_0) { + if (!::ReadFile(read_handle.Get(), buffer, length, &length, nullptr)) { + break; + } + + buffer[length] = 0; + output_from_process += buffer; + } else if (ret != WAIT_IO_COMPLETION) { + break; + } + } + + // If the pipe is no longer readable it is expected that the process will be + // terminating shortly. + int exit_code; + EXPECT_TRUE(process.WaitForExitWithTimeout( + base::TimeDelta::FromMilliseconds(kTimeout), &exit_code)); + EXPECT_EQ(exit_code, 0); + + return output_from_process; +} + +std::string GcpUsingChromeTest::MakeInlineSigninCompletionScript( + const std::string& email, + const std::string& password, + const std::string& gaia_id) const { + // Script that sends the two messages needed by inline_signin in order to + // continue with the signin flow. + return "<script>" + "let webview = null;" + "let onMessageEventHandler = function(event) {" + " if (!webview) {" + " webview = event.source;" + " var attempt_login_msg = {" + " 'method' : 'attemptLogin'," + " 'email' : '" + + email + + "'," + " 'password' : '" + + password + + "'," + " 'attemptToken' : 'attemptToken'" + " };" + " webview.postMessage(attempt_login_msg, '*');" + " var user_info_msg = {" + " 'method' : 'userInfo'," + " 'email' : '" + + email + + "'," + " 'gaiaId' : '" + + gaia_id + + "'," + " 'services' : []" + " };" + " webview.postMessage(user_info_msg, '*');" + " }" + "};" + "window.addEventListener('message', onMessageEventHandler);" + "</script>"; +} + +std::unique_ptr<net::test_server::HttpResponse> +GcpUsingChromeTest::GaiaHtmlResponseHandler( + const net::test_server::HttpRequest& request) { + auto http_response = std::make_unique<net::test_server::BasicHttpResponse>(); + http_response->set_code(net::HTTP_OK); + http_response->set_content_type("text/html"); + std::string content = "<html><head>"; + // When the "/embedded/setup/chrome" is requested on the gaia web site + // (accounts.google.com) then the embedded server can send a page with scripts + // that can force immediate signin. + if (request.GetURL().path().find("/embedded/setup/chrome") == 0) { + // This is the header that is sent by Gaia that the inline sign in page + // listens to in order to fill the information abou the email and Gaia ID. + http_response->AddCustomHeader("google-accounts-signin", + "email=\"" + + test_data_storage_.GetSuccessEmail() + + "\"," + "obfuscatedid=\"" + + test_data_storage_.GetSuccessId() + + "\", " + "sessionindex=0"); + // On a successful signin, the oauth_code cookie must also be set for the + // site. + http_response->AddCustomHeader("Set-Cookie", + "oauth_code=oauth_code; Path=/"); + // This header is needed to ensure that the inline_signin page does not + // break out of the constrained dialog. + http_response->AddCustomHeader("google-accounts-embedded", std::string()); + + content += MakeInlineSigninCompletionScript( + test_data_storage_.GetSuccessEmail(), + test_data_storage_.GetSuccessPassword(), + test_data_storage_.GetSuccessId()); + } + content += "</head></html>"; + http_response->set_content(content); + return std::move(http_response); +} + +std::unique_ptr<net::test_server::HttpResponse> +GcpUsingChromeTest::GoogleApisHtmlResponseHandler( + const net::test_server::HttpRequest& request) { + auto http_response = std::make_unique<net::test_server::BasicHttpResponse>(); + + // The following Google API requests are expected in this order: + // 1. A /oauth2/v4/token request that requests the initial access_token. This + // request is made after the user usually has entered a valid user id and + // password. + // Either of the two following requests (in any order): + // 1. A /oauth2/v2/tokeninfo to get the token handle for the user. + // 2. A /oauth2/v4/token to get the required id token for MDM + // registration as well as to request access to fetch the user info. + // Finally if the second "/oauth2/v4/token" request is made to get the MDM + // ID token then is expected that a request for "/oauth2/v1/userinfo" will + // be made to get the full name of the user. + + // All other Google API requests will be ignored with a 404 error. + + TestGoogleApiResponse* api_response = nullptr; + if (request.GetURL().path().find("/oauth2/v2/tokeninfo") == 0) { + api_response = &token_info_response_; + } else if (request.GetURL().path().find("/oauth2/v1/userinfo") == 0) { + // User info should never be requested before the mdm id token request is + // made. + EXPECT_TRUE(mdm_token_response_.response_given_); + api_response = &user_info_response_; + } else if (request.GetURL().path().find("/oauth2/v4/token") == 0) { + // Does the request want an auth_code for signin or is it the second request + // made to get the id token. + if (request.content.find("grant_type=authorization_code") == + std::string::npos) { + api_response = &mdm_token_response_; + } else { + api_response = &signin_token_response_; + } + } + + if (api_response) { + EXPECT_FALSE(api_response->response_given_); + api_response->response_given_ = true; + http_response->set_content_type("text/html"); + http_response->set_content(api_response->data_); + http_response->set_code(api_response->info_code_); + } else { + http_response->set_code(net::HTTP_NOT_FOUND); + } + + return std::move(http_response); +} + +TEST_F(GcpUsingChromeTest, VerifyMissingSigninInfoOutput) { + if (!ShouldRunTestOnThisOS()) + return; + + SetPasswordForSignin(std::string()); + SetTokenInfoResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulTokenInfoFetchResult()}); + SetUserInfoResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulUserInfoFetchResult()}); + SetMdmTokenResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulMdmTokenFetchResult()}); + SetSigninTokenResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulSigninTokenFetchResult()}); + + std::string output_from_chrome = RunChromeAndExtractOutput(); + + EXPECT_EQ(output_from_chrome, std::string()); + EXPECT_TRUE(signin_token_response_.response_given_); + EXPECT_FALSE(user_info_response_.response_given_); + EXPECT_FALSE(token_info_response_.response_given_); + EXPECT_FALSE(mdm_token_response_.response_given_); +} + +TEST_F(GcpUsingChromeTest, VerifySigninFailureOutput) { + if (!ShouldRunTestOnThisOS()) + return; + + SetTokenInfoResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulTokenInfoFetchResult()}); + SetUserInfoResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulUserInfoFetchResult()}); + SetMdmTokenResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulMdmTokenFetchResult()}); + SetSigninTokenResponse({net::HTTP_OK, + CredentialProviderSigninDialogTestDataStorage:: + kInvalidTokenFetchResponse}); + + std::string output_from_chrome = RunChromeAndExtractOutput(); + + EXPECT_EQ(output_from_chrome, std::string()); + EXPECT_TRUE(signin_token_response_.response_given_); + EXPECT_FALSE(user_info_response_.response_given_); + EXPECT_FALSE(token_info_response_.response_given_); + EXPECT_FALSE(mdm_token_response_.response_given_); +} + +TEST_F(GcpUsingChromeTest, VerifyTokenInfoFailureOutput) { + if (!ShouldRunTestOnThisOS()) + return; + + SetTokenInfoResponse({net::HTTP_OK, + CredentialProviderSigninDialogTestDataStorage:: + kInvalidTokenInfoResponse}); + SetUserInfoResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulUserInfoFetchResult()}); + SetMdmTokenResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulMdmTokenFetchResult()}); + SetSigninTokenResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulSigninTokenFetchResult()}); + + std::string output_from_chrome = RunChromeAndExtractOutput(); + + EXPECT_EQ(output_from_chrome, std::string()); + EXPECT_TRUE(signin_token_response_.response_given_); + EXPECT_TRUE(token_info_response_.response_given_); +} + +TEST_F(GcpUsingChromeTest, VerifyUserInfoFailureOutput) { + if (!ShouldRunTestOnThisOS()) + return; + + SetTokenInfoResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulTokenInfoFetchResult()}); + SetUserInfoResponse({net::HTTP_OK, + CredentialProviderSigninDialogTestDataStorage:: + kInvalidUserInfoResponse}); + SetMdmTokenResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulMdmTokenFetchResult()}); + SetSigninTokenResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulSigninTokenFetchResult()}); + + std::string output_from_chrome = RunChromeAndExtractOutput(); + + EXPECT_EQ(output_from_chrome, std::string()); + EXPECT_TRUE(signin_token_response_.response_given_); + EXPECT_TRUE(user_info_response_.response_given_); + EXPECT_TRUE(mdm_token_response_.response_given_); +} + +TEST_F(GcpUsingChromeTest, VerifyMdmFailureOutput) { + if (!ShouldRunTestOnThisOS()) + return; + + SetTokenInfoResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulTokenInfoFetchResult()}); + SetUserInfoResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulUserInfoFetchResult()}); + SetMdmTokenResponse({net::HTTP_OK, + CredentialProviderSigninDialogTestDataStorage:: + kInvalidTokenFetchResponse}); + SetSigninTokenResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulSigninTokenFetchResult()}); + + std::string output_from_chrome = RunChromeAndExtractOutput(); + + EXPECT_EQ(output_from_chrome, std::string()); + EXPECT_TRUE(mdm_token_response_.response_given_); + EXPECT_FALSE(user_info_response_.response_given_); +} + +TEST_F(GcpUsingChromeTest, VerifySuccessOutput) { + if (!ShouldRunTestOnThisOS()) + return; + + SetTokenInfoResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulTokenInfoFetchResult()}); + SetUserInfoResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulUserInfoFetchResult()}); + SetMdmTokenResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulMdmTokenFetchResult()}); + SetSigninTokenResponse( + {net::HTTP_OK, test_data_storage_.GetSuccessfulSigninTokenFetchResult()}); + + std::string output_from_chrome = RunChromeAndExtractOutput(); + + std::string expected_result; + base::JSONWriter::Write(test_data_storage_.expected_full_result(), + &expected_result); + + EXPECT_EQ(output_from_chrome, expected_result); + EXPECT_TRUE(signin_token_response_.response_given_); + EXPECT_TRUE(user_info_response_.response_given_); + EXPECT_TRUE(token_info_response_.response_given_); + EXPECT_TRUE(mdm_token_response_.response_given_); +} + +} // namespace credential_provider
diff --git a/chrome/renderer/extensions/automation_internal_custom_bindings.cc b/chrome/renderer/extensions/automation_internal_custom_bindings.cc index 979ad16..d7a90dc 100644 --- a/chrome/renderer/extensions/automation_internal_custom_bindings.cc +++ b/chrome/renderer/extensions/automation_internal_custom_bindings.cc
@@ -369,6 +369,61 @@ NodeIDPlusStringBoolFunction function_; }; +using NodeIDPlusDimensionsFunction = + void (*)(v8::Isolate* isolate, + v8::ReturnValue<v8::Value> result, + AutomationAXTreeWrapper* tree_wrapper, + ui::AXNode* node, + int x, + int y, + int width, + int height); + +class NodeIDPlusDimensionsWrapper + : public base::RefCountedThreadSafe<NodeIDPlusDimensionsWrapper> { + public: + NodeIDPlusDimensionsWrapper( + AutomationInternalCustomBindings* automation_bindings, + NodeIDPlusDimensionsFunction function) + : automation_bindings_(automation_bindings), function_(function) {} + + void Run(const v8::FunctionCallbackInfo<v8::Value>& args) { + v8::Isolate* isolate = automation_bindings_->GetIsolate(); + if (args.Length() < 6 || !args[0]->IsString() || !args[1]->IsInt32() || + !args[2]->IsInt32() || !args[3]->IsInt32() || !args[4]->IsInt32() || + !args[5]->IsInt32()) { + ThrowInvalidArgumentsException(automation_bindings_); + } + + ui::AXTreeID tree_id = + ui::AXTreeID::FromString(*v8::String::Utf8Value(isolate, args[0])); + int node_id = args[1].As<v8::Int32>()->Value(); + int x = args[2].As<v8::Int32>()->Value(); + int y = args[3].As<v8::Int32>()->Value(); + int width = args[4].As<v8::Int32>()->Value(); + int height = args[5].As<v8::Int32>()->Value(); + + AutomationAXTreeWrapper* tree_wrapper = + automation_bindings_->GetAutomationAXTreeWrapperFromTreeID(tree_id); + if (!tree_wrapper) + return; + + ui::AXNode* node = tree_wrapper->tree()->GetFromId(node_id); + if (!node) + return; + + function_(isolate, args.GetReturnValue(), tree_wrapper, node, x, y, width, + height); + } + + private: + virtual ~NodeIDPlusDimensionsWrapper() {} + + friend class base::RefCountedThreadSafe<NodeIDPlusDimensionsWrapper>; + + AutomationInternalCustomBindings* automation_bindings_; + NodeIDPlusDimensionsFunction function_; +}; } // namespace class AutomationMessageFilter : public IPC::MessageFilter { @@ -693,6 +748,20 @@ result.Set(RectToV8Object(isolate, global_bounds)); }); + RouteNodeIDPlusDimensionsFunction( + "ComputeGlobalBounds", + [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, + AutomationAXTreeWrapper* tree_wrapper, ui::AXNode* node, int x, int y, + int width, int height) { + gfx::RectF local_bounds(x, y, width, height); + + // Convert from local coordinates in Android window, to global + // coordinates spanning entire screen. + gfx::Rect global_bounds = ComputeGlobalNodeBounds( + tree_wrapper, node, local_bounds, nullptr, false /* clip_bounds */); + result.Set(RectToV8Object(isolate, global_bounds)); + }); + // Bindings that take a Tree ID and Node ID and string attribute name // and return a property of the node. @@ -1527,6 +1596,15 @@ name, base::BindRepeating(&NodeIDPlusStringBoolWrapper::Run, wrapper)); } +void AutomationInternalCustomBindings::RouteNodeIDPlusDimensionsFunction( + const std::string& name, + NodeIDPlusDimensionsFunction callback) { + scoped_refptr<NodeIDPlusDimensionsWrapper> wrapper = + new NodeIDPlusDimensionsWrapper(this, callback); + RouteHandlerFunction( + name, base::BindRepeating(&NodeIDPlusDimensionsWrapper::Run, wrapper)); +} + void AutomationInternalCustomBindings::GetChildIDAtIndex( const v8::FunctionCallbackInfo<v8::Value>& args) { if (args.Length() < 3 || !args[2]->IsNumber()) {
diff --git a/chrome/renderer/extensions/automation_internal_custom_bindings.h b/chrome/renderer/extensions/automation_internal_custom_bindings.h index 47b859b..a6298c3 100644 --- a/chrome/renderer/extensions/automation_internal_custom_bindings.h +++ b/chrome/renderer/extensions/automation_internal_custom_bindings.h
@@ -159,6 +159,16 @@ ui::AXNode* node, const std::string& strVal, bool boolVal)> callback); + void RouteNodeIDPlusDimensionsFunction( + const std::string& name, + void (*callback)(v8::Isolate* isolate, + v8::ReturnValue<v8::Value> result, + AutomationAXTreeWrapper* tree_wrapper, + ui::AXNode* node, + int start, + int end, + int width, + int height)); // // Access the cached accessibility trees and properties of their nodes.
diff --git a/chrome/renderer/net/available_offline_content_helper.cc b/chrome/renderer/net/available_offline_content_helper.cc index ff00d360..d38c027 100644 --- a/chrome/renderer/net/available_offline_content_helper.cc +++ b/chrome/renderer/net/available_offline_content_helper.cc
@@ -84,10 +84,9 @@ } void AvailableOfflineContentHelper::FetchAvailableContent( - base::OnceCallback<void(const std::string& offline_content_json)> - callback) { + AvailableContentCallback callback) { if (!BindProvider()) { - std::move(callback).Run({}); + std::move(callback).Run(true, {}); return; } provider_->List( @@ -95,9 +94,7 @@ base::Unretained(this), std::move(callback))); } -void AvailableOfflineContentHelper::FetchSummary( - base::OnceCallback<void(const std::string& content_summary_json)> - callback) { +void AvailableOfflineContentHelper::FetchSummary(SummaryCallback callback) { if (!BindProvider()) { std::move(callback).Run({}); return; @@ -139,8 +136,15 @@ provider_->LaunchDownloadsPage(has_prefetched_content_); } +void AvailableOfflineContentHelper::ListVisibilityChanged(bool is_visible) { + if (!BindProvider()) + return; + provider_->ListVisibilityChanged(is_visible); +} + void AvailableOfflineContentHelper::AvailableContentReceived( - base::OnceCallback<void(const std::string& offline_content_json)> callback, + AvailableContentCallback callback, + bool list_visible_by_prefs, std::vector<AvailableOfflineContentPtr> content) { has_prefetched_content_ = false; fetched_content_ = std::move(content); @@ -153,11 +157,15 @@ AvailableContentType::kPrefetchedPage; RecordSuggestionPresented(fetched_content_); - RecordEvent(error_page::NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN); + if (list_visible_by_prefs) + RecordEvent(error_page::NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN); + else + RecordEvent( + error_page::NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN_COLLAPSED); base::JSONWriter::Write(AvailableContentListToValue(fetched_content_), &json); } - std::move(callback).Run(json); + std::move(callback).Run(list_visible_by_prefs, json); // We don't need to retain the thumbnail here, so free up some memory. for (const AvailableOfflineContentPtr& item : fetched_content_) { item->thumbnail_data_uri = GURL(); @@ -165,7 +173,7 @@ } void AvailableOfflineContentHelper::SummaryReceived( - base::OnceCallback<void(const std::string& content_summary_json)> callback, + SummaryCallback callback, chrome::mojom::AvailableOfflineContentSummaryPtr summary) { has_prefetched_content_ = false; if (summary->total_items == 0) {
diff --git a/chrome/renderer/net/available_offline_content_helper.h b/chrome/renderer/net/available_offline_content_helper.h index bfa2855c..c87f4571 100644 --- a/chrome/renderer/net/available_offline_content_helper.h +++ b/chrome/renderer/net/available_offline_content_helper.h
@@ -18,6 +18,12 @@ // and records related UMA. class AvailableOfflineContentHelper { public: + using AvailableContentCallback = + base::OnceCallback<void(bool list_visible_by_prefs, + const std::string& offline_content_json)>; + using SummaryCallback = + base::OnceCallback<void(const std::string& content_summary_json)>; + AvailableOfflineContentHelper(); ~AvailableOfflineContentHelper(); @@ -26,35 +32,31 @@ // is returned if no offline content is available. // Note: A call to Reset, or deletion of this object will prevent the callback // from running. - void FetchAvailableContent( - base::OnceCallback<void(const std::string& offline_content_json)> - callback); + void FetchAvailableContent(AvailableContentCallback callback); // Fetch summary of available content and return a JSON representation. // Calls the callback once with the return value. An empty string // is returned if no offline content is available. // Note: A call to Reset, or deletion of this object will prevent the callback // from running. - void FetchSummary( - base::OnceCallback<void(const std::string& content_summary_json)> - callback); + void FetchSummary(SummaryCallback callback); // These methods just forward to the AvailableOfflineContentProvider. void LaunchItem(const std::string& id, const std::string& name_space); void LaunchDownloadsPage(); + void ListVisibilityChanged(bool is_visible); // Abort previous requests and free the mojo connection. void Reset(); private: void AvailableContentReceived( - base::OnceCallback<void(const std::string& offline_content_json)> - callback, + AvailableContentCallback callback, + bool list_visible_by_prefs, std::vector<chrome::mojom::AvailableOfflineContentPtr> content); void SummaryReceived( - base::OnceCallback<void(const std::string& content_summary_json)> - callback, + SummaryCallback callback, chrome::mojom::AvailableOfflineContentSummaryPtr summary); // Binds |provider_| if necessary. Returns true if the provider is bound.
diff --git a/chrome/renderer/net/net_error_helper.cc b/chrome/renderer/net/net_error_helper.cc index cd3a4f1..cd688e7 100644 --- a/chrome/renderer/net/net_error_helper.cc +++ b/chrome/renderer/net/net_error_helper.cc
@@ -217,6 +217,10 @@ core_->CancelSavePage(); } +void NetErrorHelper::ListVisibilityChanged(bool is_visible) { + core_->ListVisibilityChanged(is_visible); +} + content::RenderFrame* NetErrorHelper::GetRenderFrame() { return render_frame(); } @@ -552,11 +556,14 @@ } void NetErrorHelper::OfflineContentAvailable( + bool list_visible_by_prefs, const std::string& offline_content_json) { #if defined(OS_ANDROID) if (!offline_content_json.empty()) { - render_frame()->ExecuteJavaScript(base::UTF8ToUTF16(base::StrCat( - {"offlineContentAvailable(", offline_content_json, ");"}))); + std::string isShownParam(list_visible_by_prefs ? "true" : "false"); + render_frame()->ExecuteJavaScript(base::UTF8ToUTF16( + base::StrCat({"offlineContentAvailable(", isShownParam, ", ", + offline_content_json, ");"}))); } #endif }
diff --git a/chrome/renderer/net/net_error_helper.h b/chrome/renderer/net/net_error_helper.h index 186c8cc..066cf65 100644 --- a/chrome/renderer/net/net_error_helper.h +++ b/chrome/renderer/net/net_error_helper.h
@@ -70,6 +70,7 @@ void LaunchDownloadsPage() override; void SavePageForLater() override; void CancelSavePage() override; + void ListVisibilityChanged(bool is_visible) override; // SSLCertificateErrorPageController::Delegate implementation void SendCommand( @@ -141,6 +142,7 @@ void DownloadPageLater() override; void SetIsShowingDownloadButton(bool show) override; void OfflineContentAvailable( + bool list_visible_by_prefs, const std::string& offline_content_json) override; void OfflineContentSummaryAvailable( const std::string& offline_content_summary_json) override;
diff --git a/chrome/renderer/net/net_error_helper_core.cc b/chrome/renderer/net/net_error_helper_core.cc index 49c5ad92..b39dea14 100644 --- a/chrome/renderer/net/net_error_helper_core.cc +++ b/chrome/renderer/net/net_error_helper_core.cc
@@ -1142,3 +1142,9 @@ page_auto_fetcher_helper_->CancelSchedule(); #endif } + +void NetErrorHelperCore::ListVisibilityChanged(bool is_visible) { +#if defined(OS_ANDROID) + available_content_helper_.ListVisibilityChanged(is_visible); +#endif +}
diff --git a/chrome/renderer/net/net_error_helper_core.h b/chrome/renderer/net/net_error_helper_core.h index 2f86f16..feb7142 100644 --- a/chrome/renderer/net/net_error_helper_core.h +++ b/chrome/renderer/net/net_error_helper_core.h
@@ -125,6 +125,7 @@ // Signals that offline content is available. virtual void OfflineContentAvailable( + bool list_visible_by_prefs, const std::string& offline_content_json) = 0; // Signals that offline content summary is available. @@ -251,6 +252,10 @@ void CancelSavePage(); void SavePageForLater(); + // Signals the user changed the visibility of the offline content list in the + // dino page. + void ListVisibilityChanged(bool is_visible); + private: struct ErrorPageInfo;
diff --git a/chrome/renderer/net/net_error_helper_core_unittest.cc b/chrome/renderer/net/net_error_helper_core_unittest.cc index f7704725..ae651d27 100644 --- a/chrome/renderer/net/net_error_helper_core_unittest.cc +++ b/chrome/renderer/net/net_error_helper_core_unittest.cc
@@ -175,6 +175,7 @@ show_saved_copy_count_(0), diagnose_error_count_(0), download_count_(0), + list_visible_by_prefs_(true), enable_page_helper_functions_count_(0), default_url_(GURL(kFailedUrl)), error_url_(GURL(content::kUnreachableWebDataURL)), @@ -252,6 +253,8 @@ offline_content_feature_state_ = offline_content_feature_state; } + bool list_visible_by_prefs() const { return list_visible_by_prefs_; } + void set_auto_fetch_allowed(bool allowed) { auto_fetch_allowed_ = allowed; } const std::string& offline_content_json() const { @@ -458,7 +461,9 @@ void SetIsShowingDownloadButton(bool show) override {} void OfflineContentAvailable( + bool list_visible_by_prefs, const std::string& offline_content_json) override { + list_visible_by_prefs_ = list_visible_by_prefs; offline_content_json_ = offline_content_json; } @@ -531,6 +536,7 @@ int diagnose_error_count_; GURL diagnose_error_url_; int download_count_; + bool list_visible_by_prefs_; std::string offline_content_json_; std::string offline_content_summary_json_; #if defined(OS_ANDROID) @@ -2662,7 +2668,9 @@ const char kDataURI[] = "data:image/png;base64,abc"; -std::vector<chrome::mojom::AvailableOfflineContentPtr> TestAvailableContent() { +// Creates a couple of fake AvailableOfflineContent instances. +std::vector<chrome::mojom::AvailableOfflineContentPtr> +GetFakeAvailableContent() { std::vector<chrome::mojom::AvailableOfflineContentPtr> content; content.push_back(chrome::mojom::AvailableOfflineContent::New( "ID", "name_space", "title", "snippet", "date_modified", "attribution", @@ -2674,6 +2682,40 @@ return content; } +// Builds the expected JSON representation of the AvailableOfflineContent +// instances returned by |GetFakeAvailableContent|. +const std::string GetExpectedAvailableContentAsJson() { + // About the below data: + // * |content_type| is an AvailableContentType enum value where + // 0 = kPrefetchedPage and 3=kOtherPage. + // * The base64 encoded values represent the encoded versions of the + // respective entries returned by |GetFakeAvailableContent|. + std::string want_json = R"([ + { + "ID": "ID", + "attribution_base64": "YXR0cmlidXRpb24=", + "content_type": 0, + "date_modified": "date_modified", + "name_space": "name_space", + "snippet_base64": "c25pcHBldA==", + "thumbnail_data_uri": "data:image/png;base64,abc", + "title_base64": "dGl0bGU=" + }, + { + "ID": "ID2", + "attribution_base64": "YXR0cmlidXRpb24y", + "content_type": 3, + "date_modified": "date_modified2", + "name_space": "name_space2", + "snippet_base64": "c25pcHBldDI=", + "thumbnail_data_uri": "data:image/png;base64,abc", + "title_base64": "dGl0bGUy" + } + ])"; + base::ReplaceChars(want_json, base::kWhitespaceASCII, "", &want_json); + return want_json; +} + class FakeAvailableOfflineContentProvider : public chrome::mojom::AvailableOfflineContentProvider { public: @@ -2681,9 +2723,10 @@ void List(ListCallback callback) override { if (return_content_) { - std::move(callback).Run(TestAvailableContent()); + std::move(callback).Run(list_visible_by_prefs_, + GetFakeAvailableContent()); } else { - std::move(callback).Run({}); + std::move(callback).Run(list_visible_by_prefs_, {}); } } @@ -2700,6 +2743,7 @@ MOCK_METHOD2(LaunchItem, void(const std::string& item_ID, const std::string& name_space)); MOCK_METHOD1(LaunchDownloadsPage, void(bool open_prefetched_articles_tab)); + MOCK_METHOD1(ListVisibilityChanged, void(bool is_visible)); void AddBinding(mojo::ScopedMessagePipeHandle handle) { bindings_.AddBinding(this, @@ -2711,8 +2755,13 @@ return_content_ = return_content; } + void set_list_visible_by_prefs(bool list_visible_by_prefs) { + list_visible_by_prefs_ = list_visible_by_prefs; + } + private: bool return_content_ = true; + bool list_visible_by_prefs_ = true; mojo::BindingSet<chrome::mojom::AvailableOfflineContentProvider> bindings_; DISALLOW_COPY_AND_ASSIGN(FakeAvailableOfflineContentProvider); @@ -2744,34 +2793,8 @@ DoErrorLoad(net::ERR_INTERNET_DISCONNECTED); task_environment()->RunUntilIdle(); - // Note: content_type is an AvailableContentType enum value. - // Below, 0=kPrefetchedPage and 3=kOtherPage. The base64 encoded values - // represent the encoded versions of the values returned by - // |TestAvailableContent|. - std::string want_json = R"([ - { - "ID": "ID", - "attribution_base64": "YXR0cmlidXRpb24=", - "content_type": 0, - "date_modified": "date_modified", - "name_space": "name_space", - "snippet_base64": "c25pcHBldA==", - "thumbnail_data_uri": "data:image/png;base64,abc", - "title_base64": "dGl0bGU=" - }, - { - "ID": "ID2", - "attribution_base64": "YXR0cmlidXRpb24y", - "content_type": 3, - "date_modified": "date_modified2", - "name_space": "name_space2", - "snippet_base64": "c25pcHBldDI=", - "thumbnail_data_uri": "data:image/png;base64,abc", - "title_base64": "dGl0bGUy" - } - ])"; - base::ReplaceChars(want_json, base::kWhitespaceASCII, "", &want_json); - EXPECT_EQ(want_json, offline_content_json()); + EXPECT_TRUE(list_visible_by_prefs()); + EXPECT_EQ(GetExpectedAvailableContentAsJson(), offline_content_json()); histogram_tester_.ExpectTotalCount("Net.ErrorPageCounts.SuggestionPresented", 2); @@ -2784,6 +2807,49 @@ histogram_tester_.ExpectBucketCount( "Net.ErrorPageCounts", error_page::NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN, 1); + histogram_tester_.ExpectBucketCount( + "Net.ErrorPageCounts", + error_page::NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN_COLLAPSED, 0); + + core()->LaunchOfflineItem("ID", "name_space"); + histogram_tester_.ExpectBucketCount( + "Net.ErrorPageCounts.SuggestionPresented", + chrome::mojom::AvailableContentType::kPrefetchedPage, 1); + histogram_tester_.ExpectBucketCount( + "Net.ErrorPageCounts", + error_page::NETWORK_ERROR_PAGE_OFFLINE_SUGGESTION_CLICKED, 1); + + core()->LaunchDownloadsPage(); + histogram_tester_.ExpectBucketCount( + "Net.ErrorPageCounts", + error_page::NETWORK_ERROR_PAGE_OFFLINE_DOWNLOADS_PAGE_CLICKED, 1); +} + +TEST_F(NetErrorHelperCoreAvailableOfflineContentTest, ListHiddenByPrefs) { + set_offline_content_feature_state( + OfflineContentOnNetErrorFeatureState::kEnabledList); + fake_provider_.set_return_content(true); + fake_provider_.set_list_visible_by_prefs(false); + + DoErrorLoad(net::ERR_INTERNET_DISCONNECTED); + task_environment()->RunUntilIdle(); + EXPECT_FALSE(list_visible_by_prefs()); + EXPECT_EQ(GetExpectedAvailableContentAsJson(), offline_content_json()); + + histogram_tester_.ExpectTotalCount("Net.ErrorPageCounts.SuggestionPresented", + 2); + histogram_tester_.ExpectBucketCount( + "Net.ErrorPageCounts.SuggestionPresented", + chrome::mojom::AvailableContentType::kPrefetchedPage, 1); + histogram_tester_.ExpectBucketCount( + "Net.ErrorPageCounts.SuggestionPresented", + chrome::mojom::AvailableContentType::kOtherPage, 1); + histogram_tester_.ExpectBucketCount( + "Net.ErrorPageCounts", + error_page::NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN, 0); + histogram_tester_.ExpectBucketCount( + "Net.ErrorPageCounts", + error_page::NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN_COLLAPSED, 1); core()->LaunchOfflineItem("ID", "name_space"); histogram_tester_.ExpectBucketCount( @@ -2807,7 +2873,14 @@ DoErrorLoad(net::ERR_INTERNET_DISCONNECTED); task_environment()->RunUntilIdle(); + EXPECT_TRUE(list_visible_by_prefs()); EXPECT_EQ("", offline_content_json()); + histogram_tester_.ExpectBucketCount( + "Net.ErrorPageCounts", + error_page::NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN, 0); + histogram_tester_.ExpectBucketCount( + "Net.ErrorPageCounts", + error_page::NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN_COLLAPSED, 0); } TEST_F(NetErrorHelperCoreAvailableOfflineContentTest, SummaryAvailableContent) { @@ -2834,6 +2907,9 @@ error_page::NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN, 0); histogram_tester_.ExpectBucketCount( "Net.ErrorPageCounts", + error_page::NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN_COLLAPSED, 0); + histogram_tester_.ExpectBucketCount( + "Net.ErrorPageCounts", error_page::NETWORK_ERROR_PAGE_OFFLINE_CONTENT_SUMMARY_SHOWN, 1); core()->LaunchDownloadsPage(); @@ -2850,12 +2926,16 @@ DoErrorLoad(net::ERR_INTERNET_DISCONNECTED); task_environment()->RunUntilIdle(); + EXPECT_TRUE(list_visible_by_prefs()); EXPECT_EQ("", offline_content_json()); histogram_tester_.ExpectTotalCount("Net.ErrorPageCounts.SuggestionPresented", 0); histogram_tester_.ExpectBucketCount( "Net.ErrorPageCounts", error_page::NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN, 0); + histogram_tester_.ExpectBucketCount( + "Net.ErrorPageCounts", + error_page::NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN_COLLAPSED, 0); } class FakeOfflinePageAutoFetcher
diff --git a/chrome/renderer/net/net_error_page_controller.cc b/chrome/renderer/net/net_error_page_controller.cc index 936809d..79cfdd8 100644 --- a/chrome/renderer/net/net_error_page_controller.cc +++ b/chrome/renderer/net/net_error_page_controller.cc
@@ -112,6 +112,11 @@ delegate_->CancelSavePage(); } +void NetErrorPageController::ListVisibilityChanged(bool is_visible) { + if (delegate_) + delegate_->ListVisibilityChanged(is_visible); +} + NetErrorPageController::NetErrorPageController(base::WeakPtr<Delegate> delegate) : delegate_(delegate) { } @@ -141,5 +146,7 @@ .SetMethod("launchDownloadsPage", &NetErrorPageController::LaunchDownloadsPage) .SetMethod("savePageForLater", &NetErrorPageController::SavePageForLater) - .SetMethod("cancelSavePage", &NetErrorPageController::CancelSavePage); + .SetMethod("cancelSavePage", &NetErrorPageController::CancelSavePage) + .SetMethod("listVisibilityChanged", + &NetErrorPageController::ListVisibilityChanged); }
diff --git a/chrome/renderer/net/net_error_page_controller.h b/chrome/renderer/net/net_error_page_controller.h index c11af32..46e64d79 100644 --- a/chrome/renderer/net/net_error_page_controller.h +++ b/chrome/renderer/net/net_error_page_controller.h
@@ -49,6 +49,10 @@ // feature. virtual void CancelSavePage() = 0; + // Called to signal the user tapped the button to change the visibility of + // the offline content list. + virtual void ListVisibilityChanged(bool is_visible) = 0; + protected: Delegate(); virtual ~Delegate(); @@ -99,6 +103,7 @@ void LaunchDownloadsPage(); void SavePageForLater(); void CancelSavePage(); + void ListVisibilityChanged(bool is_visible); // gin::WrappableBase gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
diff --git a/chrome/renderer/resources/extensions/automation/automation_node.js b/chrome/renderer/resources/extensions/automation/automation_node.js index b969a268..558cf49 100644 --- a/chrome/renderer/resources/extensions/automation/automation_node.js +++ b/chrome/renderer/resources/extensions/automation/automation_node.js
@@ -179,6 +179,18 @@ var GetBoundsForRange = natives.GetBoundsForRange; /** + * @param {number} left The left location of the text range. + * @param {number} top The top location of the text range. + * @param {number} width The width of text range. + * @param {number} height The height of the text range. + * @param {number} requestID The request id associated with the query + * for this range. + * @return {?automation.Rect} The bounding box of the subrange of this node, + * specified by arguments provided to the function. + */ +var ComputeGlobalBounds = natives.ComputeGlobalBounds; + +/** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?automation.Rect} The unclipped location of the node, or @@ -369,7 +381,7 @@ AutomationNodeImpl.prototype = { __proto__: null, - treeID: "", + treeID: '', id: -1, isRootNode: false, @@ -413,8 +425,33 @@ return GetLocation(this.treeID, this.id); }, - boundsForRange: function(startIndex, endIndex) { - return GetBoundsForRange(this.treeID, this.id, startIndex, endIndex); + boundsForRange: function(startIndex, endIndex, callback) { + if (!this.rootImpl) + return; + + // Not yet initialized. + if (this.rootImpl.treeID === undefined || this.id === undefined) { + return; + } + + if (!callback) + return; + + if (!GetBoolAttribute(this.treeID, this.id, 'supportsTextLocation')) { + try { + callback( + GetBoundsForRange(this.treeID, this.id, startIndex, endIndex)); + return; + } catch (e) { + logging.WARNING('Error with bounds for range callback' + e); + } + return; + } + + this.performAction_( + 'getTextLocation', {startIndex: startIndex, endIndex: endIndex}, + callback); + return; }, get unclippedLocation() { @@ -906,7 +943,7 @@ return false; if ('role' in params && this.role != params.role) - return false; + return false; if ('state' in params) { for (var state in params.state) { @@ -958,14 +995,8 @@ 'value']; var boolAttributes = [ - 'busy', - 'clickable', - 'containerLiveAtomic', - 'containerLiveBusy', - 'liveAtomic', - 'modal', - 'scrollable', - 'selected' + 'busy', 'clickable', 'containerLiveAtomic', 'containerLiveBusy', 'liveAtomic', + 'modal', 'scrollable', 'selected', 'supportsTextLocation' ]; var intAttributes = [ @@ -1249,7 +1280,7 @@ /** * @type {string} */ - treeID: "", + treeID: '', /** * A map from id to AutomationNode. @@ -1332,7 +1363,7 @@ if (id == this.id) return this.wrapper; - var obj = this.axNodeDataCache_[id]; + var obj = this.axNodeDataCache_[id]; if (obj) return obj; @@ -1386,6 +1417,28 @@ return AutomationRootNodeImpl.actionRequestCounter; }, + onGetTextLocationResult: function(textLocationParams) { + let requestID = textLocationParams.requestID; + if (requestID in AutomationRootNodeImpl.actionRequestIDToCallback) { + let callback = + AutomationRootNodeImpl.actionRequestIDToCallback[requestID]; + try { + if (textLocationParams.result) { + callback(ComputeGlobalBounds( + this.treeID, textLocationParams.nodeID, textLocationParams.left, + textLocationParams.top, textLocationParams.width, + textLocationParams.height)); + } else { + callback(undefined); + } + } catch (e) { + logging.WARNING('Error with onGetTextLocationResult callback:' + e); + } + delete AutomationNodeImpl.actionRequestIDToCallback[requestID]; + } + }, + + onActionResult: function(requestID, result) { if (requestID in AutomationRootNodeImpl.actionRequestIDToCallback) { AutomationRootNodeImpl.actionRequestIDToCallback[requestID](result); @@ -1450,35 +1503,37 @@ 'toString', 'boundsForRange', ], - readonly: $Array.concat(publicAttributes, [ - 'parent', - 'firstChild', - 'lastChild', - 'children', - 'previousSibling', - 'nextSibling', - 'isRootNode', - 'role', - 'checked', - 'defaultActionVerb', - 'restriction', - 'state', - 'location', - 'indexInParent', - 'lineStartOffsets', - 'root', - 'htmlAttributes', - 'nameFrom', - 'bold', - 'italic', - 'underline', - 'lineThrough', - 'customActions', - 'standardActions', - 'unclippedLocation', - 'tableCellColumnHeaders', - 'tableCellRowHeaders', - ]), + readonly: $Array.concat( + publicAttributes, + [ + 'parent', + 'firstChild', + 'lastChild', + 'children', + 'previousSibling', + 'nextSibling', + 'isRootNode', + 'role', + 'checked', + 'defaultActionVerb', + 'restriction', + 'state', + 'location', + 'indexInParent', + 'lineStartOffsets', + 'root', + 'htmlAttributes', + 'nameFrom', + 'bold', + 'italic', + 'underline', + 'lineThrough', + 'customActions', + 'standardActions', + 'unclippedLocation', + 'tableCellColumnHeaders', + 'tableCellRowHeaders', + ]), }); function AutomationRootNode() {
diff --git a/chrome/renderer/resources/extensions/automation_custom_bindings.js b/chrome/renderer/resources/extensions/automation_custom_bindings.js index 129b3e4..df16509 100644 --- a/chrome/renderer/resources/extensions/automation_custom_bindings.js +++ b/chrome/renderer/resources/extensions/automation_custom_bindings.js
@@ -342,14 +342,22 @@ automationInternal.enableFrame(id); }); -automationInternal.onActionResult.addListener( - function(treeID, requestID, result) { +automationInternal.onActionResult.addListener(function( + treeID, requestID, result) { var targetTree = AutomationRootNode.get(treeID); if (!targetTree) return; privates(targetTree).impl.onActionResult(requestID, result); - }); +}); + +automationInternal.onGetTextLocationResult.addListener(function( + textLocationParams) { + var targetTree = AutomationRootNode.get(textLocationParams.treeID); + if (!targetTree) + return; + privates(targetTree).impl.onGetTextLocationResult(textLocationParams); +}); if (!apiBridge) exports.$set('binding', automation.generate());
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index c00a85d4..235ab93 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1697,6 +1697,7 @@ "../browser/chromeos/login/existing_user_controller_browsertest.cc", "../browser/chromeos/login/hid_detection_browsertest.cc", "../browser/chromeos/login/kiosk_browsertest.cc", + "../browser/chromeos/login/lock/screen_locker_browsertest.cc", "../browser/chromeos/login/lock/screen_locker_tester.cc", "../browser/chromeos/login/lock/screen_locker_tester.h", "../browser/chromeos/login/login_manager_test.cc", @@ -1763,6 +1764,7 @@ "../browser/chromeos/policy/device_quirks_policy_browsertest.cc", "../browser/chromeos/policy/device_status_collector_browsertest.cc", "../browser/chromeos/policy/device_system_use_24hour_clock_browsertest.cc", + "../browser/chromeos/policy/display_resolution_handler_browsertest.cc", "../browser/chromeos/policy/display_rotation_default_handler_browsertest.cc", "../browser/chromeos/policy/force_maximize_on_first_run_chromeos_browsertest.cc", "../browser/chromeos/policy/login_policy_test_base.cc", @@ -3015,11 +3017,12 @@ "../browser/android/tasks/task_tab_helper_unittest.cc", "../browser/autofill/autofill_credit_card_filling_infobar_delegate_mobile_unittest.cc", "../browser/autofill/autofill_save_card_infobar_delegate_mobile_unittest.cc", + "../browser/autofill/manual_filling_controller_impl_unittest.cc", "../browser/metrics/android_metrics_provider_unittest.cc", "../browser/page_load_metrics/observers/android_page_load_metrics_observer_unittest.cc", "../browser/password_manager/account_chooser_dialog_android_unittest.cc", "../browser/password_manager/auto_signin_first_run_dialog_android_unittest.cc", - "../browser/password_manager/password_accessory_controller_unittest.cc", + "../browser/password_manager/password_accessory_controller_impl_unittest.cc", "../browser/password_manager/save_password_infobar_delegate_android_unittest.cc", "../browser/password_manager/update_password_infobar_delegate_android_unittest.cc", "../browser/translate/translate_manager_render_view_host_android_unittest.cc", @@ -4928,9 +4931,6 @@ "../browser/chromeos/login/active_directory_login_browsertest.cc", "../browser/chromeos/login/active_directory_test_helper.cc", "../browser/chromeos/login/active_directory_test_helper.h", - "../browser/chromeos/login/lock/screen_locker_browsertest.cc", - "../browser/chromeos/login/lock/screen_locker_tester.cc", - "../browser/chromeos/login/lock/screen_locker_tester.h", "../browser/chromeos/login/login_auth_recorder_browsertest.cc", "../browser/chromeos/login/login_browsertest.cc", "../browser/chromeos/login/login_manager_test.cc",
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn index 69c488c..960f8fa 100644 --- a/chrome/test/android/BUILD.gn +++ b/chrome/test/android/BUILD.gn
@@ -78,6 +78,7 @@ "//components/embedder_support/android:web_contents_delegate_java", "//components/invalidation/impl:java", "//components/location/android:location_java", + "//components/omnibox/browser:browser_java", "//components/policy/android:policy_java", "//components/policy/android:policy_java_test_support", "//components/signin/core/browser/android:java",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java index 4cf8aa9..db778fe6 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java
@@ -76,9 +76,8 @@ int type, String text, String url) { List<MatchClassification> classifications = new ArrayList<>(); classifications.add(new MatchClassification(0, MatchClassificationStyle.NONE)); - mSuggestions.add(new OmniboxSuggestion( - type, false, 0, 0, text, classifications, null, classifications, - null, null, "", url, false, false)); + mSuggestions.add(new OmniboxSuggestion(type, false, 0, 0, text, classifications, null, + classifications, null, "", url, false, false)); return this; }
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index 6269eb692..d8d87490 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h
@@ -95,6 +95,7 @@ void FocusToolbar() override {} ToolbarActionsBar* GetToolbarActionsBar() override; void ToolbarSizeChanged(bool is_animating) override {} + void TabDraggingStatusChanged(bool is_dragging) override {} void FocusAppMenu() override {} void FocusBookmarksToolbar() override {} void FocusInactivePopupForAccessibility() override {}
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc index 5ea1c85..d82a06c0 100644 --- a/chrome/test/chromedriver/chrome/web_view_impl.cc +++ b/chrome/test/chromedriver/chrome/web_view_impl.cc
@@ -409,7 +409,7 @@ // thread to get consistent behavior. base::DictionaryValue params; params.SetString("expression", - "new Promise(x => setTimeout(() => setTimeout(x, 20), 20)"); + "new Promise(x => setTimeout(() => setTimeout(x, 20), 20))"); params.SetBoolean("awaitPromise", true); client_->SendCommand("Runtime.evaluate", params); for (auto it = events.begin(); it != events.end(); ++it) {
diff --git a/chrome/test/chromedriver/session_commands.cc b/chrome/test/chromedriver/session_commands.cc index e97f536..623bfb49 100644 --- a/chrome/test/chromedriver/session_commands.cc +++ b/chrome/test/chromedriver/session_commands.cc
@@ -899,33 +899,6 @@ return Status(kOk); } -// TODO(johnchen): There is no public method in Chrome or ChromeDesktopImpl to -// get both size and position in one call. What we're doing now is kind of -// wasteful, since both GetWindowPosition and GetWindowSize end up getting both -// position and size, and then discard one of the two pieces. -Status ExecuteGetWindowRect(Session* session, - const base::DictionaryValue& params, - std::unique_ptr<base::Value>* value) { - int x, y; - int width, height; - - Status status = session->chrome->GetWindowPosition(session->window, &x, &y); - if (status.IsError()) - return status; - status = session->chrome->GetWindowSize(session->window, &width, &height); - - if (status.IsError()) - return status; - - base::DictionaryValue rect; - rect.SetInteger("x", x); - rect.SetInteger("y", y); - rect.SetInteger("width", width); - rect.SetInteger("height", height); - value->reset(rect.DeepCopy()); - return Status(kOk); -} - Status ExecuteGetWindowPosition(Session* session, const base::DictionaryValue& params, std::unique_ptr<base::Value>* value) { @@ -972,65 +945,6 @@ return Status(kOk); } -Status ExecuteSetWindowRect(Session* session, - const base::DictionaryValue& params, - std::unique_ptr<base::Value>* value) { - const double max_range = 2147483647; // 2^31 - 1 - const double min_range = -2147483648; // -2^31 - const base::Value* temp; - double width = 0; - double height = 0; - double x = 0; - double y = 0; - - bool has_x = params.Get("x", &temp) && !temp->is_none(); - if (has_x) { - if (!temp->GetAsDouble(&x)) - return Status(kInvalidArgument, "'x' must be a number"); - if (x > max_range || x < min_range) - return Status(kInvalidArgument, "'x' out of range"); - } - bool has_y = params.Get("y", &temp) && !temp->is_none(); - if (has_y) { - if (!temp->GetAsDouble(&y)) - return Status(kInvalidArgument, "'y' must be a number"); - if (y > max_range || y < min_range ) - return Status(kInvalidArgument, "'y' out of range"); - } - bool has_width = params.Get("width", &temp) && !temp->is_none(); - if (has_width) { - if (!temp->GetAsDouble(&width)) - return Status(kInvalidArgument, "'width' must be a number"); - if (width > max_range || width < 0 ) - return Status(kInvalidArgument, "'width' out of range"); - } - bool has_height = params.Get("height", &temp) && !temp->is_none(); - if (has_height) { - if (!temp->GetAsDouble(&height)) - return Status(kInvalidArgument, "'height' must be a number"); - if (height > max_range || height < 0 ) - return Status(kInvalidArgument, "'height' out of range"); - } - - // to pass to the set window rect command - base::DictionaryValue rect_params; - // only set position if both x and y are given - if (has_x && has_y) { - rect_params.SetInteger("x", static_cast<int>(x)); - rect_params.SetInteger("y", static_cast<int>(y)); - } // only set size if both height and width are given - if (has_width && has_height) { - rect_params.SetInteger("width", static_cast<int>(width)); - rect_params.SetInteger("height", static_cast<int>(height)); - } - Status status = session->chrome->SetWindowRect(session->window, rect_params); - if (status.IsError()) - return status; - - // return the current window rect - return ExecuteGetWindowRect(session, params, value); -} - Status ExecuteSetWindowSize(Session* session, const base::DictionaryValue& params, std::unique_ptr<base::Value>* value) { @@ -1045,36 +959,6 @@ static_cast<int>(height)); } -Status ExecuteMaximizeWindow(Session* session, - const base::DictionaryValue& params, - std::unique_ptr<base::Value>* value) { - Status status = session->chrome->MaximizeWindow(session->window); - if (status.IsError()) - return status; - - return ExecuteGetWindowRect(session, params, value); -} - -Status ExecuteMinimizeWindow(Session* session, - const base::DictionaryValue& params, - std::unique_ptr<base::Value>* value) { - Status status = session->chrome->MinimizeWindow(session->window); - if (status.IsError()) - return status; - - return ExecuteGetWindowRect(session, params, value); -} - -Status ExecuteFullScreenWindow(Session* session, - const base::DictionaryValue& params, - std::unique_ptr<base::Value>* value) { - Status status = session->chrome->FullScreenWindow(session->window); - if (status.IsError()) - return status; - - return ExecuteGetWindowRect(session, params, value); -} - Status ExecuteGetAvailableLogTypes(Session* session, const base::DictionaryValue& params, std::unique_ptr<base::Value>* value) {
diff --git a/chrome/test/chromedriver/session_commands.h b/chrome/test/chromedriver/session_commands.h index 20dfe62..81c6db190 100644 --- a/chrome/test/chromedriver/session_commands.h +++ b/chrome/test/chromedriver/session_commands.h
@@ -126,10 +126,6 @@ const base::DictionaryValue& params, std::unique_ptr<base::Value>* value); -Status ExecuteGetWindowRect(Session* session, - const base::DictionaryValue& params, - std::unique_ptr<base::Value>* value); - Status ExecuteGetWindowPosition(Session* session, const base::DictionaryValue& params, std::unique_ptr<base::Value>* value); @@ -142,26 +138,10 @@ const base::DictionaryValue& params, std::unique_ptr<base::Value>* value); -Status ExecuteSetWindowRect(Session* session, - const base::DictionaryValue& params, - std::unique_ptr<base::Value>* value); - Status ExecuteSetWindowSize(Session* session, const base::DictionaryValue& params, std::unique_ptr<base::Value>* value); -Status ExecuteMaximizeWindow(Session* session, - const base::DictionaryValue& params, - std::unique_ptr<base::Value>* value); - -Status ExecuteMinimizeWindow(Session* session, - const base::DictionaryValue& params, - std::unique_ptr<base::Value>* value); - -Status ExecuteFullScreenWindow(Session* session, - const base::DictionaryValue& params, - std::unique_ptr<base::Value>* value); - Status ExecuteGetAvailableLogTypes(Session* session, const base::DictionaryValue& params, std::unique_ptr<base::Value>* value);
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc index 5004b2b..7c2af3f 100644 --- a/chrome/test/chromedriver/window_commands.cc +++ b/chrome/test/chromedriver/window_commands.cc
@@ -1585,3 +1585,129 @@ Timeout* timeout) { return web_view->TakeHeapSnapshot(value); } + +// TODO(johnchen): There is no public method in Chrome or ChromeDesktopImpl to +// get both size and position in one call. What we're doing now is kind of +// wasteful, since both GetWindowPosition and GetWindowSize end up getting both +// position and size, and then discard one of the two pieces. +Status ExecuteGetWindowRect(Session* session, + WebView* web_view, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value, + Timeout* timeout) { + int x, y; + int width, height; + + Status status = session->chrome->GetWindowPosition(session->window, &x, &y); + if (status.IsError()) + return status; + status = session->chrome->GetWindowSize(session->window, &width, &height); + + if (status.IsError()) + return status; + + base::DictionaryValue rect; + rect.SetInteger("x", x); + rect.SetInteger("y", y); + rect.SetInteger("width", width); + rect.SetInteger("height", height); + value->reset(rect.DeepCopy()); + return Status(kOk); +} + +Status ExecuteSetWindowRect(Session* session, + WebView* web_view, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value, + Timeout* timeout) { + const double max_range = 2147483647; // 2^31 - 1 + const double min_range = -2147483648; // -2^31 + const base::Value* temp; + double width = 0; + double height = 0; + double x = 0; + double y = 0; + + bool has_x = params.Get("x", &temp) && !temp->is_none(); + if (has_x) { + if (!temp->GetAsDouble(&x)) + return Status(kInvalidArgument, "'x' must be a number"); + if (x > max_range || x < min_range) + return Status(kInvalidArgument, "'x' out of range"); + } + bool has_y = params.Get("y", &temp) && !temp->is_none(); + if (has_y) { + if (!temp->GetAsDouble(&y)) + return Status(kInvalidArgument, "'y' must be a number"); + if (y > max_range || y < min_range ) + return Status(kInvalidArgument, "'y' out of range"); + } + bool has_width = params.Get("width", &temp) && !temp->is_none(); + if (has_width) { + if (!temp->GetAsDouble(&width)) + return Status(kInvalidArgument, "'width' must be a number"); + if (width > max_range || width < 0 ) + return Status(kInvalidArgument, "'width' out of range"); + } + bool has_height = params.Get("height", &temp) && !temp->is_none(); + if (has_height) { + if (!temp->GetAsDouble(&height)) + return Status(kInvalidArgument, "'height' must be a number"); + if (height > max_range || height < 0 ) + return Status(kInvalidArgument, "'height' out of range"); + } + + // to pass to the set window rect command + base::DictionaryValue rect_params; + // only set position if both x and y are given + if (has_x && has_y) { + rect_params.SetInteger("x", static_cast<int>(x)); + rect_params.SetInteger("y", static_cast<int>(y)); + } // only set size if both height and width are given + if (has_width && has_height) { + rect_params.SetInteger("width", static_cast<int>(width)); + rect_params.SetInteger("height", static_cast<int>(height)); + } + Status status = session->chrome->SetWindowRect(session->window, rect_params); + if (status.IsError()) + return status; + + // return the current window rect + return ExecuteGetWindowRect(session, web_view, params, value, timeout); +} + +Status ExecuteMaximizeWindow(Session* session, + WebView* web_view, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value, + Timeout* timeout) { + Status status = session->chrome->MaximizeWindow(session->window); + if (status.IsError()) + return status; + + return ExecuteGetWindowRect(session, web_view, params, value, timeout); +} + +Status ExecuteMinimizeWindow(Session* session, + WebView* web_view, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value, + Timeout* timeout) { + Status status = session->chrome->MinimizeWindow(session->window); + if (status.IsError()) + return status; + + return ExecuteGetWindowRect(session, web_view, params, value, timeout); +} + +Status ExecuteFullScreenWindow(Session* session, + WebView* web_view, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value, + Timeout* timeout) { + Status status = session->chrome->FullScreenWindow(session->window); + if (status.IsError()) + return status; + + return ExecuteGetWindowRect(session, web_view, params, value, timeout); +}
diff --git a/chrome/test/chromedriver/window_commands.h b/chrome/test/chromedriver/window_commands.h index 5e18353..a42a098f 100644 --- a/chrome/test/chromedriver/window_commands.h +++ b/chrome/test/chromedriver/window_commands.h
@@ -365,4 +365,35 @@ Status ProcessInputActionSequence(Session* session, const base::DictionaryValue* action_sequence, std::unique_ptr<base::ListValue>* result); + +Status ExecuteGetWindowRect(Session* session, + WebView* web_view, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value, + Timeout* timeout); + +Status ExecuteSetWindowRect(Session* session, + WebView* web_view, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value, + Timeout* timeout); + +Status ExecuteMaximizeWindow(Session* session, + WebView* web_view, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value, + Timeout* timeout); + +Status ExecuteMinimizeWindow(Session* session, + WebView* web_view, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value, + Timeout* timeout); + +Status ExecuteFullScreenWindow(Session* session, + WebView* web_view, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value, + Timeout* timeout); + #endif // CHROME_TEST_CHROMEDRIVER_WINDOW_COMMANDS_H_
diff --git a/chrome/test/data/extensions/api_test/automation/tests/tabs/bounds_for_range.js b/chrome/test/data/extensions/api_test/automation/tests/tabs/bounds_for_range.js index 243dd09..a029e1a6 100644 --- a/chrome/test/data/extensions/api_test/automation/tests/tabs/bounds_for_range.js +++ b/chrome/test/data/extensions/api_test/automation/tests/tabs/bounds_for_range.js
@@ -19,81 +19,95 @@ // Left-to-right. var ltr = getNthListItemInlineTextBox(0); - var bounds = ltr.location; - var firstHalf = ltr.boundsForRange(0, 4); - var secondHalf = ltr.boundsForRange(4, ltr.name.length); - assertEq(bounds.top, firstHalf.top); - assertEq(bounds.left, firstHalf.left); - assertEq(bounds.height, firstHalf.height); - assertEq(bounds.top, secondHalf.top); - assertEq(bounds.height, secondHalf.height); - assertTrue(secondHalf.left > bounds.left); - assertTrue(firstHalf.width < bounds.width); - assertTrue(secondHalf.width < bounds.width); - assertTrue(Math.abs(bounds.width - firstHalf.width - secondHalf.width) < 3); + ltr.boundsForRange( + 0, 4, + (firstHalf) => {ltr.boundsForRange(4, ltr.name.length, (secondHalf) => { + var bounds = ltr.location; + assertEq(bounds.top, firstHalf.top); + assertEq(bounds.left, firstHalf.left); + assertEq(bounds.height, firstHalf.height); + assertEq(bounds.top, secondHalf.top); + assertEq(bounds.height, secondHalf.height); + assertTrue(secondHalf.left > bounds.left); + assertTrue(firstHalf.width < bounds.width); + assertTrue(secondHalf.width < bounds.width); + assertTrue( + Math.abs(bounds.width - firstHalf.width - secondHalf.width) < 3); + })}); // Right-to-left. var rtl = getNthListItemInlineTextBox(1); bounds = rtl.location; - firstHalf = rtl.boundsForRange(0, 4); - secondHalf = rtl.boundsForRange(4, rtl.name.length); - assertEq(bounds.top, secondHalf.top); - assertTrue(Math.abs(bounds.left - secondHalf.left) < 3); - assertEq(bounds.height, secondHalf.height); - assertEq(bounds.top, firstHalf.top); - assertEq(bounds.height, firstHalf.height); - assertTrue(firstHalf.left > bounds.left); - assertTrue(secondHalf.width < bounds.width); - assertTrue(firstHalf.width < bounds.width); - assertTrue(Math.abs(bounds.width - secondHalf.width - firstHalf.width) < 3); + rtl.boundsForRange(0, 4, (firstHalf) => { + rtl.boundsForRange(4, rtl.name.length, (secondHalf) => { + assertEq(bounds.top, secondHalf.top); + assertTrue(Math.abs(bounds.left - secondHalf.left) < 3); + assertEq(bounds.height, secondHalf.height); + assertEq(bounds.top, firstHalf.top); + assertEq(bounds.height, firstHalf.height); + assertTrue(firstHalf.left > bounds.left); + assertTrue(secondHalf.width < bounds.width); + assertTrue(firstHalf.width < bounds.width); + assertTrue( + Math.abs(bounds.width - secondHalf.width - firstHalf.width) < 3); + }); + }); // Top-to-bottom. var ttb = getNthListItemInlineTextBox(2); var bounds = ttb.location; - var firstHalf = ttb.boundsForRange(0, 4); - var secondHalf = ttb.boundsForRange(4, ttb.name.length); - assertEq(bounds.left, firstHalf.left); - assertEq(bounds.top, firstHalf.top); - assertEq(bounds.width, firstHalf.width); - assertEq(bounds.left, secondHalf.left); - assertEq(bounds.width, secondHalf.width); - assertTrue(secondHalf.top > bounds.top); - assertTrue(firstHalf.height < bounds.height); - assertTrue(secondHalf.height < bounds.height); - assertTrue(Math.abs(bounds.height - firstHalf.height - secondHalf.height) - < 3); + ttb.boundsForRange(0, 4, (firstHalf) => { + ttb.boundsForRange(4, ttb.name.length, (secondHalf) => { + assertEq(bounds.left, firstHalf.left); + assertEq(bounds.top, firstHalf.top); + assertEq(bounds.width, firstHalf.width); + assertEq(bounds.left, secondHalf.left); + assertEq(bounds.width, secondHalf.width); + assertTrue(secondHalf.top > bounds.top); + assertTrue(firstHalf.height < bounds.height); + assertTrue(secondHalf.height < bounds.height); + assertTrue( + Math.abs(bounds.height - firstHalf.height - secondHalf.height) < 3); + }); + }); // Bottom-to-top. var btt = getNthListItemInlineTextBox(3); bounds = btt.location; - firstHalf = btt.boundsForRange(0, 4); - secondHalf = btt.boundsForRange(4, btt.name.length); - assertEq(bounds.left, secondHalf.left); - assertTrue(Math.abs(bounds.top - secondHalf.top) < 3); - assertEq(bounds.width, secondHalf.width); - assertEq(bounds.left, firstHalf.left); - assertEq(bounds.width, firstHalf.width); - assertTrue(firstHalf.top > bounds.top); - assertTrue(secondHalf.height < bounds.height); - assertTrue(firstHalf.height < bounds.height); - assertTrue(Math.abs(bounds.height - secondHalf.height - firstHalf.height) - < 3); - chrome.test.succeed(); + btt.boundsForRange(0, 4, (firstHalf) => { + btt.boundsForRange(4, btt.name.length, (secondHalf) => { + assertEq(bounds.left, secondHalf.left); + assertTrue(Math.abs(bounds.top - secondHalf.top) < 3); + assertEq(bounds.width, secondHalf.width); + assertEq(bounds.left, firstHalf.left); + assertEq(bounds.width, firstHalf.width); + assertTrue(firstHalf.top > bounds.top); + assertTrue(secondHalf.height < bounds.height); + assertTrue(firstHalf.height < bounds.height); + assertTrue( + Math.abs(bounds.height - secondHalf.height - firstHalf.height) < 3); + chrome.test.succeed(); + }); + }); }, function boundsForRangeClips() { let clipped = rootNode.find({attributes: {name: "This text overflows"}}); - let clippedBounds = clipped.boundsForRange(0, clipped.name.length); - assertTrue(clipped.parent.location.width < clipped.unclippedLocation.width); - assertEq(clipped.parent.location.width, clippedBounds.width); + clipped.boundsForRange(0, clipped.name.length, (clippedBounds) => { + assertTrue( + clipped.parent.location.width < clipped.unclippedLocation.width); + assertEq(clipped.parent.location.width, clippedBounds.width); + }); let hidden = rootNode.find({attributes: {name: "This text is hidden"}}); - let hiddenBounds = hidden.boundsForRange(0, hidden.name.length); - assertTrue(hidden.parent.location.width < hidden.unclippedLocation.width); - assertTrue(hidden.parent.location.height < hidden.unclippedLocation.height); - assertEq(hidden.parent.location.width, hiddenBounds.width); - assertEq(hidden.parent.location.height, hiddenBounds.height); + hidden.boundsForRange(0, hidden.name.length, (hiddenBounds) => { + assertTrue(hidden.parent.location.width < hidden.unclippedLocation.width); + assertTrue( + hidden.parent.location.height < hidden.unclippedLocation.height); + assertEq(hidden.parent.location.width, hiddenBounds.width); + assertEq(hidden.parent.location.height, hiddenBounds.height); + }); chrome.test.succeed(); }
diff --git a/chrome/test/data/extensions/api_test/webrequest/test_devtools.js b/chrome/test/data/extensions/api_test/webrequest/test_devtools.js index d7c9795f..74f45f5 100644 --- a/chrome/test/data/extensions/api_test/webrequest/test_devtools.js +++ b/chrome/test/data/extensions/api_test/webrequest/test_devtools.js
@@ -10,45 +10,11 @@ // To do so, we override logAllRequests=false from framework.js. logAllRequests = true; -// The URL that fakedevtools.html requests upon completion. This is used to -// detect when the DevTools resource has finished loading, because the requested -// front-end resources should not be visible in the webRequest API. +// The URL that fakedevtools.html requests upon completion. function getCompletionURL() { - // We do not care about the exact events, so use a non-existing extension - // resource because it produces only two events: onBeforeRequest and - // onErrorOccurred. return getURL('does_not_exist.html'); } -// The expected events when fakedevtools.html requests to |getCompletionURL()|. -function expectCompletionEvents() { - // These events are expected to occur. If that does not happen, check whether - // fakedevtools.html was actually loaded via the chrome-devtools:-URL. - expect( - [ - { - label: 'onBeforeRequest', - event: 'onBeforeRequest', - details: { - type: 'image', - url: getURL('does_not_exist.html'), - frameUrl: 'unknown frame URL', - }, - }, - { - label: 'onErrorOccurred', - event: 'onErrorOccurred', - details: { - type: 'image', - url: getURL('does_not_exist.html'), - fromCache: false, - error: 'net::ERR_FILE_NOT_FOUND', - } - }, - ], - [['onBeforeRequest', 'onErrorOccurred']]); -} - function expectNormalTabNavigationEvents(url) { var scriptUrl = new URL(url); var frontendHost = scriptUrl.hostname; @@ -352,16 +318,53 @@ ]]); } +var requestsIntercepted = []; +var onBeforeRequest = function(details) { + // Ignore favicon requests. + if (details.url.match(/\/favicon.ico$/)) + return; + + requestsIntercepted.push(details.url); +}; + +function addRequestListener() { + chrome.webRequest.onBeforeRequest.addListener( + onBeforeRequest, {urls: ['*://*/*']}, []); +}; + +function removeRequestListener() { + chrome.webRequest.onBeforeRequest.removeListener(onBeforeRequest); +}; + +function verifyInterceptedRequests(expectedRequests) { + chrome.test.assertEq( + expectedRequests, requestsIntercepted, + 'Expected: ' + JSON.stringify(expectedRequests) + + ' Actual: ' + JSON.stringify(requestsIntercepted)); + requestsIntercepted = []; +}; + runTests([ // Tests that chrome-devtools://devtools/custom/ is hidden from webRequest. function testDevToolsCustomFrontendRequest() { - expectCompletionEvents(); + // The extension shouldn't be able to observe the requests for the devtools + // resources. It should also not be able to intercept the request to the + // completion url, since it doesn't have access to the initiator + // chrome-devtools://devtools/. + var expectedRequests = []; + + addRequestListener(); + // DevToolsFrontendInWebRequestApuTest has set the kCustomDevtoolsFrontend // switch to the customfrontend/ subdirectory, so we do not include the path // name in the URL again. navigateAndWait( 'chrome-devtools://devtools/custom/fakedevtools.html#' + - getCompletionURL()); + getCompletionURL(), + chrome.test.callbackPass(() => { + verifyInterceptedRequests(expectedRequests); + removeRequestListener(); + })); }, // Tests that the custom front-end URL is visible in non-DevTools requests. @@ -375,10 +378,19 @@ // Tests that chrome-devtools://devtools/remote/ is hidden from webRequest. function testDevToolsRemoteFrontendRequest() { - expectCompletionEvents(); + // The extension shouldn't be able to observe the requests for the devtools + // resources. It should also not be able to intercept the request to the + // completion url, since it doesn't have access to the initiator + // chrome-devtools://devtools/. + var expectedRequests = []; + addRequestListener(); navigateAndWait( 'chrome-devtools://devtools/remote/devtoolsfrontend/fakedevtools.html' + - '#' + getCompletionURL()); + '#' + getCompletionURL(), + chrome.test.callbackPass(() => { + verifyInterceptedRequests(expectedRequests); + removeRequestListener(); + })); }, // Tests that the custom front-end URL is visible in non-DevTools requests.
diff --git a/chrome/test/data/extensions/api_test/webrequest_permissions/initiator/background.js b/chrome/test/data/extensions/api_test/webrequest_permissions/initiator/background.js index 56fd3c2..e69c230 100644 --- a/chrome/test/data/extensions/api_test/webrequest_permissions/initiator/background.js +++ b/chrome/test/data/extensions/api_test/webrequest_permissions/initiator/background.js
@@ -1,10 +1,11 @@ // 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. +var requestsIntercepted = 0; chrome.webRequest.onBeforeRequest.addListener((details) => { - chrome.test.sendMessage( - (details.initiator === undefined) ? 'NO_INITIATOR' : details.initiator); + requestsIntercepted++; + chrome.test.sendMessage(details.initiator); }, {urls: ['*://*/extensions/api_test/webrequest/xhr/data.json']}, []); chrome.test.sendMessage('ready');
diff --git a/chrome/test/data/extensions/api_test/webrequest_permissions/initiator/manifest.json b/chrome/test/data/extensions/api_test/webrequest_permissions/initiator/manifest.json index 7ba8e971..bb1b169 100644 --- a/chrome/test/data/extensions/api_test/webrequest_permissions/initiator/manifest.json +++ b/chrome/test/data/extensions/api_test/webrequest_permissions/initiator/manifest.json
@@ -2,7 +2,7 @@ "name": "webRequest permissions initiator", "version": "1.0", "manifest_version": 2, - "description": "Tests circumstances of exposing initiator in webRequest API.", + "description": "Tests that an extension needs access to the request initiator", "permissions": [ "webRequest", "*://*.example.com/*",
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 94d67d4..03f5c02 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -3427,6 +3427,20 @@ "test_policy": { "DisplayRotationDefault": 1 } }, + "DeviceDisplayResolution": { + "os": ["chromeos"], + "can_be_recommended": false, + "test_policy": { + "DeviceDisplayResolution": { + "external_width": 1920, + "external_height": 1080, + "external_scale_percentage": 100, + "internal_scale_percentage": 50, + "recommended": true + } + } + }, + "ChromeOsReleaseChannel": { },
diff --git a/chrome/test/data/webui/md_bookmarks/.eslintrc.js b/chrome/test/data/webui/md_bookmarks/.eslintrc.js index 4cbd5cf8..a8aaea1 100644 --- a/chrome/test/data/webui/md_bookmarks/.eslintrc.js +++ b/chrome/test/data/webui/md_bookmarks/.eslintrc.js
@@ -3,6 +3,9 @@ // found in the LICENSE file. module.exports = { + 'parserOptions': { + 'ecmaVersion': 2017, + }, 'rules': { 'no-var': 'error', },
diff --git a/chrome/test/data/webui/md_bookmarks/app_test.js b/chrome/test/data/webui/md_bookmarks/app_test.js index ddc5cf2..84562f0 100644 --- a/chrome/test/data/webui/md_bookmarks/app_test.js +++ b/chrome/test/data/webui/md_bookmarks/app_test.js
@@ -69,25 +69,24 @@ assertEquals(sidebarWidth, app.$.sidebar.style.width); }); - test('focus ring hides and restores', function() { - return PolymerTest.flushTasks().then(() => { - const list = app.$$('bookmarks-list'); - const item = list.root.querySelectorAll('bookmarks-item')[0]; - const getFocusAttribute = () => - app.getAttribute(bookmarks.HIDE_FOCUS_RING_ATTRIBUTE); + test('focus ring hides and restores', async function() { + await PolymerTest.flushTasks(); + const list = app.$$('bookmarks-list'); + const item = list.root.querySelectorAll('bookmarks-item')[0]; + const getFocusAttribute = () => + app.getAttribute(bookmarks.HIDE_FOCUS_RING_ATTRIBUTE); - assertEquals(null, getFocusAttribute()); + assertEquals(null, getFocusAttribute()); - MockInteractions.tap(item); - assertEquals('', getFocusAttribute()); + MockInteractions.tap(item); + assertEquals('', getFocusAttribute()); - MockInteractions.keyDownOn(item, 16, [], 'Shift'); - assertEquals('', getFocusAttribute()); + MockInteractions.keyDownOn(item, 16, [], 'Shift'); + assertEquals('', getFocusAttribute()); - // This event is also captured by the bookmarks-list and propagation is - // stopped. Regardless, it should clear the focus first. - MockInteractions.keyDownOn(item, 40, [], 'ArrowDown'); - assertEquals(null, getFocusAttribute()); - }); + // This event is also captured by the bookmarks-list and propagation is + // stopped. Regardless, it should clear the focus first. + MockInteractions.keyDownOn(item, 40, [], 'ArrowDown'); + assertEquals(null, getFocusAttribute()); }); });
diff --git a/chrome/test/data/webui/md_bookmarks/command_manager_test.js b/chrome/test/data/webui/md_bookmarks/command_manager_test.js index fe20ecd..b2a1f4c 100644 --- a/chrome/test/data/webui/md_bookmarks/command_manager_test.js +++ b/chrome/test/data/webui/md_bookmarks/command_manager_test.js
@@ -616,26 +616,24 @@ }); } - suiteSetup(function() { + suiteSetup(async function() { const testFolder = { parentId: '1', title: 'Test', }; - return create(testFolder).then(function(testFolderNode) { - testFolderId = testFolderNode.id; - const testItem = { - parentId: testFolderId, - title: 'Test bookmark', - url: 'https://www.example.com/', - }; - return Promise.all([ - create(testItem), - create(testItem), - ]); - }); + const testFolderNode = await create(testFolder); + testFolderId = testFolderNode.id; + const testItem = { + parentId: testFolderId, + title: 'Test bookmark', + url: 'https://www.example.com/', + }; + + await create(testItem); + await create(testItem); }); - setup(function() { + setup(async function() { store = new bookmarks.TestStore({}); store.replaceSingleton(); store.setReducersEnabled(true); @@ -645,12 +643,12 @@ commandManager = bookmarks.CommandManager.getInstance(); - return promise.then(() => { - store.dispatch(bookmarks.actions.selectFolder(testFolderId)); - }); + await promise; + + store.dispatch(bookmarks.actions.selectFolder(testFolderId)); }); - test('paste selects newly created items', function() { + test('paste selects newly created items', async function() { const displayedIdsBefore = bookmarks.util.getDisplayedList(store.data); commandManager.handle(Command.SELECT_ALL, new Set()); commandManager.handle(Command.COPY, new Set(displayedIdsBefore)); @@ -658,20 +656,20 @@ store.expectAction('select-items'); commandManager.handle(Command.PASTE, new Set()); - return store.waitForAction('select-items').then(function(action) { - const displayedIdsAfter = bookmarks.util.getDisplayedList(store.data); - assertEquals(4, displayedIdsAfter.length); + const action = await store.waitForAction('select-items'); - // The start of the list shouldn't change. - assertEquals(displayedIdsBefore[0], displayedIdsAfter[0]); - assertEquals(displayedIdsBefore[1], displayedIdsAfter[1]); + const displayedIdsAfter = bookmarks.util.getDisplayedList(store.data); + assertEquals(4, displayedIdsAfter.length); - // The two pasted items should be selected at the end of the list. - assertEquals(action.items[0], displayedIdsAfter[2]); - assertEquals(action.items[1], displayedIdsAfter[3]); - assertEquals(2, action.items.length); - assertEquals(action.anchor, displayedIdsAfter[2]); - }); + // The start of the list shouldn't change. + assertEquals(displayedIdsBefore[0], displayedIdsAfter[0]); + assertEquals(displayedIdsBefore[1], displayedIdsAfter[1]); + + // The two pasted items should be selected at the end of the list. + assertEquals(action.items[0], displayedIdsAfter[2]); + assertEquals(action.items[1], displayedIdsAfter[3]); + assertEquals(2, action.items.length); + assertEquals(action.anchor, displayedIdsAfter[2]); }); suiteTeardown(function(done) {
diff --git a/chrome/test/data/webui/md_bookmarks/md_bookmarks_focus_test.js b/chrome/test/data/webui/md_bookmarks/md_bookmarks_focus_test.js index b3ee492..007f5d9 100644 --- a/chrome/test/data/webui/md_bookmarks/md_bookmarks_focus_test.js +++ b/chrome/test/data/webui/md_bookmarks/md_bookmarks_focus_test.js
@@ -494,7 +494,7 @@ bookmarks.DialogFocusManager.instance_ = dialogFocusManager; }); - test('restores focus on dialog dismissal', function() { + test('restores focus on dialog dismissal', async function() { const focusedItem = items[0]; focusedItem.focus(); assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); @@ -508,17 +508,15 @@ keydown(dropdown, 'Escape'); assertFalse(dropdown.open); - return Promise - .all([ - test_util.eventToPromise('close', dropdown), - test_util.eventToPromise('focus', focusedItem), - ]) - .then(() => { - assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); - }); + await Promise.all([ + test_util.eventToPromise('close', dropdown), + test_util.eventToPromise('focus', focusedItem), + ]); + + assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); }); - test('restores focus after stacked dialogs', function() { + test('restores focus after stacked dialogs', async () => { const focusedItem = items[0]; focusedItem.focus(); assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); @@ -531,20 +529,15 @@ const editDialog = commandManager.$.editDialog.get(); editDialog.showEditDialog(store.data.nodes['2']); - return test_util.eventToPromise('close', dropdown) - .then(() => { - editDialog.onCancelButtonTap_(); - assertNotEquals( - focusedItem, dialogFocusManager.getFocusedElement_()); + await test_util.eventToPromise('close', dropdown); + editDialog.onCancelButtonTap_(); + assertNotEquals(focusedItem, dialogFocusManager.getFocusedElement_()); - return test_util.eventToPromise('close', editDialog); - }) - .then(() => { - assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); - }); + await test_util.eventToPromise('close', editDialog); + assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); }); - test('restores focus after multiple shows of same dialog', function() { + test('restores focus after multiple shows of same dialog', async () => { let focusedItem = items[0]; focusedItem.focus(); assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); @@ -558,18 +551,13 @@ focusedItem.focus(); commandManager.openCommandMenuAtPosition(0, 0, MenuSource.ITEM); - return test_util.eventToPromise('close', dropdown) - .then(() => { - assertTrue(dropdown.open); - dropdown.close(); - assertNotEquals( - focusedItem, dialogFocusManager.getFocusedElement_()); + await test_util.eventToPromise('close', dropdown); + assertTrue(dropdown.open); + dropdown.close(); + assertNotEquals(focusedItem, dialogFocusManager.getFocusedElement_()); - return test_util.eventToPromise('close', dropdown); - }) - .then(() => { - assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); - }); + await test_util.eventToPromise('close', dropdown); + assertEquals(focusedItem, dialogFocusManager.getFocusedElement_()); }); });
diff --git a/chrome/test/data/webui/md_bookmarks/policy_test.js b/chrome/test/data/webui/md_bookmarks/policy_test.js index 0896e5f..8d000ac 100644 --- a/chrome/test/data/webui/md_bookmarks/policy_test.js +++ b/chrome/test/data/webui/md_bookmarks/policy_test.js
@@ -24,44 +24,31 @@ replaceBody(app); }); - test('incognito availability updates when changed', function() { + test('incognito availability updates when changed', async function() { const commandManager = bookmarks.CommandManager.getInstance(); // Incognito is disabled during testGenPreamble(). Wait for the front-end to // load the config. - return store.waitForAction('set-incognito-availability') - .then(action => { - assertEquals( - IncognitoAvailability.DISABLED, - store.data.prefs.incognitoAvailability); - assertFalse(commandManager.canExecute( - Command.OPEN_INCOGNITO, new Set(['11']))); + const action = await store.waitForAction('set-incognito-availability'); + assertEquals( + IncognitoAvailability.DISABLED, store.data.prefs.incognitoAvailability); + assertFalse( + commandManager.canExecute(Command.OPEN_INCOGNITO, new Set(['11']))); - return cr.sendWithPromise( - 'testSetIncognito', IncognitoAvailability.ENABLED); - }) - .then(() => { - assertEquals( - IncognitoAvailability.ENABLED, - store.data.prefs.incognitoAvailability); - assertTrue(commandManager.canExecute( - Command.OPEN_INCOGNITO, new Set(['11']))); - }); + await cr.sendWithPromise('testSetIncognito', IncognitoAvailability.ENABLED); + assertEquals( + IncognitoAvailability.ENABLED, store.data.prefs.incognitoAvailability); + assertTrue( + commandManager.canExecute(Command.OPEN_INCOGNITO, new Set(['11']))); }); - test('canEdit updates when changed', function() { + test('canEdit updates when changed', async function() { const commandManager = bookmarks.CommandManager.getInstance(); - return store.waitForAction('set-can-edit') - .then(action => { - assertFalse(store.data.prefs.canEdit); - assertFalse( - commandManager.canExecute(Command.DELETE, new Set(['11']))); + let action = await store.waitForAction('set-can-edit'); + assertFalse(store.data.prefs.canEdit); + assertFalse(commandManager.canExecute(Command.DELETE, new Set(['11']))); - return cr.sendWithPromise('testSetCanEdit', true); - }) - .then(() => { - assertTrue(store.data.prefs.canEdit); - assertTrue( - commandManager.canExecute(Command.DELETE, new Set(['11']))); - }); + await cr.sendWithPromise('testSetCanEdit', true); + assertTrue(store.data.prefs.canEdit); + assertTrue(commandManager.canExecute(Command.DELETE, new Set(['11']))); }); });
diff --git a/chrome/test/data/webui/md_bookmarks/router_test.js b/chrome/test/data/webui/md_bookmarks/router_test.js index 276e080..c28109af 100644 --- a/chrome/test/data/webui/md_bookmarks/router_test.js +++ b/chrome/test/data/webui/md_bookmarks/router_test.js
@@ -39,37 +39,31 @@ assertEquals('2', store.lastAction.id); }); - test('route updates from ID', function() { + test('route updates from ID', async function() { store.data.selectedFolder = '2'; store.notifyObservers(); - return Promise.resolve() - .then(function() { - assertEquals('chrome://bookmarks/?id=2', window.location.href); - store.data.selectedFolder = '1'; - store.notifyObservers(); - }) - .then(function() { - // Selecting Bookmarks bar clears route. - assertEquals('chrome://bookmarks/', window.location.href); - }); + await PolymerTest.flushTasks(); + assertEquals('chrome://bookmarks/?id=2', window.location.href); + store.data.selectedFolder = '1'; + store.notifyObservers(); + await PolymerTest.flushTasks(); + // Selecting Bookmarks bar clears route. + assertEquals('chrome://bookmarks/', window.location.href); }); - test('route updates from search', function() { + test('route updates from search', async function() { store.data.search = {term: 'bloop'}; store.notifyObservers(); + await PolymerTest.flushTasks(); - return Promise.resolve() - .then(function() { - assertEquals('chrome://bookmarks/?q=bloop', window.location.href); + assertEquals('chrome://bookmarks/?q=bloop', window.location.href); - // Ensure that the route doesn't change when the search finishes. - store.data.selectedFolder = null; - store.notifyObservers(); - }) - .then(function() { - assertEquals('chrome://bookmarks/?q=bloop', window.location.href); - }); + // Ensure that the route doesn't change when the search finishes. + store.data.selectedFolder = null; + store.notifyObservers(); + await PolymerTest.flushTasks(); + assertEquals('chrome://bookmarks/?q=bloop', window.location.href); }); test('bookmarks bar selected with empty route', function() {
diff --git a/chrome/test/data/webui/md_bookmarks/test_store.js b/chrome/test/data/webui/md_bookmarks/test_store.js index 136f188..278d4070 100644 --- a/chrome/test/data/webui/md_bookmarks/test_store.js +++ b/chrome/test/data/webui/md_bookmarks/test_store.js
@@ -104,14 +104,13 @@ * @param {string} name * @return {!Promise<!Action>} */ - waitForAction(name) { + async waitForAction(name) { assertTrue( this.resolverMap_.has(name), 'Must call expectAction before each call to waitForAction'); - return this.resolverMap_.get(name).promise.then((action) => { - this.resolverMap_.delete(name); - return action; - }); + const action = await this.resolverMap_.get(name).promise; + this.resolverMap_.delete(name); + return action; } }
diff --git a/chrome/test/data/webui/menu_test.html b/chrome/test/data/webui/menu_test.html index 6d26cc3..e242fa9 100644 --- a/chrome/test/data/webui/menu_test.html +++ b/chrome/test/data/webui/menu_test.html
@@ -63,6 +63,93 @@ assertTrue(mouseUpAt(0, 0)); } +/** + * Tests that if the command attributes are spacified, they are copied to the + * corresponding menuitem. + */ +function testCommandMenuItem() { + // Test 1: The case that the command label is set and other attributes copied. + var command = new cr.ui.Command(); + command.id = 'the-command'; + command.label = 'CommandLabel'; + command.disabled = true; + command.hidden = true; + command.checked = true; + document.body.appendChild(command); + + var menuItem = new cr.ui.MenuItem(); + menuItem.command = '#the-command'; + + // Confirms the label is copied from the command. + assertEquals('CommandLabel', menuItem.label); + // Confirms the attributes are copied from the command. + assertEquals(true, menuItem.disabled); + assertEquals(true, menuItem.hidden); + assertEquals(true, menuItem.checked); + + // Test 2: The case that the command label is not set, and other attributes + // have default values. + var command2 = new cr.ui.Command(); + command2.id = 'the-command2'; + document.body.appendChild(command2); + + var menuItem2 = new cr.ui.MenuItem(); + menuItem2.label = 'MenuLabel'; + menuItem2.command = '#the-command2'; + + // Confirms the label is not copied, keeping the original label. + assertEquals('MenuLabel', menuItem2.label); + // Confirms the attributes are copied from the command. + assertEquals(false, menuItem2.disabled); + assertEquals(false, menuItem2.hidden); + assertEquals(false, menuItem2.checked); +} + +/** + * Mark all menu items other than |hiddenItems| as visible and check that the + * expected number of separators are visible. + */ +function runSeparatorTest(items, hiddenItems, expectedSeparators) { + for (let item of menu.menuItems) { + item.hidden = false; + } + for (let i of hiddenItems) { + items[i].hidden = true; + } + menu.updateCommands(); + assertEquals(hiddenItems.length != items.length, menu.hasVisibleItems()); + assertEquals(expectedSeparators, + menu.querySelectorAll('hr:not([hidden])').length); + + // The separators at the ends are always hidden. + assertTrue(menu.menuItems[0].hidden); + assertTrue(menu.menuItems[6].hidden); +} + +/** + * Tests that separators are only displayed when there is a visible + * non-separator item on both sides of it. Further, ensure that multiple + * separators will not be displayed adjacent to each other. + */ +function testSeparators() { + const menuItems = []; + menu.addSeparator(); + menuItems.push(menu.addMenuItem({label: 'a'})); + menu.addSeparator(); + menuItems.push(menu.addMenuItem({label: 'b'})); + menu.addSeparator(); + menuItems.push(menu.addMenuItem({label: 'c'})); + menu.addSeparator(); + + runSeparatorTest(menuItems, [0, 1, 2], 0); + runSeparatorTest(menuItems, [0, 1], 0); + runSeparatorTest(menuItems, [0, 2], 0); + runSeparatorTest(menuItems, [1, 2], 0); + runSeparatorTest(menuItems, [0], 1); + runSeparatorTest(menuItems, [1], 1); + runSeparatorTest(menuItems, [2], 1); + runSeparatorTest(menuItems, [], 2); +} </script> </body> </html>
diff --git a/chrome/test/data/webui/settings/people_page_sync_page_test.js b/chrome/test/data/webui/settings/people_page_sync_page_test.js index 92fa740a..9f4a508 100644 --- a/chrome/test/data/webui/settings/people_page_sync_page_test.js +++ b/chrome/test/data/webui/settings/people_page_sync_page_test.js
@@ -74,10 +74,9 @@ // Tests the initial layout of the sync section and the personalize section, // depending on the sync state and the unified consent state. function testInitialLayout( - unifiedConsentGiven, signedIn, hasError, setupInProgress, - syncSectionExpanded, syncSectionDisabled, personalizeSectionExpanded) { + signedIn, hasError, setupInProgress, syncSectionExpanded, + syncSectionDisabled, personalizeSectionExpanded) { syncPage.unifiedConsentEnabled = true; - syncPage.prefs = {unified_consent_given: {value: unifiedConsentGiven}}; syncPage.syncStatus = { signedIn: signedIn, disabled: false, @@ -95,9 +94,7 @@ syncPage.$$('#personalize-section-toggle'); const personalizeSectionExpandIcon = personalizeSectionToggle.querySelector('cr-expand-button'); - const unifiedConsentToggle = syncPage.$$('#unifiedConsentToggle'); - assertTrue(unifiedConsentToggle.checked == unifiedConsentGiven); assertTrue(syncSectionExpandIcon.expanded == syncSectionExpanded); assertTrue(syncSectionExpandIcon.disabled == syncSectionDisabled); assertTrue( @@ -177,7 +174,6 @@ const ironCollapse = syncPage.$$('#sync-section'); const otherItems = syncPage.$$('#other-sync-items'); const syncSectionToggle = syncPage.$$('#sync-section-toggle'); - const unifiedConsentToggle = syncPage.$$('#unifiedConsentToggle'); // When unified-consent is disabled and signed in, sync-section should be // visible and open by default. Accordion toggle row should not be present @@ -190,9 +186,6 @@ assertTrue(syncSectionToggle.hidden); assertFalse(otherItems.classList.contains('list-frame')); assertFalse(!!otherItems.querySelector('list-item')); - - // The unified consent toggle should be hidden. - assertTrue(unifiedConsentToggle.hidden); }); test('SyncSectionLayout_UnifiedConsentEnabled_SignedIn', function() { @@ -200,7 +193,6 @@ const otherItems = syncPage.$$('#other-sync-items'); const syncSectionToggle = syncPage.$$('#sync-section-toggle'); const expandIcon = syncSectionToggle.querySelector('cr-expand-button'); - const unifiedConsentToggle = syncPage.$$('#unifiedConsentToggle'); // When unified-consent is enabled and signed in, sync-section should be // visible and open by default. Accordion toggle row should be present, @@ -246,9 +238,6 @@ assertTrue(ironCollapse.opened); assertTrue(expandIcon.expanded); - // The unified consent toggle should be visible. - assertFalse(unifiedConsentToggle.hidden); - // Test sync paused state. syncPage.syncStatus = { signedIn: true, @@ -268,30 +257,6 @@ assertFalse(ironCollapse.hidden); }); - test( - 'UnifiedConsentToggleNotifiesHandler_UnifiedConsentEnabled', - function() { - const unifiedConsentToggle = syncPage.$$('#unifiedConsentToggle'); - syncPage.syncStatus = { - signedIn: true, - disabled: false, - hasError: false, - statusAction: settings.StatusAction.NO_ACTION, - }; - syncPage.unifiedConsentEnabled = true; - Polymer.dom.flush(); - - assertFalse(unifiedConsentToggle.hidden); - assertFalse(unifiedConsentToggle.checked); - - unifiedConsentToggle.click(); - - return browserProxy.whenCalled('unifiedConsentToggleChanged') - .then(toggleChecked => { - assertTrue(toggleChecked); - }); - }); - test('SyncSectionLayout_UnifiedConsentEnabled_SignoutCollapse', function() { const ironCollapse = syncPage.$$('#sync-section'); const syncSectionToggle = syncPage.$$('#sync-section-toggle'); @@ -334,7 +299,6 @@ const ironCollapse = syncPage.$$('#sync-section'); const syncSectionToggle = syncPage.$$('#sync-section-toggle'); const expandIcon = syncSectionToggle.querySelector('cr-expand-button'); - const unifiedConsentToggle = syncPage.$$('#unifiedConsentToggle'); // When unified-consent is enabled and signed out, sync-section should be // hidden, and the accordion toggle row should be visible not actionable. @@ -351,15 +315,11 @@ assertFalse(syncSectionToggle.hasAttribute('actionable')); assertFalse(expandIcon.expanded); assertTrue(expandIcon.disabled); - - // The unified consent toggle should be hidden. - assertTrue(unifiedConsentToggle.hidden); }); test('SyncSectionLayout_UnifiedConsentEnabled_SyncDisabled', function() { const ironCollapse = syncPage.$$('#sync-section'); const syncSectionToggle = syncPage.$$('#sync-section-toggle'); - const unifiedConsentToggle = syncPage.$$('#unifiedConsentToggle'); // When unified-consent is enabled and sync is disabled, the sync-section // should be hidden. @@ -373,47 +333,10 @@ Polymer.dom.flush(); assertTrue(ironCollapse.hidden); assertTrue(syncSectionToggle.hidden); - - // The unified consent toggle should be hidden. - assertTrue(unifiedConsentToggle.hidden); }); - test('InitialLayout_UnifiedConsentGiven_SignedIn', function() { + test('InitialLayout_UnifiedConsent_SignedIn', function() { testInitialLayout( - /*unifiedConsentGiven=*/true, - /*signedIn=*/true, - /*hasError=*/false, - /*setupInProgress=*/false, - /*syncSectionExpanded=*/false, - /*syncSectionDisabled=*/false, - /*personalizeSectionExpanded=*/false); - }); - - test('InitialLayout_UnifiedConsentGiven_SignedOut', function() { - testInitialLayout( - /*unifiedConsentGiven=*/true, - /*signedIn=*/false, - /*hasError=*/false, - /*setupInProgress=*/false, - /*syncSectionExpanded=*/false, - /*syncSectionDisabled=*/true, - /*personalizeSectionExpanded=*/false); - }); - - test('InitialLayout_UnifiedConsentGiven_SyncPaused', function() { - testInitialLayout( - /*unifiedConsentGiven=*/true, - /*signedIn=*/true, - /*hasError=*/true, - /*setupInProgress=*/false, - /*syncSectionExpanded=*/false, - /*syncSectionDisabled=*/true, - /*personalizeSectionExpanded=*/false); - }); - - test('InitialLayout_NoUnifiedConsentGiven_SignedIn', function() { - testInitialLayout( - /*unifiedConsentGiven=*/false, /*signedIn=*/true, /*hasError=*/false, /*setupInProgress=*/false, @@ -422,9 +345,8 @@ /*personalizeSectionExpanded=*/true); }); - test('InitialLayout_NoUnifiedConsentGiven_SignedOut', function() { + test('InitialLayout_UnifiedConsent_SignedOut', function() { testInitialLayout( - /*unifiedConsentGiven=*/false, /*signedIn=*/false, /*hasError=*/false, /*setupInProgress=*/false, @@ -433,9 +355,8 @@ /*personalizeSectionExpanded=*/true); }); - test('InitialLayout_NoUnifiedConsentGiven_SyncPaused', function() { + test('InitialLayout_UnifiedConsent_SyncPaused', function() { testInitialLayout( - /*unifiedConsentGiven=*/false, /*signedIn=*/true, /*hasError=*/true, /*setupInProgress=*/false, @@ -444,17 +365,6 @@ /*personalizeSectionExpanded=*/true); }); - test('InitialLayout_SetupInProgress', function() { - testInitialLayout( - /*unifiedConsentGiven=*/true, - /*signedIn=*/true, - /*hasError=*/false, - /*setupInProgress=*/true, - /*syncSectionExpanded=*/true, - /*syncSectionDisabled=*/false, - /*personalizeSectionExpanded=*/true); - }); - test('LoadingAndTimeout', function() { const configurePage = syncPage.$$('#' + settings.PageStatus.CONFIGURE); const spinnerPage = syncPage.$$('#' + settings.PageStatus.SPINNER);
diff --git a/chrome/test/data/webui/settings/personalization_options_test.js b/chrome/test/data/webui/settings/personalization_options_test.js index e6e5761..1a4e3e6 100644 --- a/chrome/test/data/webui/settings/personalization_options_test.js +++ b/chrome/test/data/webui/settings/personalization_options_test.js
@@ -35,7 +35,7 @@ testElement.root.querySelectorAll('settings-toggle-button').length); }); - test('hide spellcheck toggle when there is no dictionary', function() { + test('UnifiedConsent spellcheck toggle', function() { testElement.unifiedConsentEnabled = true; testElement.prefs = {spellcheck: {dictionaries: {value: ['en-US']}}}; Polymer.dom.flush(); @@ -45,5 +45,16 @@ Polymer.dom.flush(); assertTrue(testElement.$.spellCheckControl.hidden); }); + + test('NoUnifiedConsent spellcheck toggle', function() { + testElement.unifiedConsentEnabled = false; + testElement.prefs = {spellcheck: {dictionaries: {value: ['en-US']}}}; + Polymer.dom.flush(); + assertFalse(testElement.$.spellCheckControl.hidden); + + testElement.prefs = {spellcheck: {dictionaries: {value: []}}}; + Polymer.dom.flush(); + assertFalse(testElement.$.spellCheckControl.hidden); + }); }); });
diff --git a/chrome/test/data/webui/settings/test_sync_browser_proxy.js b/chrome/test/data/webui/settings/test_sync_browser_proxy.js index f272ce07..efcfd55 100644 --- a/chrome/test/data/webui/settings/test_sync_browser_proxy.js +++ b/chrome/test/data/webui/settings/test_sync_browser_proxy.js
@@ -18,7 +18,6 @@ 'pauseSync', 'startSignIn', 'startSyncingWithEmail', - 'unifiedConsentToggleChanged', ]); /** @private {number} */ @@ -96,9 +95,4 @@ this.methodCalled('setSyncEncryption', syncPrefs); return Promise.resolve(this.encryptionResponse); } - - /** @override */ - unifiedConsentToggleChanged(toggleChecked) { - this.methodCalled('unifiedConsentToggleChanged', toggleChecked); - } }
diff --git a/chrome/test/mini_installer/create_zip.py b/chrome/test/mini_installer/create_zip.py index 993d8c9..e6c7fae 100644 --- a/chrome/test/mini_installer/create_zip.py +++ b/chrome/test/mini_installer/create_zip.py
@@ -105,7 +105,7 @@ if args.installer_path: installer_name = os.path.split(args.installer_path)[-1] run_args.append('--installer-path=' + installer_name) - logging.info('Archiving: %s', installer_name) + logging.debug('Archiving: %s', installer_name) zipf.write(args.installer_path, installer_name) if args.previous_version_installer_path: @@ -113,14 +113,14 @@ args.previous_version_installer_path)[-1] run_args.append( '--previous-version-installer-path=' + previous_version_installer_name) - logging.info('Archiving: %s', previous_version_installer_name) + logging.debug('Archiving: %s', previous_version_installer_name) zipf.write( args.previous_version_installer_path, previous_version_installer_name) if args.chromedriver_path: chromedriver_name = os.path.split(args.chromedriver_path)[-1] run_args.append('--chromedriver-path=' + chromedriver_name) - logging.info('Archiving: %s', chromedriver_name) + logging.debug('Archiving: %s', chromedriver_name) zipf.write( args.chromedriver_path, chromedriver_name) @@ -133,11 +133,11 @@ os.path.split('README.txt')[-1]) # Archive this and the chromedriver code directories - logging.info('Zipping chrome/test/mini_installer') + logging.debug('Zipping chrome/test/mini_installer') ArchiveDirectory(THIS_DIR, zipf) - logging.info('Zipping third_party/webdriver/pylib') + logging.debug('Zipping third_party/webdriver/pylib') ArchiveDirectory(SELENIUM_PATH, zipf) - logging.info('Wrote zip to %s', args.output_path) + logging.debug('Wrote zip to %s', args.output_path) return 0
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc index 6b50ad865..8cf25b4 100644 --- a/chrome/utility/chrome_content_utility_client.cc +++ b/chrome/utility/chrome_content_utility_client.cc
@@ -300,13 +300,6 @@ #if defined(OS_CHROMEOS) // TODO(jamescook): Figure out why we have to do this when not using mash. mash_service_factory_->RegisterOutOfProcessServices(services); - - { - service_manager::EmbeddedServiceInfo service_info; - service_info.factory = - base::BindRepeating(&chromeos::ime::CreateImeService); - services->emplace(chromeos::ime::mojom::kServiceName, service_info); - } #endif #if BUILDFLAG(ENABLE_SIMPLE_BROWSER_SERVICE_OUT_OF_PROCESS) @@ -335,7 +328,15 @@ return std::make_unique<patch::PatchService>(std::move(request)); #endif +#if defined(OS_CHROMEOS) + if (service_name == chromeos::ime::mojom::kServiceName) + return std::make_unique<chromeos::ime::ImeService>(std::move(request)); + + return mash_service_factory_->HandleServiceRequest(service_name, + std::move(request)); +#else return nullptr; +#endif } void ChromeContentUtilityClient::RegisterNetworkBinders(
diff --git a/chrome/utility/mash_service_factory.cc b/chrome/utility/mash_service_factory.cc index 6d32dc7..33e067a 100644 --- a/chrome/utility/mash_service_factory.cc +++ b/chrome/utility/mash_service_factory.cc
@@ -57,10 +57,12 @@ return std::make_unique<ash::AshService>(); } -std::unique_ptr<service_manager::Service> CreateQuickLaunchApp() { +std::unique_ptr<service_manager::Service> CreateQuickLaunchService( + service_manager::mojom::ServiceRequest request) { RecordMashServiceLaunch(MashService::kQuickLaunch); logging::SetLogPrefix("quick"); - return std::make_unique<quick_launch::QuickLaunchApplication>(); + return std::make_unique<quick_launch::QuickLaunchApplication>( + std::move(request)); } std::unique_ptr<service_manager::Service> CreateShortcutViewerApp() { @@ -84,8 +86,6 @@ void MashServiceFactory::RegisterOutOfProcessServices( content::ContentUtilityClient::StaticServiceMap* services) { - RegisterMashService(services, quick_launch::mojom::kServiceName, - &CreateQuickLaunchApp); RegisterMashService(services, ash::mojom::kServiceName, &CreateAshService); RegisterMashService(services, shortcut_viewer::mojom::kServiceName, &CreateShortcutViewerApp); @@ -94,3 +94,13 @@ keyboard_shortcut_viewer::ShortcutViewerApplication::RegisterForTraceEvents(); } + +std::unique_ptr<service_manager::Service> +MashServiceFactory::HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) { + if (service_name == quick_launch::mojom::kServiceName) + return CreateQuickLaunchService(std::move(request)); + + return nullptr; +}
diff --git a/chrome/utility/mash_service_factory.h b/chrome/utility/mash_service_factory.h index 6f40dca..95d09c5 100644 --- a/chrome/utility/mash_service_factory.h +++ b/chrome/utility/mash_service_factory.h
@@ -6,6 +6,11 @@ #define CHROME_UTILITY_MASH_SERVICE_FACTORY_H_ #include "content/public/utility/content_utility_client.h" +#include "services/service_manager/public/mojom/service.mojom.h" + +namespace service_manager { +class Service; +} // Lives on the utility process main thread. class MashServiceFactory { @@ -17,6 +22,12 @@ void RegisterOutOfProcessServices( content::ContentUtilityClient::StaticServiceMap* services); + // Handles an incoming service request for this utility process. Returns + // null if the named service is unknown or cannot be created. + std::unique_ptr<service_manager::Service> HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request); + private: DISALLOW_COPY_AND_ASSIGN(MashServiceFactory); };
diff --git a/chromecast/browser/android/BUILD.gn b/chromecast/browser/android/BUILD.gn index 07349457..cb471e6 100644 --- a/chromecast/browser/android/BUILD.gn +++ b/chromecast/browser/android/BUILD.gn
@@ -118,7 +118,7 @@ "$java_src_dir/org/chromium/chromecast/shell/CastWebContentsIntentUtils.java", "$java_src_dir/org/chromium/chromecast/shell/CastWebContentsService.java", "$java_src_dir/org/chromium/chromecast/shell/CastWebContentsSurfaceHelper.java", - "$java_src_dir/org/chromium/chromecast/shell/CastWebContentsView.java", + "$java_src_dir/org/chromium/chromecast/shell/CastWebContentsScopes.java", "$java_src_dir/org/chromium/chromecast/shell/LogcatElision.java", "$java_src_dir/org/chromium/chromecast/shell/ElidedLogcatProvider.java", ]
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java index 622fb1b1..083b616 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
@@ -11,6 +11,7 @@ import android.media.AudioManager; import android.net.Uri; import android.os.Bundle; +import android.support.annotation.Nullable; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; @@ -60,6 +61,7 @@ // Set at creation. Handles destroying SurfaceHelper. private final Controller<CastWebContentsSurfaceHelper> mSurfaceHelperState = new Controller<>(); + @Nullable private CastWebContentsSurfaceHelper mSurfaceHelper; { @@ -87,7 +89,7 @@ setContentView(R.layout.cast_web_contents_activity); mSurfaceHelperState.set(new CastWebContentsSurfaceHelper(this /* hostActivity */, - CastWebContentsView.onLayoutActivity(this, + CastWebContentsScopes.onLayoutActivity(this, (FrameLayout) findViewById(R.id.web_contents_container), CastSwitches.getSwitchValueColor( CastSwitches.CAST_APP_BACKGROUND_COLOR, Color.BLACK)), @@ -97,7 +99,7 @@ mSurfaceHelperState.subscribe((CastWebContentsSurfaceHelper surfaceHelper) -> { mSurfaceHelper = surfaceHelper; return () -> { - mSurfaceHelper.onDestroy(); + surfaceHelper.onDestroy(); mSurfaceHelper = null; }; }); @@ -246,7 +248,9 @@ || keyCode == KeyEvent.KEYCODE_MEDIA_STOP || keyCode == KeyEvent.KEYCODE_MEDIA_NEXT || keyCode == KeyEvent.KEYCODE_MEDIA_PREVIOUS) { - CastWebContentsComponent.onKeyDown(mSurfaceHelper.getSessionId(), keyCode); + if (mSurfaceHelper != null) { + CastWebContentsComponent.onKeyDown(mSurfaceHelper.getSessionId(), keyCode); + } return true; } } @@ -269,7 +273,7 @@ @Override public boolean dispatchTouchEvent(MotionEvent ev) { - if (mSurfaceHelper.isTouchInputEnabled()) { + if (mSurfaceHelper != null && mSurfaceHelper.isTouchInputEnabled()) { return super.dispatchTouchEvent(ev); } else { return false;
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsFragment.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsFragment.java index 2324550..f2cd416 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsFragment.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsFragment.java
@@ -87,8 +87,8 @@ return; } - mSurfaceHelper = new CastWebContentsSurfaceHelper(getActivity(), /* hostActivity */ - CastWebContentsView.onLayoutFragment(getActivity(), + mSurfaceHelper = new CastWebContentsSurfaceHelper(/* hostActivity= */ getActivity(), + CastWebContentsScopes.onLayoutFragment(getActivity(), (FrameLayout) getView().findViewById(R.id.web_contents_container), CastSwitches.getSwitchValueColor( CastSwitches.CAST_APP_BACKGROUND_COLOR, Color.BLACK)),
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsView.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsScopes.java similarity index 90% rename from chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsView.java rename to chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsScopes.java index d70d96f..2d5ecb3a 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsView.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsScopes.java
@@ -7,6 +7,7 @@ import android.app.Activity; import android.content.Context; import android.graphics.drawable.ColorDrawable; +import android.support.annotation.ColorInt; import android.widget.FrameLayout; import org.chromium.chromecast.base.Observer; @@ -17,23 +18,23 @@ import org.chromium.ui.base.ViewAndroidDelegate; import org.chromium.ui.base.WindowAndroid; -class CastWebContentsView { +class CastWebContentsScopes { public static Observer<WebContents> onLayoutActivity( - Activity activity, FrameLayout layout, int backgroundColor) { + Activity activity, FrameLayout layout, @ColorInt int backgroundColor) { layout.setBackgroundColor(backgroundColor); WindowAndroid window = new ActivityWindowAndroid(activity); return onLayoutInternal(activity, layout, window, backgroundColor); } public static Observer<WebContents> onLayoutFragment( - Activity activity, FrameLayout layout, int backgroundColor) { + Activity activity, FrameLayout layout, @ColorInt int backgroundColor) { layout.setBackgroundColor(backgroundColor); WindowAndroid window = new WindowAndroid(activity); return onLayoutInternal(activity, layout, window, backgroundColor); } - private static Observer<WebContents> onLayoutInternal( - Activity activity, FrameLayout layout, WindowAndroid window, int backgroundColor) { + private static Observer<WebContents> onLayoutInternal(Activity activity, FrameLayout layout, + WindowAndroid window, @ColorInt int backgroundColor) { return (WebContents webContents) -> { ContentViewRenderView contentViewRenderView = new ContentViewRenderView(activity) { @Override
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsService.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsService.java index ace709f..8fd841d 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsService.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsService.java
@@ -40,7 +40,7 @@ { // React to web contents by presenting them in a headless view. - mWebContentsState.subscribe(CastWebContentsView.withoutLayout(this)); + mWebContentsState.subscribe(CastWebContentsScopes.withoutLayout(this)); mWebContentsState.subscribe(x -> { // TODO(thoren): Notification.Builder(Context) is deprecated in O. Use the // (Context, String) constructor when CastWebContentsService starts supporting O.
diff --git a/chromecast/browser/cast_display_configurator.cc b/chromecast/browser/cast_display_configurator.cc index 7b9626c..5368c013 100644 --- a/chromecast/browser/cast_display_configurator.cc +++ b/chromecast/browser/cast_display_configurator.cc
@@ -14,6 +14,7 @@ #include "base/strings/string_number_conversions.h" #include "chromecast/base/cast_features.h" #include "chromecast/browser/cast_touch_device_manager.h" +#include "chromecast/graphics/cast_display_util.h" #include "chromecast/graphics/cast_screen.h" #include "chromecast/public/graphics_properties_shlib.h" #include "ui/display/types/display_snapshot.h" @@ -68,17 +69,6 @@ return display::Display::ROTATE_0; } -float GetDeviceScaleFactor(gfx::Size display_resolution) { - // TODO(spang): Look into tightening up the allowed scale factors here - // rather than allowing all scales >= 1.f - int smaller_dimension = - std::min(display_resolution.width(), display_resolution.height()); - float ratio = smaller_dimension / 720.f; - if (ratio < 1.f) - return 1.f; - return ratio; -} - gfx::Rect GetScreenBounds(const gfx::Size& size_in_pixels, display::Display::Rotation rotation) { switch (rotation) {
diff --git a/chromecast/graphics/BUILD.gn b/chromecast/graphics/BUILD.gn index d241a63..e80bd84b 100644 --- a/chromecast/graphics/BUILD.gn +++ b/chromecast/graphics/BUILD.gn
@@ -43,6 +43,8 @@ "accessibility/magnification_controller.h", "accessibility/partial_magnification_controller.cc", "accessibility/partial_magnification_controller.h", + "cast_display_util.cc", + "cast_display_util.h", "cast_focus_client_aura.cc", "cast_focus_client_aura.h", "cast_touch_event_gate.cc", @@ -116,6 +118,7 @@ sources = [ "accessibility/accessibility_focus_ring_controller_unittest.cc", "accessibility/partial_magnification_controller_unittest.cc", + "cast_display_util_unittest.cc", "cast_focus_client_aura_test.cc", "cast_touch_event_gate_test.cc", "cast_views_test.cc",
diff --git a/chromecast/graphics/cast_display_util.cc b/chromecast/graphics/cast_display_util.cc new file mode 100644 index 0000000..3d2c7f9 --- /dev/null +++ b/chromecast/graphics/cast_display_util.cc
@@ -0,0 +1,23 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromecast/graphics/cast_display_util.h" + +#include <math.h> +#include <algorithm> + +namespace chromecast { + +float GetDeviceScaleFactor(const gfx::Size& display_resolution) { + int smaller_dimension = + std::min(display_resolution.width(), display_resolution.height()); + float ratio = smaller_dimension / 720.f; + if (ratio >= 2.f) + return floorf(ratio); + if (ratio >= 1.5f) + return 1.5f; + return 1.f; +} + +} // namespace chromecast
diff --git a/chromecast/graphics/cast_display_util.h b/chromecast/graphics/cast_display_util.h new file mode 100644 index 0000000..8830ca3 --- /dev/null +++ b/chromecast/graphics/cast_display_util.h
@@ -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. + +#ifndef CHROMECAST_GRAPHICS_CAST_DISPLAY_UTIL_H_ +#define CHROMECAST_GRAPHICS_CAST_DISPLAY_UTIL_H_ + +#include "ui/gfx/geometry/size.h" + +namespace chromecast { + +// Computes the default scale factor for display with given resolution. +// +// Cast applications target 720p; larger resolutions will be scaled up so +// that content fills the screen. +float GetDeviceScaleFactor(const gfx::Size& display_resolution); + +} // namespace chromecast + +#endif // CHROMECAST_GRAPHICS_CAST_DISPLAY_UTIL_H_
diff --git a/chromecast/graphics/cast_display_util_unittest.cc b/chromecast/graphics/cast_display_util_unittest.cc new file mode 100644 index 0000000..f686d56 --- /dev/null +++ b/chromecast/graphics/cast_display_util_unittest.cc
@@ -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. + +#include "chromecast/graphics/cast_display_util.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromecast { + +TEST(CastDisplayScaleTest, StandardResolutions_16x9) { + const gfx::Size kResolution720p(1280, 720); + const gfx::Size kResolution1080p(1920, 1080); + const gfx::Size kResolution1440p(2560, 1440); + const gfx::Size kResolution2160p(3840, 2160); + const gfx::Size kResolution4320p(7680, 4320); + + EXPECT_EQ(1.f, GetDeviceScaleFactor(kResolution720p)); + EXPECT_EQ(1.5f, GetDeviceScaleFactor(kResolution1080p)); + EXPECT_EQ(2.f, GetDeviceScaleFactor(kResolution1440p)); + EXPECT_EQ(3.f, GetDeviceScaleFactor(kResolution2160p)); + EXPECT_EQ(6.f, GetDeviceScaleFactor(kResolution4320p)); +} + +TEST(CastDisplayScaleTest, NonstandardResolutions) { + const gfx::Size kResolutionHomeHub(600, 1024); + EXPECT_EQ(1.f, GetDeviceScaleFactor(kResolutionHomeHub)); +} + +} // namespace chromecast
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 570b1ec..47b4d16 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -51,6 +51,9 @@ const base::Feature kAssistantFeature{"ChromeOSAssistant", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kShowPlayInDemoMode{"ShowPlayInDemoMode", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Please keep the order of these switches synchronized with the header file // (i.e. in alphabetical order). @@ -538,9 +541,6 @@ // This makes it easier to test layout logic. const char kShowLoginDevOverlay[] = "show-login-dev-overlay"; -// Show Play Store in Demo Mode. -const char kShowPlayInDemoMode[] = "show-play-in-demo-mode"; - // Indicates that a stub implementation of CrosSettings that stores settings in // memory without signing should be used, treating current user as the owner. // This also modifies OwnerSettingsServiceChromeOS::HandlesSetting such that no @@ -713,7 +713,7 @@ } bool ShouldShowPlayStoreInDemoMode() { - return base::CommandLine::ForCurrentProcess()->HasSwitch(kShowPlayInDemoMode); + return base::FeatureList::IsEnabled(kShowPlayInDemoMode); } } // namespace switches
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index c0292d44..743c983a 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h
@@ -150,7 +150,6 @@ CHROMEOS_EXPORT extern const char kShelfHoverPreviews[]; CHROMEOS_EXPORT extern const char kShowAndroidFilesInFilesApp[]; CHROMEOS_EXPORT extern const char kShowLoginDevOverlay[]; -CHROMEOS_EXPORT extern const char kShowPlayInDemoMode[]; CHROMEOS_EXPORT extern const char kStubCrosSettings[]; CHROMEOS_EXPORT extern const char kTestEncryptionMigrationUI[]; CHROMEOS_EXPORT extern const char kTetherStub[]; @@ -165,6 +164,9 @@ // Controls whether to enable Google Assistant feature. CHROMEOS_EXPORT extern const base::Feature kAssistantFeature; +// Controls whether to show the Play Store icon in Demo Mode. +CHROMEOS_EXPORT extern const base::Feature kShowPlayInDemoMode; + // Returns true if the system should wake in response to wifi traffic. CHROMEOS_EXPORT bool WakeOnWifiEnabled();
diff --git a/chromeos/components/drivefs/drivefs_host.cc b/chromeos/components/drivefs/drivefs_host.cc index 0bcaa205..5db1ced 100644 --- a/chromeos/components/drivefs/drivefs_host.cc +++ b/chromeos/components/drivefs/drivefs_host.cc
@@ -57,48 +57,31 @@ } // namespace -std::unique_ptr<OAuth2MintTokenFlow> DriveFsHost::Delegate::CreateMintTokenFlow( - OAuth2MintTokenFlow::Delegate* delegate, - const std::string& client_id, - const std::string& app_id, - const std::vector<std::string>& scopes) { - return std::make_unique<OAuth2MintTokenFlow>( - delegate, OAuth2MintTokenFlow::Parameters{ - app_id, client_id, scopes, kIdentityConsumerId, - OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE}); -} - std::unique_ptr<DriveFsHost::MojoConnectionDelegate> DriveFsHost::Delegate::CreateMojoConnectionDelegate() { return std::make_unique<MojoConnectionDelegateImpl>(); } -class DriveFsHost::AccountTokenDelegate : public OAuth2MintTokenFlow::Delegate { +class DriveFsHost::AccountTokenDelegate { public: explicit AccountTokenDelegate(DriveFsHost* host) : host_(host) {} - ~AccountTokenDelegate() override = default; void GetAccessToken(bool use_cached, const std::string& client_id, const std::string& app_id, - const std::vector<std::string>& scopes, mojom::DriveFsDelegate::GetAccessTokenCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(host_->sequence_checker_); if (get_access_token_callback_) { std::move(callback).Run(mojom::AccessTokenStatus::kTransientError, ""); return; } - DCHECK(!mint_token_flow_); const std::string& token = - MaybeGetCachedToken(use_cached, client_id, app_id, scopes); + MaybeGetCachedToken(use_cached, client_id, app_id); if (!token.empty()) { std::move(callback).Run(mojom::AccessTokenStatus::kSuccess, token); return; } get_access_token_callback_ = std::move(callback); - mint_token_flow_ = - host_->delegate_->CreateMintTokenFlow(this, client_id, app_id, scopes); - DCHECK(mint_token_flow_); GetIdentityManager().GetPrimaryAccountWhenAvailable(base::BindOnce( &AccountTokenDelegate::AccountReady, base::Unretained(this))); } @@ -107,8 +90,8 @@ void AccountReady(const AccountInfo& info, const identity::AccountState& state) { GetIdentityManager().GetAccessToken( - host_->delegate_->GetAccountId().GetUserEmail(), {}, - kIdentityConsumerId, + host_->delegate_->GetAccountId().GetUserEmail(), + {"https://www.googleapis.com/auth/drive"}, kIdentityConsumerId, base::BindOnce(&AccountTokenDelegate::GotChromeAccessToken, base::Unretained(this))); } @@ -118,38 +101,21 @@ const GoogleServiceAuthError& error) { DCHECK_CALLED_ON_VALID_SEQUENCE(host_->sequence_checker_); if (!access_token) { - OnMintTokenFailure(error); + std::move(get_access_token_callback_) + .Run(error.IsPersistentError() + ? mojom::AccessTokenStatus::kAuthError + : mojom::AccessTokenStatus::kTransientError, + ""); return; } - mint_token_flow_->Start(host_->delegate_->GetURLLoaderFactory(), - *access_token); - } - - // OAuth2MintTokenFlow::Delegate: - void OnMintTokenSuccess(const std::string& access_token, - int time_to_live) override { - DCHECK_CALLED_ON_VALID_SEQUENCE(host_->sequence_checker_); - UpdateCachedToken(access_token, base::TimeDelta::FromSeconds(time_to_live)); + UpdateCachedToken(*access_token, expiration_time); std::move(get_access_token_callback_) - .Run(mojom::AccessTokenStatus::kSuccess, access_token); - mint_token_flow_.reset(); + .Run(mojom::AccessTokenStatus::kSuccess, *access_token); } - void OnMintTokenFailure(const GoogleServiceAuthError& error) override { - DCHECK_CALLED_ON_VALID_SEQUENCE(host_->sequence_checker_); - std::move(get_access_token_callback_) - .Run(error.IsPersistentError() - ? mojom::AccessTokenStatus::kAuthError - : mojom::AccessTokenStatus::kTransientError, - ""); - mint_token_flow_.reset(); - } - - const std::string& MaybeGetCachedToken( - bool use_cached, - const std::string& client_id, - const std::string& app_id, - const std::vector<std::string>& scopes) { + const std::string& MaybeGetCachedToken(bool use_cached, + const std::string& client_id, + const std::string& app_id) { // Return value from cache at most once per mount. if (!use_cached || host_->clock_->Now() >= last_token_expiry_) { last_token_.clear(); @@ -157,9 +123,9 @@ return last_token_; } - void UpdateCachedToken(const std::string& token, const base::TimeDelta& ttl) { + void UpdateCachedToken(const std::string& token, const base::Time& expiry) { last_token_ = token; - last_token_expiry_ = host_->clock_->Now() + ttl; + last_token_expiry_ = expiry; } identity::mojom::IdentityManager& GetIdentityManager() { @@ -180,9 +146,6 @@ // Pending callback for an in-flight GetAccessToken request. mojom::DriveFsDelegate::GetAccessTokenCallback get_access_token_callback_; - // The mint token flow, if one is in flight. - std::unique_ptr<OAuth2MintTokenFlow> mint_token_flow_; - std::string last_token_; base::Time last_token_expiry_; @@ -193,7 +156,6 @@ // should be shared between mounts. class DriveFsHost::MountState : public mojom::DriveFsDelegate, - public OAuth2MintTokenFlow::Delegate, public chromeos::disks::DiskMountManager::Observer, public drive::DriveNotificationObserver { public: @@ -308,9 +270,8 @@ const std::vector<std::string>& scopes, GetAccessTokenCallback callback) override { DCHECK_CALLED_ON_VALID_SEQUENCE(host_->sequence_checker_); - host_->account_token_delegate_->GetAccessToken(!token_fetch_attempted_, - client_id, app_id, scopes, - std::move(callback)); + host_->account_token_delegate_->GetAccessToken( + !token_fetch_attempted_, client_id, app_id, std::move(callback)); token_fetch_attempted_ = true; }
diff --git a/chromeos/components/drivefs/drivefs_host.h b/chromeos/components/drivefs/drivefs_host.h index 42da1b2..410b202 100644 --- a/chromeos/components/drivefs/drivefs_host.h +++ b/chromeos/components/drivefs/drivefs_host.h
@@ -18,7 +18,6 @@ #include "chromeos/components/drivefs/mojom/drivefs.mojom.h" #include "chromeos/disks/disk_mount_manager.h" #include "components/account_id/account_id.h" -#include "google_apis/gaia/oauth2_mint_token_flow.h" #include "services/identity/public/mojom/identity_manager.mojom.h" namespace drive { @@ -95,11 +94,6 @@ virtual const AccountId& GetAccountId() = 0; virtual std::string GetObfuscatedAccountId() = 0; virtual drive::DriveNotificationManager& GetDriveNotificationManager() = 0; - virtual std::unique_ptr<OAuth2MintTokenFlow> CreateMintTokenFlow( - OAuth2MintTokenFlow::Delegate* delegate, - const std::string& client_id, - const std::string& app_id, - const std::vector<std::string>& scopes); virtual std::unique_ptr<MojoConnectionDelegate> CreateMojoConnectionDelegate();
diff --git a/chromeos/components/drivefs/drivefs_host_unittest.cc b/chromeos/components/drivefs/drivefs_host_unittest.cc index 32c4f04e..8dbb56f 100644 --- a/chromeos/components/drivefs/drivefs_host_unittest.cc +++ b/chromeos/components/drivefs/drivefs_host_unittest.cc
@@ -56,67 +56,6 @@ mojom::DriveFsBootstrapPtrInfo pending_bootstrap_; }; -class ForwardingOAuth2MintTokenFlow; - -ACTION_P(SucceedMintToken, token) { - base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindLambdaForTesting([=] { - arg0->OnMintTokenSuccess(token, - base::TimeDelta::FromHours(1).InSeconds()); - })); -} - -ACTION_P(FailMintToken, error) { - base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindLambdaForTesting([=] { - arg0->OnMintTokenFailure(GoogleServiceAuthError(error)); - })); -} - -class MockOAuth2MintTokenFlow { - public: - MockOAuth2MintTokenFlow() = default; - - void ExpectStartAndSucceed(const std::string& expected_token, - const std::string& token_to_return) { - EXPECT_CALL(*this, Start(_, expected_token)) - .WillOnce(SucceedMintToken(token_to_return)); - } - - void ExpectStartAndFail(const std::string& expected_token, - GoogleServiceAuthError::State error) { - EXPECT_CALL(*this, Start(_, expected_token)).WillOnce(FailMintToken(error)); - } - - void ExpectNoStartCalls() { EXPECT_CALL(*this, Start(_, _)).Times(0); } - - MOCK_METHOD2(Start, - void(OAuth2MintTokenFlow::Delegate* delegate, - const std::string& access_token)); - - private: - friend class ForwardingOAuth2MintTokenFlow; - - DISALLOW_COPY_AND_ASSIGN(MockOAuth2MintTokenFlow); -}; - -class ForwardingOAuth2MintTokenFlow : public OAuth2MintTokenFlow { - public: - ForwardingOAuth2MintTokenFlow(OAuth2MintTokenFlow::Delegate* delegate, - MockOAuth2MintTokenFlow* mock) - : OAuth2MintTokenFlow(delegate, {}), delegate_(delegate), mock_(mock) {} - - void Start(scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const std::string& access_token) override { - EXPECT_EQ(nullptr, url_loader_factory); - mock_->Start(delegate_, access_token); - } - - private: - Delegate* const delegate_; - MockOAuth2MintTokenFlow* mock_; -}; - class MockDriveFs : public mojom::DriveFsInterceptorForTesting, public mojom::SearchQuery { public: @@ -178,8 +117,6 @@ drive_notification_manager_.Shutdown(); } - MockOAuth2MintTokenFlow& mock_flow() { return mock_flow_; } - void set_pending_bootstrap(mojom::DriveFsBootstrapPtrInfo pending_bootstrap) { pending_bootstrap_ = std::move(pending_bootstrap); } @@ -208,18 +145,6 @@ return "salt-" + account_id_.GetAccountIdKey(); } - std::unique_ptr<OAuth2MintTokenFlow> CreateMintTokenFlow( - OAuth2MintTokenFlow::Delegate* delegate, - const std::string& client_id, - const std::string& app_id, - const std::vector<std::string>& scopes) override { - EXPECT_EQ("client ID", client_id); - EXPECT_EQ("app ID", app_id); - EXPECT_EQ((std::vector<std::string>{"scope1", "scope2"}), scopes); - return std::make_unique<ForwardingOAuth2MintTokenFlow>(delegate, - &mock_flow_); - } - std::unique_ptr<DriveFsHost::MojoConnectionDelegate> CreateMojoConnectionDelegate() override { DCHECK(pending_bootstrap_); @@ -229,7 +154,6 @@ const std::unique_ptr<service_manager::Connector> connector_; const AccountId account_id_; - MockOAuth2MintTokenFlow mock_flow_; mojom::DriveFsBootstrapPtrInfo pending_bootstrap_; invalidation::FakeInvalidationService invalidation_service_; drive::DriveNotificationManager drive_notification_manager_; @@ -239,6 +163,7 @@ class MockIdentityManager { public: + explicit MockIdentityManager(const base::Clock* clock) : clock_(clock) {} MOCK_METHOD3( GetAccessToken, std::pair<base::Optional<std::string>, GoogleServiceAuthError::State>( @@ -246,6 +171,32 @@ const ::identity::ScopeSet& scopes, const std::string& consumer_id)); + void OnGetAccessToken( + const std::string& account_id, + const ::identity::ScopeSet& scopes, + const std::string& consumer_id, + identity::mojom::IdentityManager::GetAccessTokenCallback callback) { + if (pause_requests_) { + callbacks_.push_back(std::move(callback)); + return; + } + auto result = GetAccessToken(account_id, scopes, consumer_id); + std::move(callback).Run(std::move(result.first), + clock_->Now() + base::TimeDelta::FromHours(1), + GoogleServiceAuthError(result.second)); + } + + std::vector<identity::mojom::IdentityManager::GetAccessTokenCallback>& + callbacks() { + return callbacks_; + } + + void set_pause_requests(bool pause) { pause_requests_ = pause; } + + const base::Clock* const clock_; + bool pause_requests_ = false; + std::vector<identity::mojom::IdentityManager::GetAccessTokenCallback> + callbacks_; mojo::BindingSet<identity::mojom::IdentityManager>* bindings_ = nullptr; }; @@ -253,9 +204,7 @@ : public identity::mojom::IdentityManagerInterceptorForTesting, public service_manager::Service { public: - explicit FakeIdentityService(MockIdentityManager* mock, - const base::Clock* clock) - : mock_(mock), clock_(clock) { + explicit FakeIdentityService(MockIdentityManager* mock) : mock_(mock) { binder_registry_.AddInterface( base::BindRepeating(&FakeIdentityService::BindIdentityManagerRequest, base::Unretained(this))); @@ -291,9 +240,8 @@ const ::identity::ScopeSet& scopes, const std::string& consumer_id, GetAccessTokenCallback callback) override { - auto result = mock_->GetAccessToken(account_id, scopes, consumer_id); - std::move(callback).Run(std::move(result.first), clock_->Now(), - GoogleServiceAuthError(result.second)); + mock_->OnGetAccessToken(account_id, scopes, consumer_id, + std::move(callback)); } IdentityManager* GetForwardingInterface() override { @@ -302,7 +250,6 @@ } MockIdentityManager* const mock_; - const base::Clock* const clock_; service_manager::BinderRegistry binder_registry_; mojo::BindingSet<identity::mojom::IdentityManager> bindings_; @@ -324,7 +271,10 @@ class DriveFsHostTest : public ::testing::Test, public mojom::DriveFsBootstrap { public: - DriveFsHostTest() : bootstrap_binding_(this), binding_(&mock_drivefs_) { + DriveFsHostTest() + : mock_identity_manager_(&clock_), + bootstrap_binding_(this), + binding_(&mock_drivefs_) { clock_.SetNow(base::Time::Now()); } @@ -337,8 +287,7 @@ disk_manager_ = std::make_unique<chromeos::disks::MockDiskMountManager>(); connector_factory_ = service_manager::TestConnectorFactory::CreateForUniqueService( - std::make_unique<FakeIdentityService>(&mock_identity_manager_, - &clock_)); + std::make_unique<FakeIdentityService>(&mock_identity_manager_)); host_delegate_ = std::make_unique<TestingDriveFsHostDelegate>( connector_factory_->CreateConnector(), account_id_); auto timer = std::make_unique<base::MockOneShotTimer>(); @@ -756,9 +705,7 @@ EXPECT_CALL(mock_identity_manager_, GetAccessToken("test@example.com", _, "drivefs")) .WillOnce(testing::Return( - std::make_pair("chrome token", GoogleServiceAuthError::NONE))); - host_delegate_->mock_flow().ExpectStartAndSucceed("chrome token", - "auth token"); + std::make_pair("auth token", GoogleServiceAuthError::NONE))); ExpectAccessToken(mojom::AccessTokenStatus::kSuccess, "auth token"); } @@ -792,9 +739,7 @@ EXPECT_CALL(mock_identity_manager_, GetAccessToken("test@example.com", _, "drivefs")) .WillOnce(testing::Return( - std::make_pair("chrome token", GoogleServiceAuthError::NONE))); - host_delegate_->mock_flow().ExpectStartAndSucceed("chrome token", - "auth token"); + std::make_pair("auth token", GoogleServiceAuthError::NONE))); ExpectAccessToken(mojom::AccessTokenStatus::kSuccess, "auth token"); } for (int i = 0; i < 3; ++i) { @@ -802,7 +747,6 @@ GetAccessToken("test@example.com", _, "drivefs")) .WillOnce(testing::Return(std::make_pair( base::nullopt, GoogleServiceAuthError::ACCOUNT_DISABLED))); - host_delegate_->mock_flow().ExpectNoStartCalls(); ExpectAccessToken(mojom::AccessTokenStatus::kAuthError, ""); } } @@ -814,7 +758,6 @@ GetAccessToken("test@example.com", _, "drivefs")) .WillOnce(testing::Return(std::make_pair( base::nullopt, GoogleServiceAuthError::ACCOUNT_DISABLED))); - host_delegate_->mock_flow().ExpectNoStartCalls(); ExpectAccessToken(mojom::AccessTokenStatus::kAuthError, ""); } @@ -825,31 +768,6 @@ GetAccessToken("test@example.com", _, "drivefs")) .WillOnce(testing::Return(std::make_pair( base::nullopt, GoogleServiceAuthError::SERVICE_UNAVAILABLE))); - host_delegate_->mock_flow().ExpectNoStartCalls(); - ExpectAccessToken(mojom::AccessTokenStatus::kTransientError, ""); -} - -TEST_F(DriveFsHostTest, GetAccessToken_MintTokenFailure_Permanent) { - ASSERT_NO_FATAL_FAILURE(DoMount()); - - EXPECT_CALL(mock_identity_manager_, - GetAccessToken("test@example.com", _, "drivefs")) - .WillOnce(testing::Return( - std::make_pair("chrome token", GoogleServiceAuthError::NONE))); - host_delegate_->mock_flow().ExpectStartAndFail( - "chrome token", GoogleServiceAuthError::ACCOUNT_DISABLED); - ExpectAccessToken(mojom::AccessTokenStatus::kAuthError, ""); -} - -TEST_F(DriveFsHostTest, GetAccessToken_MintTokenFailure_Transient) { - ASSERT_NO_FATAL_FAILURE(DoMount()); - - EXPECT_CALL(mock_identity_manager_, - GetAccessToken("test@example.com", _, "drivefs")) - .WillOnce(testing::Return( - std::make_pair("chrome token", GoogleServiceAuthError::NONE))); - host_delegate_->mock_flow().ExpectStartAndFail( - "chrome token", GoogleServiceAuthError::SERVICE_UNAVAILABLE); ExpectAccessToken(mojom::AccessTokenStatus::kTransientError, ""); } @@ -862,7 +780,6 @@ testing::InvokeWithoutArgs([&]() { host_->Unmount(); }), testing::Return(std::make_pair( base::nullopt, GoogleServiceAuthError::ACCOUNT_DISABLED)))); - host_delegate_->mock_flow().ExpectNoStartCalls(); base::RunLoop run_loop; delegate_ptr_.set_connection_error_handler(run_loop.QuitClosure()); @@ -1037,10 +954,7 @@ EXPECT_CALL(mock_identity_manager_, GetAccessToken("test@example.com", _, "drivefs")) .WillOnce(testing::Return( - std::make_pair("chrome token", GoogleServiceAuthError::NONE))); - - host_delegate_->mock_flow().ExpectStartAndSucceed("chrome token", - "auth token"); + std::make_pair("auth token", GoogleServiceAuthError::NONE))); ExpectAccessToken(mojom::AccessTokenStatus::kSuccess, "auth token"); @@ -1061,12 +975,9 @@ EXPECT_CALL(mock_identity_manager_, GetAccessToken("test@example.com", _, "drivefs")) .WillOnce(testing::Return( - std::make_pair("chrome token", GoogleServiceAuthError::NONE))) + std::make_pair("auth token", GoogleServiceAuthError::NONE))) .WillOnce(testing::Return( - std::make_pair("chrome token 2", GoogleServiceAuthError::NONE))); - - host_delegate_->mock_flow().ExpectStartAndSucceed("chrome token", - "auth token"); + std::make_pair("auth token 2", GoogleServiceAuthError::NONE))); ExpectAccessToken(mojom::AccessTokenStatus::kSuccess, "auth token"); @@ -1081,9 +992,6 @@ ExpectAccessToken(mojom::AccessTokenStatus::kSuccess, "auth token"); // But if it asks for token more than once it goes straight to identity. - host_delegate_->mock_flow().ExpectStartAndSucceed("chrome token 2", - "auth token 2"); - ExpectAccessToken(mojom::AccessTokenStatus::kSuccess, "auth token 2"); } @@ -1093,12 +1001,9 @@ EXPECT_CALL(mock_identity_manager_, GetAccessToken("test@example.com", _, "drivefs")) .WillOnce(testing::Return( - std::make_pair("chrome token", GoogleServiceAuthError::NONE))) + std::make_pair("auth token", GoogleServiceAuthError::NONE))) .WillOnce(testing::Return( - std::make_pair("chrome token 2", GoogleServiceAuthError::NONE))); - - host_delegate_->mock_flow().ExpectStartAndSucceed("chrome token", - "auth token"); + std::make_pair("auth token 2", GoogleServiceAuthError::NONE))); ExpectAccessToken(mojom::AccessTokenStatus::kSuccess, "auth token"); @@ -1112,22 +1017,12 @@ // As the token expired second mount should go to identity. ASSERT_NO_FATAL_FAILURE(DoMount()); - host_delegate_->mock_flow().ExpectStartAndSucceed("chrome token 2", - "auth token 2"); - ExpectAccessToken(mojom::AccessTokenStatus::kSuccess, "auth token 2"); } TEST_F(DriveFsHostTest, Remount_RequestInflight) { ASSERT_NO_FATAL_FAILURE(DoMount()); - - EXPECT_CALL(mock_identity_manager_, - GetAccessToken("test@example.com", _, "drivefs")) - .WillOnce(testing::Return( - std::make_pair("chrome token", GoogleServiceAuthError::NONE))); - OAuth2MintTokenFlow::Delegate* delegate = nullptr; - EXPECT_CALL(host_delegate_->mock_flow(), Start(_, "chrome token")) - .WillOnce(testing::SaveArg<0>(&delegate)); + mock_identity_manager_.set_pause_requests(true); delegate_ptr_->GetAccessToken( "client ID", "app ID", {"scope1", "scope2"}, @@ -1141,8 +1036,10 @@ ASSERT_NO_FATAL_FAILURE(DoUnmount()); // Now the response is ready. - delegate->OnMintTokenSuccess("auth token", - base::TimeDelta::FromHours(1).InSeconds()); + ASSERT_EQ(1u, mock_identity_manager_.callbacks().size()); + std::move(mock_identity_manager_.callbacks().front()) + .Run("auth token", clock_.Now() + base::TimeDelta::FromHours(1), + GoogleServiceAuthError(GoogleServiceAuthError::NONE)); // Second mount will reuse previous token. ASSERT_NO_FATAL_FAILURE(DoMount());
diff --git a/chromeos/components/tether/BUILD.gn b/chromeos/components/tether/BUILD.gn index fdffc1d..8ccbf81 100644 --- a/chromeos/components/tether/BUILD.gn +++ b/chromeos/components/tether/BUILD.gn
@@ -17,18 +17,10 @@ "ble_advertisement_device_queue.h", "ble_advertiser.cc", "ble_advertiser.h", - "ble_advertiser_impl.cc", - "ble_advertiser_impl.h", "ble_connection_manager.cc", "ble_connection_manager.h", - "ble_connection_metrics_logger.cc", - "ble_connection_metrics_logger.h", "ble_scanner.cc", "ble_scanner.h", - "ble_scanner_impl.cc", - "ble_scanner_impl.h", - "ble_service_data_helper_impl.cc", - "ble_service_data_helper_impl.h", "connect_tethering_operation.cc", "connect_tethering_operation.h", "connection_preserver.cc", @@ -252,11 +244,7 @@ "active_host_unittest.cc", "asynchronous_shutdown_object_container_impl_unittest.cc", "ble_advertisement_device_queue_unittest.cc", - "ble_advertiser_impl_unittest.cc", "ble_connection_manager_unittest.cc", - "ble_connection_metrics_logger_unittest.cc", - "ble_scanner_impl_unittest.cc", - "ble_service_data_helper_impl_unittest.cc", "connect_tethering_operation_unittest.cc", "connection_preserver_impl_unittest.cc", "crash_recovery_manager_impl_unittest.cc",
diff --git a/chromeos/components/tether/asynchronous_shutdown_object_container_impl.cc b/chromeos/components/tether/asynchronous_shutdown_object_container_impl.cc index b6bdb4a2..7dcca5d 100644 --- a/chromeos/components/tether/asynchronous_shutdown_object_container_impl.cc +++ b/chromeos/components/tether/asynchronous_shutdown_object_container_impl.cc
@@ -5,17 +5,10 @@ #include "chromeos/components/tether/asynchronous_shutdown_object_container_impl.h" #include "base/memory/ptr_util.h" -#include "chromeos/chromeos_features.h" -#include "chromeos/components/tether/ble_advertisement_device_queue.h" -#include "chromeos/components/tether/ble_advertiser_impl.h" -#include "chromeos/components/tether/ble_connection_metrics_logger.h" -#include "chromeos/components/tether/ble_scanner_impl.h" -#include "chromeos/components/tether/ble_service_data_helper_impl.h" #include "chromeos/components/tether/disconnect_tethering_request_sender_impl.h" #include "chromeos/components/tether/network_configuration_remover.h" #include "chromeos/components/tether/wifi_hotspot_disconnector_impl.h" #include "chromeos/services/device_sync/public/cpp/device_sync_client.h" -#include "chromeos/services/secure_channel/ble_synchronizer.h" #include "chromeos/services/secure_channel/public/cpp/client/secure_channel_client.h" #include "components/cryptauth/cryptauth_service.h" #include "components/cryptauth/local_device_data_provider.h" @@ -32,7 +25,6 @@ // static std::unique_ptr<AsynchronousShutdownObjectContainer> AsynchronousShutdownObjectContainerImpl::Factory::NewInstance( - scoped_refptr<device::BluetoothAdapter> adapter, cryptauth::CryptAuthService* cryptauth_service, device_sync::DeviceSyncClient* device_sync_client, secure_channel::SecureChannelClient* secure_channel_client, @@ -45,7 +37,7 @@ factory_instance_ = new Factory(); return factory_instance_->BuildInstance( - adapter, cryptauth_service, device_sync_client, secure_channel_client, + cryptauth_service, device_sync_client, secure_channel_client, tether_host_fetcher, network_state_handler, managed_network_configuration_handler, network_connection_handler, pref_service); @@ -61,7 +53,6 @@ std::unique_ptr<AsynchronousShutdownObjectContainer> AsynchronousShutdownObjectContainerImpl::Factory::BuildInstance( - scoped_refptr<device::BluetoothAdapter> adapter, cryptauth::CryptAuthService* cryptauth_service, device_sync::DeviceSyncClient* device_sync_client, secure_channel::SecureChannelClient* secure_channel_client, @@ -71,7 +62,7 @@ NetworkConnectionHandler* network_connection_handler, PrefService* pref_service) { return base::WrapUnique(new AsynchronousShutdownObjectContainerImpl( - adapter, cryptauth_service, device_sync_client, secure_channel_client, + cryptauth_service, device_sync_client, secure_channel_client, tether_host_fetcher, network_state_handler, managed_network_configuration_handler, network_connection_handler, pref_service)); @@ -79,7 +70,6 @@ AsynchronousShutdownObjectContainerImpl:: AsynchronousShutdownObjectContainerImpl( - scoped_refptr<device::BluetoothAdapter> adapter, cryptauth::CryptAuthService* cryptauth_service, device_sync::DeviceSyncClient* device_sync_client, secure_channel::SecureChannelClient* secure_channel_client, @@ -89,47 +79,10 @@ managed_network_configuration_handler, NetworkConnectionHandler* network_connection_handler, PrefService* pref_service) - : adapter_(base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) - ? nullptr - : adapter), - tether_host_fetcher_(tether_host_fetcher), + : tether_host_fetcher_(tether_host_fetcher), local_device_data_provider_( std::make_unique<cryptauth::LocalDeviceDataProvider>( cryptauth_service)), - ble_service_data_helper_( - base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) - ? nullptr - : BleServiceDataHelperImpl::Factory::Get()->BuildInstance( - tether_host_fetcher_, - local_device_data_provider_.get(), - device_sync_client)), - ble_advertisement_device_queue_( - base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) - ? nullptr - : std::make_unique<BleAdvertisementDeviceQueue>()), - ble_synchronizer_( - base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) - ? nullptr - : secure_channel::BleSynchronizer::Factory::Get()->BuildInstance( - adapter)), - ble_advertiser_( - base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) - ? nullptr - : BleAdvertiserImpl::Factory::NewInstance( - ble_service_data_helper_.get(), - ble_synchronizer_.get())), - ble_scanner_( - base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) - ? nullptr - : BleScannerImpl::Factory::NewInstance( - adapter, - ble_service_data_helper_.get(), - ble_synchronizer_.get(), - tether_host_fetcher_)), - ble_connection_metrics_logger_( - base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) - ? nullptr - : std::make_unique<BleConnectionMetricsLogger>()), disconnect_tethering_request_sender_( DisconnectTetheringRequestSenderImpl::Factory::NewInstance( device_sync_client, @@ -142,16 +95,10 @@ network_connection_handler, network_state_handler, pref_service, - network_configuration_remover_.get())) { -} + network_configuration_remover_.get())) {} AsynchronousShutdownObjectContainerImpl:: ~AsynchronousShutdownObjectContainerImpl() { - disconnect_tethering_request_sender_->RemoveObserver(this); - if (!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) { - ble_advertiser_->RemoveObserver(this); - ble_scanner_->RemoveObserver(this); - } } void AsynchronousShutdownObjectContainerImpl::Shutdown( @@ -162,10 +109,6 @@ // The objects below require asynchronous shutdowns, so start observering // these objects. Once they notify observers that they are finished shutting // down, the asynchronous shutdown will complete. - if (!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) { - ble_advertiser_->AddObserver(this); - ble_scanner_->AddObserver(this); - } disconnect_tethering_request_sender_->AddObserver(this); ShutdownIfPossible(); @@ -192,30 +135,16 @@ } void AsynchronousShutdownObjectContainerImpl:: - OnAllAdvertisementsUnregistered() { - ShutdownIfPossible(); -} - -void AsynchronousShutdownObjectContainerImpl:: OnPendingDisconnectRequestsComplete() { ShutdownIfPossible(); } -void AsynchronousShutdownObjectContainerImpl::OnDiscoverySessionStateChanged( - bool discovery_session_active) { - ShutdownIfPossible(); -} - void AsynchronousShutdownObjectContainerImpl::ShutdownIfPossible() { DCHECK(!shutdown_complete_callback_.is_null()); if (AreAsynchronousOperationsActive()) return; - if (!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) { - ble_advertiser_->RemoveObserver(this); - ble_scanner_->RemoveObserver(this); - } disconnect_tethering_request_sender_->RemoveObserver(this); shutdown_complete_callback_.Run(); @@ -223,42 +152,18 @@ bool AsynchronousShutdownObjectContainerImpl:: AreAsynchronousOperationsActive() { - // All of the asynchronous shutdown procedures depend on Bluetooth. If - // Bluetooth is off, there is no way to complete these tasks. - if (!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) && - !adapter_->IsPowered()) - return false; - // If there are pending disconnection requests, they must be sent before the // component shuts down. if (disconnect_tethering_request_sender_->HasPendingRequests()) { return true; } - // The BLE scanner must shut down completely before the component shuts down. - if (!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) && - ble_scanner_->ShouldDiscoverySessionBeActive() != - ble_scanner_->IsDiscoverySessionActive()) { - return true; - } - - // The BLE advertiser must unregister all of its advertisements. - if (!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) && - ble_advertiser_->AreAdvertisementsRegistered()) - return true; - return false; } void AsynchronousShutdownObjectContainerImpl::SetTestDoubles( - std::unique_ptr<BleAdvertiser> ble_advertiser, - std::unique_ptr<BleScanner> ble_scanner, std::unique_ptr<DisconnectTetheringRequestSender> disconnect_tethering_request_sender) { - if (!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) { - ble_advertiser_ = std::move(ble_advertiser); - ble_scanner_ = std::move(ble_scanner); - } disconnect_tethering_request_sender_ = std::move(disconnect_tethering_request_sender); }
diff --git a/chromeos/components/tether/asynchronous_shutdown_object_container_impl.h b/chromeos/components/tether/asynchronous_shutdown_object_container_impl.h index 311dd02..154e95d 100644 --- a/chromeos/components/tether/asynchronous_shutdown_object_container_impl.h +++ b/chromeos/components/tether/asynchronous_shutdown_object_container_impl.h
@@ -22,20 +22,12 @@ class LocalDeviceDataProvider; } // namespace cryptauth -namespace device { -class BluetoothAdapter; -} // namespace device - namespace chromeos { class ManagedNetworkConfigurationHandler; class NetworkConnectionHandler; class NetworkStateHandler; -namespace secure_channel { -class BleSynchronizerBase; -} // namespace secure_channel - namespace device_sync { class DeviceSyncClient; } // namespace device_sync @@ -44,14 +36,8 @@ class SecureChannelClient; } // namespace secure_channel -namespace secure_channel { -class BleServiceDataHelper; -} // namespace secure_channel - namespace tether { -class BleAdvertisementDeviceQueue; -class BleConnectionMetricsLogger; class NetworkConfigurationRemover; class TetherHostFetcher; class WifiHotspotDisconnector; @@ -59,14 +45,11 @@ // Concrete AsynchronousShutdownObjectContainer implementation. class AsynchronousShutdownObjectContainerImpl : public AsynchronousShutdownObjectContainer, - public BleAdvertiser::Observer, - public BleScanner::Observer, public DisconnectTetheringRequestSender::Observer { public: class Factory { public: static std::unique_ptr<AsynchronousShutdownObjectContainer> NewInstance( - scoped_refptr<device::BluetoothAdapter> adapter, cryptauth::CryptAuthService* cryptauth_service, device_sync::DeviceSyncClient* device_sync_client, secure_channel::SecureChannelClient* secure_channel_client, @@ -80,7 +63,6 @@ protected: virtual std::unique_ptr<AsynchronousShutdownObjectContainer> BuildInstance( - scoped_refptr<device::BluetoothAdapter> adapter, cryptauth::CryptAuthService* cryptauth_service, device_sync::DeviceSyncClient* device_sync_client, secure_channel::SecureChannelClient* secure_channel_client, @@ -108,7 +90,6 @@ protected: AsynchronousShutdownObjectContainerImpl( - scoped_refptr<device::BluetoothAdapter> adapter, cryptauth::CryptAuthService* cryptauth_service, device_sync::DeviceSyncClient* device_sync_client, secure_channel::SecureChannelClient* secure_channel_client, @@ -118,12 +99,6 @@ NetworkConnectionHandler* network_connection_handler, PrefService* pref_service); - // BleAdvertiser::Observer: - void OnAllAdvertisementsUnregistered() override; - - // BleScanner::Observer: - void OnDiscoverySessionStateChanged(bool discovery_session_active) override; - // DisconnectTetheringRequestSender::Observer: void OnPendingDisconnectRequestsComplete() override; @@ -133,23 +108,13 @@ void ShutdownIfPossible(); bool AreAsynchronousOperationsActive(); - void SetTestDoubles(std::unique_ptr<BleAdvertiser> ble_advertiser, - std::unique_ptr<BleScanner> ble_scanner, - std::unique_ptr<DisconnectTetheringRequestSender> + void SetTestDoubles(std::unique_ptr<DisconnectTetheringRequestSender> disconnect_tethering_request_sender); - scoped_refptr<device::BluetoothAdapter> adapter_; TetherHostFetcher* tether_host_fetcher_; std::unique_ptr<cryptauth::LocalDeviceDataProvider> local_device_data_provider_; - std::unique_ptr<secure_channel::BleServiceDataHelper> - ble_service_data_helper_; - std::unique_ptr<BleAdvertisementDeviceQueue> ble_advertisement_device_queue_; - std::unique_ptr<secure_channel::BleSynchronizerBase> ble_synchronizer_; - std::unique_ptr<BleAdvertiser> ble_advertiser_; - std::unique_ptr<BleScanner> ble_scanner_; - std::unique_ptr<BleConnectionMetricsLogger> ble_connection_metrics_logger_; std::unique_ptr<DisconnectTetheringRequestSender> disconnect_tethering_request_sender_; std::unique_ptr<NetworkConfigurationRemover> network_configuration_remover_;
diff --git a/chromeos/components/tether/asynchronous_shutdown_object_container_impl_unittest.cc b/chromeos/components/tether/asynchronous_shutdown_object_container_impl_unittest.cc index 2e952d0d..9931251 100644 --- a/chromeos/components/tether/asynchronous_shutdown_object_container_impl_unittest.cc +++ b/chromeos/components/tether/asynchronous_shutdown_object_container_impl_unittest.cc
@@ -8,11 +8,7 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" -#include "chromeos/chromeos_features.h" -#include "chromeos/components/tether/fake_ble_advertiser.h" -#include "chromeos/components/tether/fake_ble_scanner.h" #include "chromeos/components/tether/fake_disconnect_tethering_request_sender.h" #include "chromeos/components/tether/fake_tether_host_fetcher.h" #include "chromeos/components/tether/tether_component_impl.h" @@ -23,7 +19,7 @@ #include "components/cryptauth/remote_device_provider_impl.h" #include "components/cryptauth/remote_device_test_util.h" #include "components/sync_preferences/testing_pref_service_syncable.h" -#include "device/bluetooth/test/mock_bluetooth_adapter.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using testing::Invoke; @@ -59,17 +55,7 @@ : test_device_(cryptauth::CreateRemoteDeviceRefListForTest(1u)[0]) {} void SetUp() override { - scoped_feature_list_.InitAndDisableFeature(features::kMultiDeviceApi); - was_shutdown_callback_invoked_ = false; - is_adapter_powered_ = true; - - mock_adapter_ = - base::MakeRefCounted<NiceMock<device::MockBluetoothAdapter>>(); - ON_CALL(*mock_adapter_, IsPowered()) - .WillByDefault( - Invoke(this, &AsynchronousShutdownObjectContainerImplTest:: - MockIsAdapterPowered)); fake_remote_device_provider_factory_ = base::WrapUnique(new FakeRemoteDeviceProviderFactory()); @@ -92,29 +78,21 @@ // by the object itself; rather, they are simply passed to the constructors // of objects created by the container. container_ = base::WrapUnique(new AsynchronousShutdownObjectContainerImpl( - mock_adapter_, fake_cryptauth_service_.get(), - fake_device_sync_client_.get(), fake_secure_channel_client_.get(), + fake_cryptauth_service_.get(), fake_device_sync_client_.get(), + fake_secure_channel_client_.get(), fake_tether_host_fetcher_.get() /* tether_host_fetcher */, nullptr /* network_state_handler */, nullptr /* managed_network_configuration_handler */, nullptr /* network_connection_handler */, test_pref_service_.get() /* pref_service */)); - fake_ble_advertiser_ = new FakeBleAdvertiser( - false /* automatically_update_active_advertisements */); - fake_ble_scanner_ = - new FakeBleScanner(false /* automatically_update_discovery_session */); fake_disconnect_tethering_request_sender_ = new FakeDisconnectTetheringRequestSender(); container_->SetTestDoubles( - base::WrapUnique(fake_ble_advertiser_), - base::WrapUnique(fake_ble_scanner_), base::WrapUnique(fake_disconnect_tethering_request_sender_)); } - bool MockIsAdapterPowered() { return is_adapter_powered_; } - void CallShutdown() { container_->Shutdown(base::Bind( &AsynchronousShutdownObjectContainerImplTest::OnShutdownComplete, @@ -125,9 +103,7 @@ const base::test::ScopedTaskEnvironment scoped_task_environment_; const cryptauth::RemoteDeviceRef test_device_; - base::test::ScopedFeatureList scoped_feature_list_; - scoped_refptr<NiceMock<device::MockBluetoothAdapter>> mock_adapter_; std::unique_ptr<cryptauth::FakeCryptAuthService> fake_cryptauth_service_; std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_; std::unique_ptr<secure_channel::FakeSecureChannelClient> @@ -137,13 +113,10 @@ test_pref_service_; std::unique_ptr<FakeRemoteDeviceProviderFactory> fake_remote_device_provider_factory_; - FakeBleAdvertiser* fake_ble_advertiser_; - FakeBleScanner* fake_ble_scanner_; FakeDisconnectTetheringRequestSender* fake_disconnect_tethering_request_sender_; bool was_shutdown_callback_invoked_; - bool is_adapter_powered_; std::unique_ptr<AsynchronousShutdownObjectContainerImpl> container_; @@ -158,42 +131,6 @@ } TEST_F(AsynchronousShutdownObjectContainerImplTest, - TestShutdown_AsyncBleAdvertiserShutdown) { - fake_ble_advertiser_->set_are_advertisements_registered(true); - EXPECT_TRUE(fake_ble_advertiser_->AreAdvertisementsRegistered()); - - // Start the shutdown; it should not yet succeed since there are still - // registered advertisements. - CallShutdown(); - EXPECT_FALSE(was_shutdown_callback_invoked_); - - // Now, remove these advertisements; this should cause the shutdown to - // complete. - fake_ble_advertiser_->set_are_advertisements_registered(false); - fake_ble_advertiser_->NotifyAllAdvertisementsUnregistered(); - EXPECT_TRUE(was_shutdown_callback_invoked_); -} - -TEST_F(AsynchronousShutdownObjectContainerImplTest, - TestShutdown_AsyncBleScannerShutdown) { - fake_ble_scanner_->set_is_discovery_session_active(true); - EXPECT_FALSE(fake_ble_scanner_->ShouldDiscoverySessionBeActive()); - EXPECT_TRUE(fake_ble_scanner_->IsDiscoverySessionActive()); - - // Start the shutdown; it should not yet succeed since there is an active - // discovery session. - CallShutdown(); - EXPECT_FALSE(was_shutdown_callback_invoked_); - - // Now, remove the discovery session; this should cause the shutdown to - // complete. - fake_ble_scanner_->set_is_discovery_session_active(false); - fake_ble_scanner_->NotifyDiscoverySessionStateChanged( - false /* discovery_session_active */); - EXPECT_TRUE(was_shutdown_callback_invoked_); -} - -TEST_F(AsynchronousShutdownObjectContainerImplTest, TestShutdown_AsyncDisconnectTetheringRequestSenderShutdown) { fake_disconnect_tethering_request_sender_->set_has_pending_requests(true); EXPECT_TRUE(fake_disconnect_tethering_request_sender_->HasPendingRequests()); @@ -213,13 +150,6 @@ TEST_F(AsynchronousShutdownObjectContainerImplTest, TestShutdown_MultipleSimultaneousAsyncShutdowns) { - fake_ble_advertiser_->set_are_advertisements_registered(true); - EXPECT_TRUE(fake_ble_advertiser_->AreAdvertisementsRegistered()); - - fake_ble_scanner_->set_is_discovery_session_active(true); - EXPECT_FALSE(fake_ble_scanner_->ShouldDiscoverySessionBeActive()); - EXPECT_TRUE(fake_ble_scanner_->IsDiscoverySessionActive()); - fake_disconnect_tethering_request_sender_->set_has_pending_requests(true); EXPECT_TRUE(fake_disconnect_tethering_request_sender_->HasPendingRequests()); @@ -228,20 +158,6 @@ CallShutdown(); EXPECT_FALSE(was_shutdown_callback_invoked_); - // Now, remove the advertisements; this should not cause the shutdown to - // complete since there is still an active discovery session and pending - // requests. - fake_ble_advertiser_->set_are_advertisements_registered(false); - fake_ble_advertiser_->NotifyAllAdvertisementsUnregistered(); - EXPECT_FALSE(was_shutdown_callback_invoked_); - - // Now, remove the discovery session; this should not cause the shutdown to - // complete since there are still pending requests. - fake_ble_scanner_->set_is_discovery_session_active(false); - fake_ble_scanner_->NotifyDiscoverySessionStateChanged( - false /* discovery_session_active */); - EXPECT_FALSE(was_shutdown_callback_invoked_); - // Now, finish the pending requests; this should cause the shutdown to // complete. fake_disconnect_tethering_request_sender_->set_has_pending_requests(false); @@ -250,26 +166,6 @@ EXPECT_TRUE(was_shutdown_callback_invoked_); } -TEST_F(AsynchronousShutdownObjectContainerImplTest, - TestShutdown_MultipleSimultaneousAsyncShutdowns_BluetoothDisabled) { - fake_ble_advertiser_->set_are_advertisements_registered(true); - EXPECT_TRUE(fake_ble_advertiser_->AreAdvertisementsRegistered()); - - fake_ble_scanner_->set_is_discovery_session_active(true); - EXPECT_FALSE(fake_ble_scanner_->ShouldDiscoverySessionBeActive()); - EXPECT_TRUE(fake_ble_scanner_->IsDiscoverySessionActive()); - - fake_disconnect_tethering_request_sender_->set_has_pending_requests(true); - EXPECT_TRUE(fake_disconnect_tethering_request_sender_->HasPendingRequests()); - - // Shut off Bluetooth power. This should cause a synchronous shutdown despite - // the fact that there are still objects which require an asynchronous - // shutdown. - is_adapter_powered_ = false; - CallShutdown(); - EXPECT_TRUE(was_shutdown_callback_invoked_); -} - } // namespace tether } // namespace chromeos
diff --git a/chromeos/components/tether/ble_advertiser_impl.cc b/chromeos/components/tether/ble_advertiser_impl.cc deleted file mode 100644 index 8a58ef3..0000000 --- a/chromeos/components/tether/ble_advertiser_impl.cc +++ /dev/null
@@ -1,187 +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 "chromeos/components/tether/ble_advertiser_impl.h" - -#include "base/bind.h" -#include "base/memory/ptr_util.h" -#include "base/threading/thread_task_runner_handle.h" -#include "chromeos/components/proximity_auth/logging/logging.h" -#include "chromeos/services/secure_channel/ble_service_data_helper.h" -#include "chromeos/services/secure_channel/device_id_pair.h" -#include "chromeos/services/secure_channel/error_tolerant_ble_advertisement_impl.h" -#include "components/cryptauth/ble/ble_advertisement_generator.h" -#include "components/cryptauth/proto/cryptauth_api.pb.h" -#include "components/cryptauth/remote_device_ref.h" -#include "device/bluetooth/bluetooth_advertisement.h" - -namespace chromeos { - -namespace tether { - -namespace { - -const char kStubLocalDeviceId[] = "N/A"; - -// Instant Tethering does not make use of the "local device ID" argument, since -// all connections are from the same device. -// TODO(hansberry): Remove when SecureChannelClient migration is complete. -secure_channel::DeviceIdPair StubDeviceIdPair( - const std::string& remote_device_id) { - return secure_channel::DeviceIdPair(remote_device_id, kStubLocalDeviceId); -} - -} // namespace - -// static -BleAdvertiserImpl::Factory* BleAdvertiserImpl::Factory::factory_instance_ = - nullptr; - -// static -std::unique_ptr<BleAdvertiser> BleAdvertiserImpl::Factory::NewInstance( - secure_channel::BleServiceDataHelper* ble_service_data_helper, - secure_channel::BleSynchronizerBase* ble_synchronizer) { - if (!factory_instance_) - factory_instance_ = new Factory(); - - return factory_instance_->BuildInstance(ble_service_data_helper, - ble_synchronizer); -} - -// static -void BleAdvertiserImpl::Factory::SetInstanceForTesting(Factory* factory) { - factory_instance_ = factory; -} - -std::unique_ptr<BleAdvertiser> BleAdvertiserImpl::Factory::BuildInstance( - secure_channel::BleServiceDataHelper* ble_service_data_helper, - secure_channel::BleSynchronizerBase* ble_synchronizer) { - return base::WrapUnique( - new BleAdvertiserImpl(ble_service_data_helper, ble_synchronizer)); -} - -BleAdvertiserImpl::AdvertisementMetadata::AdvertisementMetadata( - const std::string& device_id, - std::unique_ptr<cryptauth::DataWithTimestamp> service_data) - : device_id(device_id), service_data(std::move(service_data)) {} - -BleAdvertiserImpl::AdvertisementMetadata::~AdvertisementMetadata() = default; - -BleAdvertiserImpl::BleAdvertiserImpl( - secure_channel::BleServiceDataHelper* ble_service_data_helper, - secure_channel::BleSynchronizerBase* ble_synchronizer) - : ble_service_data_helper_(ble_service_data_helper), - ble_synchronizer_(ble_synchronizer), - task_runner_(base::ThreadTaskRunnerHandle::Get()), - weak_ptr_factory_(this) {} - -BleAdvertiserImpl::~BleAdvertiserImpl() = default; - -bool BleAdvertiserImpl::StartAdvertisingToDevice(const std::string& device_id) { - int index_for_device = -1; - for (size_t i = 0; i < secure_channel::kMaxConcurrentAdvertisements; ++i) { - if (!registered_device_metadata_[i]) { - index_for_device = i; - break; - } - } - - if (index_for_device == -1) { - PA_LOG(ERROR) << "Attempted to register a device when the maximum number " - << "of devices have already been registered."; - return false; - } - - std::unique_ptr<cryptauth::DataWithTimestamp> service_data = - ble_service_data_helper_->GenerateForegroundAdvertisement( - secure_channel::DeviceIdPair(device_id /* remote_device_id */, - kStubLocalDeviceId)); - if (!service_data) { - PA_LOG(WARNING) << "Error generating advertisement for device with ID " - << cryptauth::RemoteDeviceRef::TruncateDeviceIdForLogs( - device_id) - << ". Cannot advertise."; - return false; - } - - registered_device_metadata_[index_for_device].reset( - new AdvertisementMetadata(device_id, std::move(service_data))); - UpdateAdvertisements(); - - return true; -} - -bool BleAdvertiserImpl::StopAdvertisingToDevice(const std::string& device_id) { - for (auto& metadata : registered_device_metadata_) { - if (metadata && metadata->device_id == device_id) { - metadata.reset(); - UpdateAdvertisements(); - return true; - } - } - - return false; -} - -bool BleAdvertiserImpl::AreAdvertisementsRegistered() { - for (const auto& advertisement : advertisements_) { - if (advertisement) - return true; - } - - return false; -} - -void BleAdvertiserImpl::SetTaskRunnerForTesting( - scoped_refptr<base::TaskRunner> test_task_runner) { - task_runner_ = test_task_runner; -} - -void BleAdvertiserImpl::UpdateAdvertisements() { - for (size_t i = 0; i < secure_channel::kMaxConcurrentAdvertisements; ++i) { - std::unique_ptr<AdvertisementMetadata>& metadata = - registered_device_metadata_[i]; - std::unique_ptr<secure_channel::ErrorTolerantBleAdvertisement>& - advertisement = advertisements_[i]; - - // If there is a registered device but no associated advertisement, create - // the advertisement. - if (metadata && !advertisement) { - std::unique_ptr<cryptauth::DataWithTimestamp> service_data_copy = - std::make_unique<cryptauth::DataWithTimestamp>( - *metadata->service_data); - advertisements_[i] = - secure_channel::ErrorTolerantBleAdvertisementImpl::Factory::Get() - ->BuildInstance(StubDeviceIdPair(metadata->device_id), - std::move(service_data_copy), ble_synchronizer_); - continue; - } - - // If there is no registered device but there is an advertisement, stop it - // if it has not yet been stopped. - if (!metadata && advertisement && !advertisement->HasBeenStopped()) { - advertisement->Stop(base::Bind(&BleAdvertiserImpl::OnAdvertisementStopped, - weak_ptr_factory_.GetWeakPtr(), - i /* index */)); - } - } -} - -void BleAdvertiserImpl::OnAdvertisementStopped(size_t index) { - DCHECK(advertisements_[index] && advertisements_[index]->HasBeenStopped()); - advertisements_[index].reset(); - - // Update advertisements, but do so as part of a new task in the run loop to - // prevent the possibility of a crash. See crbug.com/776241. - task_runner_->PostTask( - FROM_HERE, base::BindOnce(&BleAdvertiserImpl::UpdateAdvertisements, - weak_ptr_factory_.GetWeakPtr())); - - if (!AreAdvertisementsRegistered()) - NotifyAllAdvertisementsUnregistered(); -} - -} // namespace tether - -} // namespace chromeos
diff --git a/chromeos/components/tether/ble_advertiser_impl.h b/chromeos/components/tether/ble_advertiser_impl.h deleted file mode 100644 index ccdca39..0000000 --- a/chromeos/components/tether/ble_advertiser_impl.h +++ /dev/null
@@ -1,107 +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 CHROMEOS_COMPONENTS_TETHER_BLE_ADVERTISER_IMPL_H_ -#define CHROMEOS_COMPONENTS_TETHER_BLE_ADVERTISER_IMPL_H_ - -#include <array> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "chromeos/components/tether/ble_advertiser.h" -#include "chromeos/services/secure_channel/ble_constants.h" -#include "components/cryptauth/data_with_timestamp.h" - -namespace base { -class TaskRunner; -} // namespace base - -namespace chromeos { - -namespace secure_channel { -class BleServiceDataHelper; -class BleSynchronizerBase; -class ErrorTolerantBleAdvertisement; -} // namespace secure_channel - -namespace tether { - -// Concrete BleAdvertiser implementation. -class BleAdvertiserImpl : public BleAdvertiser { - public: - class Factory { - public: - static std::unique_ptr<BleAdvertiser> NewInstance( - secure_channel::BleServiceDataHelper* ble_service_data_helper, - secure_channel::BleSynchronizerBase* ble_synchronizer); - static void SetInstanceForTesting(Factory* factory); - - protected: - virtual std::unique_ptr<BleAdvertiser> BuildInstance( - secure_channel::BleServiceDataHelper* ble_service_data_helper, - secure_channel::BleSynchronizerBase* ble_synchronizer); - - private: - static Factory* factory_instance_; - }; - - ~BleAdvertiserImpl() override; - - // BleAdvertiser: - bool StartAdvertisingToDevice(const std::string& device_id) override; - bool StopAdvertisingToDevice(const std::string& device_id) override; - bool AreAdvertisementsRegistered() override; - - protected: - BleAdvertiserImpl( - secure_channel::BleServiceDataHelper* ble_service_data_helper, - secure_channel::BleSynchronizerBase* ble_synchronizer); - - private: - friend class BleAdvertiserImplTest; - - // Data needed to generate an advertisement. - struct AdvertisementMetadata { - AdvertisementMetadata( - const std::string& device_id, - std::unique_ptr<cryptauth::DataWithTimestamp> service_data); - ~AdvertisementMetadata(); - - std::string device_id; - std::unique_ptr<cryptauth::DataWithTimestamp> service_data; - }; - - void SetTaskRunnerForTesting( - scoped_refptr<base::TaskRunner> test_task_runner); - void UpdateAdvertisements(); - void OnAdvertisementStopped(size_t index); - - secure_channel::BleServiceDataHelper* ble_service_data_helper_; - secure_channel::BleSynchronizerBase* ble_synchronizer_; - - scoped_refptr<base::TaskRunner> task_runner_; - - // |registered_device_ids_| holds the device IDs that are currently - // registered and is always up-to-date. |advertisements_| contains the active - // advertisements, which may not correspond exactly to - // |registered_device_ids_| in the case that a previous advertisement failed - // to unregister. - std::array<std::unique_ptr<AdvertisementMetadata>, - secure_channel::kMaxConcurrentAdvertisements> - registered_device_metadata_; - std::array<std::unique_ptr<secure_channel::ErrorTolerantBleAdvertisement>, - secure_channel::kMaxConcurrentAdvertisements> - advertisements_; - - base::WeakPtrFactory<BleAdvertiserImpl> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(BleAdvertiserImpl); -}; - -} // namespace tether - -} // namespace chromeos - -#endif // CHROMEOS_COMPONENTS_TETHER_BLE_ADVERTISER_IMPL_H_
diff --git a/chromeos/components/tether/ble_advertiser_impl_unittest.cc b/chromeos/components/tether/ble_advertiser_impl_unittest.cc deleted file mode 100644 index 6c9b8768..0000000 --- a/chromeos/components/tether/ble_advertiser_impl_unittest.cc +++ /dev/null
@@ -1,405 +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. - -#include "chromeos/components/tether/ble_advertiser_impl.h" - -#include "base/bind.h" -#include "base/callback_forward.h" -#include "base/memory/ptr_util.h" -#include "base/stl_util.h" -#include "base/test/scoped_task_environment.h" -#include "base/test/test_simple_task_runner.h" -#include "chromeos/services/secure_channel/ble_constants.h" -#include "chromeos/services/secure_channel/device_id_pair.h" -#include "chromeos/services/secure_channel/error_tolerant_ble_advertisement_impl.h" -#include "chromeos/services/secure_channel/fake_ble_service_data_helper.h" -#include "chromeos/services/secure_channel/fake_ble_synchronizer.h" -#include "chromeos/services/secure_channel/fake_error_tolerant_ble_advertisement.h" -#include "components/cryptauth/proto/cryptauth_api.pb.h" -#include "components/cryptauth/remote_device_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace chromeos { - -namespace tether { - -namespace { - -const char kStubLocalDeviceId[] = "N/A"; - -std::vector<cryptauth::DataWithTimestamp> GenerateFakeAdvertisements() { - cryptauth::DataWithTimestamp advertisement1("advertisement1", 1000L, 2000L); - cryptauth::DataWithTimestamp advertisement2("advertisement2", 2000L, 3000L); - cryptauth::DataWithTimestamp advertisement3("advertisement3", 3000L, 4000L); - - std::vector<cryptauth::DataWithTimestamp> advertisements = { - advertisement1, advertisement2, advertisement3}; - return advertisements; -} - -class FakeErrorTolerantBleAdvertisementFactory - : public secure_channel::ErrorTolerantBleAdvertisementImpl::Factory { - public: - FakeErrorTolerantBleAdvertisementFactory() = default; - ~FakeErrorTolerantBleAdvertisementFactory() override = default; - - const std::vector<secure_channel::FakeErrorTolerantBleAdvertisement*>& - active_advertisements() { - return active_advertisements_; - } - - size_t num_created() { return num_created_; } - - // secure_channel::ErrorTolerantBleAdvertisementImpl::Factory: - std::unique_ptr<secure_channel::ErrorTolerantBleAdvertisement> BuildInstance( - const secure_channel::DeviceIdPair& device_id_pair, - std::unique_ptr<cryptauth::DataWithTimestamp> advertisement_data, - secure_channel::BleSynchronizerBase* ble_synchronizer) override { - auto fake_advertisement = - std::make_unique<secure_channel::FakeErrorTolerantBleAdvertisement>( - device_id_pair, - base::BindOnce(&FakeErrorTolerantBleAdvertisementFactory:: - OnFakeAdvertisementDeleted, - base::Unretained(this))); - active_advertisements_.push_back(fake_advertisement.get()); - ++num_created_; - return fake_advertisement; - } - - protected: - void OnFakeAdvertisementDeleted( - const secure_channel::DeviceIdPair& device_id_pair) { - auto it = std::find_if( - active_advertisements_.begin(), active_advertisements_.end(), - [&device_id_pair](const auto* advertisement) { - return advertisement->device_id_pair() == device_id_pair; - }); - active_advertisements_.erase(it); - } - - private: - std::vector<secure_channel::FakeErrorTolerantBleAdvertisement*> - active_advertisements_; - size_t num_created_ = 0; -}; - -class TestObserver final : public BleAdvertiser::Observer { - public: - TestObserver() = default; - ~TestObserver() override = default; - - size_t num_times_all_advertisements_unregistered() { - return num_times_all_advertisements_unregistered_; - } - - // BleAdvertiser::Observer: - void OnAllAdvertisementsUnregistered() override { - ++num_times_all_advertisements_unregistered_; - } - - private: - size_t num_times_all_advertisements_unregistered_ = 0; -}; - -// Deletes the BleAdvertiser when notified. -class DeletingObserver final : public BleAdvertiser::Observer { - public: - DeletingObserver(std::unique_ptr<BleAdvertiserImpl>& ble_advertiser) - : ble_advertiser_(ble_advertiser) { - ble_advertiser_->AddObserver(this); - } - - ~DeletingObserver() override = default; - - // BleAdvertiser::Observer: - void OnAllAdvertisementsUnregistered() override { - ble_advertiser_->RemoveObserver(this); - ble_advertiser_.reset(); - } - - private: - std::unique_ptr<BleAdvertiserImpl>& ble_advertiser_; -}; - -} // namespace - -class BleAdvertiserImplTest : public testing::Test { - protected: - BleAdvertiserImplTest() - : fake_devices_(cryptauth::CreateRemoteDeviceRefListForTest(3)), - fake_advertisements_(GenerateFakeAdvertisements()) {} - - void SetUp() override { - fake_ble_service_data_helper_ = - std::make_unique<secure_channel::FakeBleServiceDataHelper>(); - fake_ble_service_data_helper_->SetAdvertisement( - secure_channel::DeviceIdPair(fake_devices_[0].GetDeviceId(), - kStubLocalDeviceId), - fake_advertisements_[0]); - fake_ble_service_data_helper_->SetAdvertisement( - secure_channel::DeviceIdPair(fake_devices_[1].GetDeviceId(), - kStubLocalDeviceId), - fake_advertisements_[1]); - fake_ble_service_data_helper_->SetAdvertisement( - secure_channel::DeviceIdPair(fake_devices_[2].GetDeviceId(), - kStubLocalDeviceId), - fake_advertisements_[2]); - - fake_ble_synchronizer_ = - std::make_unique<secure_channel::FakeBleSynchronizer>(); - - fake_advertisement_factory_ = - base::WrapUnique(new FakeErrorTolerantBleAdvertisementFactory()); - secure_channel::ErrorTolerantBleAdvertisementImpl::Factory:: - SetFactoryForTesting(fake_advertisement_factory_.get()); - - ble_advertiser_ = base::WrapUnique(new BleAdvertiserImpl( - fake_ble_service_data_helper_.get(), fake_ble_synchronizer_.get())); - - test_task_runner_ = base::MakeRefCounted<base::TestSimpleTaskRunner>(); - ble_advertiser_->SetTaskRunnerForTesting(test_task_runner_); - - test_observer_ = base::WrapUnique(new TestObserver()); - ble_advertiser_->AddObserver(test_observer_.get()); - } - - void TearDown() override { - secure_channel::ErrorTolerantBleAdvertisementImpl::Factory:: - SetFactoryForTesting(nullptr); - } - - void VerifyAdvertisementHasBeenStopped( - size_t index, - const std::string& expected_device_id) { - secure_channel::FakeErrorTolerantBleAdvertisement* advertisement = - fake_advertisement_factory_->active_advertisements()[index]; - EXPECT_EQ(expected_device_id, - advertisement->device_id_pair().remote_device_id()); - EXPECT_TRUE(advertisement->HasBeenStopped()); - } - - void InvokeAdvertisementStoppedCallback( - size_t index, - const std::string& expected_device_id) { - secure_channel::FakeErrorTolerantBleAdvertisement* advertisement = - fake_advertisement_factory_->active_advertisements()[index]; - EXPECT_EQ(expected_device_id, - advertisement->device_id_pair().remote_device_id()); - advertisement->InvokeStopCallback(); - } - - const base::test::ScopedTaskEnvironment scoped_task_environment_; - const cryptauth::RemoteDeviceRefList fake_devices_; - const std::vector<cryptauth::DataWithTimestamp> fake_advertisements_; - - std::unique_ptr<secure_channel::FakeBleServiceDataHelper> - fake_ble_service_data_helper_; - std::unique_ptr<secure_channel::FakeBleSynchronizer> fake_ble_synchronizer_; - - scoped_refptr<base::TestSimpleTaskRunner> test_task_runner_; - - std::unique_ptr<TestObserver> test_observer_; - - std::unique_ptr<FakeErrorTolerantBleAdvertisementFactory> - fake_advertisement_factory_; - - std::unique_ptr<BleAdvertiserImpl> ble_advertiser_; - - private: - DISALLOW_COPY_AND_ASSIGN(BleAdvertiserImplTest); -}; - -TEST_F(BleAdvertiserImplTest, CannotGenerateAdvertisement) { - fake_ble_service_data_helper_->RemoveAdvertisement( - secure_channel::DeviceIdPair(fake_devices_[0].GetDeviceId(), - kStubLocalDeviceId)); - - EXPECT_FALSE(ble_advertiser_->StartAdvertisingToDevice( - fake_devices_[0].GetDeviceId())); - EXPECT_EQ(0u, fake_advertisement_factory_->num_created()); - EXPECT_EQ(0u, test_observer_->num_times_all_advertisements_unregistered()); -} - -// ryan -TEST_F(BleAdvertiserImplTest, AdvertisementRegisteredSuccessfully) { - EXPECT_TRUE(ble_advertiser_->StartAdvertisingToDevice( - fake_devices_[0].GetDeviceId())); - EXPECT_EQ(1u, fake_advertisement_factory_->num_created()); - EXPECT_EQ(1u, fake_advertisement_factory_->active_advertisements().size()); - EXPECT_TRUE(ble_advertiser_->AreAdvertisementsRegistered()); - EXPECT_EQ(0u, test_observer_->num_times_all_advertisements_unregistered()); - - // Now, unregister. - EXPECT_TRUE( - ble_advertiser_->StopAdvertisingToDevice(fake_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_advertiser_->AreAdvertisementsRegistered()); - - // The advertisement should have been stopped, but it should not yet have - // been removed. - EXPECT_EQ(1u, fake_advertisement_factory_->active_advertisements().size()); - VerifyAdvertisementHasBeenStopped(0u /* index */, - fake_devices_[0].GetDeviceId()); - - // Invoke the stop callback and ensure the advertisement was deleted. - InvokeAdvertisementStoppedCallback(0u /* index */, - fake_devices_[0].GetDeviceId()); - test_task_runner_->RunUntilIdle(); - EXPECT_EQ(0u, fake_advertisement_factory_->active_advertisements().size()); - EXPECT_FALSE(ble_advertiser_->AreAdvertisementsRegistered()); - EXPECT_EQ(1u, test_observer_->num_times_all_advertisements_unregistered()); -} - -TEST_F(BleAdvertiserImplTest, AdvertisementRegisteredSuccessfully_TwoDevices) { - EXPECT_TRUE(ble_advertiser_->StartAdvertisingToDevice( - fake_devices_[0].GetDeviceId())); - EXPECT_EQ(1u, fake_advertisement_factory_->num_created()); - EXPECT_EQ(1u, fake_advertisement_factory_->active_advertisements().size()); - EXPECT_TRUE(ble_advertiser_->AreAdvertisementsRegistered()); - EXPECT_EQ(0u, test_observer_->num_times_all_advertisements_unregistered()); - - EXPECT_TRUE(ble_advertiser_->StartAdvertisingToDevice( - fake_devices_[1].GetDeviceId())); - EXPECT_EQ(2u, fake_advertisement_factory_->num_created()); - EXPECT_EQ(2u, fake_advertisement_factory_->active_advertisements().size()); - EXPECT_TRUE(ble_advertiser_->AreAdvertisementsRegistered()); - EXPECT_EQ(0u, test_observer_->num_times_all_advertisements_unregistered()); - - // Unregister device 0. - EXPECT_TRUE( - ble_advertiser_->StopAdvertisingToDevice(fake_devices_[0].GetDeviceId())); - EXPECT_EQ(2u, fake_advertisement_factory_->active_advertisements().size()); - InvokeAdvertisementStoppedCallback(0u /* index */, - fake_devices_[0].GetDeviceId()); - EXPECT_EQ(1u, fake_advertisement_factory_->active_advertisements().size()); - EXPECT_TRUE(ble_advertiser_->AreAdvertisementsRegistered()); - EXPECT_EQ(0u, test_observer_->num_times_all_advertisements_unregistered()); - - // Unregister device 1. - EXPECT_TRUE( - ble_advertiser_->StopAdvertisingToDevice(fake_devices_[1].GetDeviceId())); - EXPECT_EQ(1u, fake_advertisement_factory_->active_advertisements().size()); - InvokeAdvertisementStoppedCallback(0u /* index */, - fake_devices_[1].GetDeviceId()); - test_task_runner_->RunUntilIdle(); - EXPECT_EQ(0u, fake_advertisement_factory_->active_advertisements().size()); - EXPECT_FALSE(ble_advertiser_->AreAdvertisementsRegistered()); - EXPECT_EQ(1u, test_observer_->num_times_all_advertisements_unregistered()); -} - -TEST_F(BleAdvertiserImplTest, TooManyDevicesRegistered) { - ASSERT_EQ(2u, secure_channel::kMaxConcurrentAdvertisements); - - // Register device 0. - EXPECT_TRUE(ble_advertiser_->StartAdvertisingToDevice( - fake_devices_[0].GetDeviceId())); - EXPECT_EQ(1u, fake_advertisement_factory_->num_created()); - EXPECT_EQ(1u, fake_advertisement_factory_->active_advertisements().size()); - - // Register device 1. - EXPECT_TRUE(ble_advertiser_->StartAdvertisingToDevice( - fake_devices_[1].GetDeviceId())); - EXPECT_EQ(2u, fake_advertisement_factory_->num_created()); - EXPECT_EQ(2u, fake_advertisement_factory_->active_advertisements().size()); - - // Register device 2. This should fail, since it is over the limit. - EXPECT_FALSE(ble_advertiser_->StartAdvertisingToDevice( - fake_devices_[2].GetDeviceId())); - EXPECT_EQ(2u, fake_advertisement_factory_->num_created()); - EXPECT_EQ(2u, fake_advertisement_factory_->active_advertisements().size()); - - // Now, stop advertising to device 1. It should now be possible to advertise - // to device 2. - EXPECT_TRUE( - ble_advertiser_->StopAdvertisingToDevice(fake_devices_[1].GetDeviceId())); - EXPECT_TRUE(ble_advertiser_->StartAdvertisingToDevice( - fake_devices_[2].GetDeviceId())); - - // However, the advertisement for device 1 should still be present, and no new - // advertisement for device 2 should have yet been created. - EXPECT_EQ(2u, fake_advertisement_factory_->num_created()); - EXPECT_EQ(2u, fake_advertisement_factory_->active_advertisements().size()); - VerifyAdvertisementHasBeenStopped(1u /* index */, - fake_devices_[1].GetDeviceId()); - - // Stop the advertisement for device 1. This should cause a new advertisement - // for device 2 to be created. - InvokeAdvertisementStoppedCallback(1u /* index */, - fake_devices_[1].GetDeviceId()); - test_task_runner_->RunUntilIdle(); - EXPECT_EQ(3u, fake_advertisement_factory_->num_created()); - EXPECT_EQ(2u, fake_advertisement_factory_->active_advertisements().size()); - - // Verify that the remaining active advertisements correspond to the correct - // devices. - EXPECT_EQ(fake_devices_[0].GetDeviceId(), - fake_advertisement_factory_->active_advertisements()[0] - ->device_id_pair() - .remote_device_id()); - EXPECT_EQ(fake_devices_[2].GetDeviceId(), - fake_advertisement_factory_->active_advertisements()[1] - ->device_id_pair() - .remote_device_id()); -} - -// Regression test for crbug.com/739883. This issue arises when the following -// occurs: -// (1) BleAdvertiserImpl starts advertising to device A. -// (2) BleAdvertiserImpl stops advertising to device A. The advertisement -// starts its asynchyronous unregistration flow. -// (3) BleAdvertiserImpl starts advertising to device A again, but the -// previous advertisement has not yet been fully unregistered. -// Before the fix for crbug.com/739883, this would cause an error of type -// ERROR_ADVERTISEMENT_ALREADY_EXISTS. However, the fix for this issue ensures -// that the new advertisement in step (3) above does not start until the -// previous one has been finished. -TEST_F(BleAdvertiserImplTest, SameAdvertisementAdded_FirstHasNotBeenStopped) { - EXPECT_TRUE(ble_advertiser_->StartAdvertisingToDevice( - fake_devices_[0].GetDeviceId())); - EXPECT_EQ(1u, fake_advertisement_factory_->num_created()); - EXPECT_EQ(1u, fake_advertisement_factory_->active_advertisements().size()); - - // Unregister, but do not invoke the stop callback. - EXPECT_TRUE( - ble_advertiser_->StopAdvertisingToDevice(fake_devices_[0].GetDeviceId())); - VerifyAdvertisementHasBeenStopped(0u /* index */, - fake_devices_[0].GetDeviceId()); - - // Start advertising again, to the same device. Since the previous - // advertisement has not successfully stopped, no new advertisement should - // have been created yet. - EXPECT_TRUE(ble_advertiser_->StartAdvertisingToDevice( - fake_devices_[0].GetDeviceId())); - EXPECT_EQ(1u, fake_advertisement_factory_->num_created()); - EXPECT_EQ(1u, fake_advertisement_factory_->active_advertisements().size()); - - // Now, complete the previous stop. This should cause a new advertisement to - // be generated, but only the new one should be active. - InvokeAdvertisementStoppedCallback(0u /* index */, - fake_devices_[0].GetDeviceId()); - test_task_runner_->RunUntilIdle(); - EXPECT_EQ(2u, fake_advertisement_factory_->num_created()); - EXPECT_EQ(1u, fake_advertisement_factory_->active_advertisements().size()); -} - -// Regression test for crbug.com/776241. This bug could cause a crash if, when -// BleAdvertiserImpl notifies observers that all advertisements were -// unregistered, an observer deletes BleAdvertiserImpl. The fix for this issue -// is simply processing the next advertisement in a new task so that the new -// task will be canceled if the object is deleted. Without the fix for -// crbug.com/776241, this test would crash. -TEST_F(BleAdvertiserImplTest, ObserverDeletesObjectWhenNotified) { - // For this test, use a DeletingObserver instead. - DeletingObserver deleting_observer(ble_advertiser_); - ble_advertiser_->RemoveObserver(test_observer_.get()); - - ble_advertiser_->StartAdvertisingToDevice(fake_devices_[0].GetDeviceId()); - ble_advertiser_->StopAdvertisingToDevice(fake_devices_[0].GetDeviceId()); - InvokeAdvertisementStoppedCallback(0u /* index */, - fake_devices_[0].GetDeviceId()); - test_task_runner_->RunUntilIdle(); -} - -} // namespace tether - -} // namespace chromeos
diff --git a/chromeos/components/tether/ble_connection_metrics_logger.cc b/chromeos/components/tether/ble_connection_metrics_logger.cc deleted file mode 100644 index 1a64d90..0000000 --- a/chromeos/components/tether/ble_connection_metrics_logger.cc +++ /dev/null
@@ -1,209 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chromeos/components/tether/ble_connection_metrics_logger.h" - -#include "base/memory/ptr_util.h" -#include "base/metrics/histogram_macros.h" -#include "base/time/default_clock.h" -#include "chromeos/components/proximity_auth/logging/logging.h" - -namespace chromeos { - -namespace tether { - -BleConnectionMetricsLogger::BleConnectionMetricsLogger() - : clock_(base::DefaultClock::GetInstance()) {} - -BleConnectionMetricsLogger::~BleConnectionMetricsLogger() = default; - -void BleConnectionMetricsLogger::OnConnectionAttemptStarted( - const std::string& device_id) { - device_id_to_started_scan_time_map_[device_id] = clock_->Now(); -} - -void BleConnectionMetricsLogger::OnAdvertisementReceived( - const std::string& device_id, - bool is_background_advertisement) { - device_id_to_received_advertisement_time_map_[device_id] = clock_->Now(); - RecordStartScanToReceiveAdvertisementDuration(device_id, - is_background_advertisement); -} - -void BleConnectionMetricsLogger::OnConnection( - const std::string& device_id, - bool is_background_advertisement) { - device_id_to_status_connected_time_map_[device_id] = clock_->Now(); - RecordStartScanToConnectionDuration(device_id, is_background_advertisement); -} - -void BleConnectionMetricsLogger::OnSecureChannelCreated( - const std::string& device_id, - bool is_background_advertisement) { - RecordConnectionToAuthenticationDuration(device_id, - is_background_advertisement); - RecordGattConnectionAttemptSuccessRate(true /* success */, - is_background_advertisement); - - device_id_to_status_authenticated_map_[device_id] = true; -} - -void BleConnectionMetricsLogger::OnDeviceDisconnected( - const std::string& device_id, - BleConnectionManager::StateChangeDetail state_change_detail, - bool is_background_advertisement) { - if (state_change_detail == - BleConnectionManager::StateChangeDetail:: - STATE_CHANGE_DETAIL_GATT_CONNECTION_WAS_ATTEMPTED) { - RecordGattConnectionAttemptSuccessRate(false /* success */, - is_background_advertisement); - } else if (state_change_detail == - BleConnectionManager::StateChangeDetail:: - STATE_CHANGE_DETAIL_DEVICE_WAS_UNREGISTERED) { - bool did_device_disconnect_after_success = - base::ContainsKey(device_id_to_status_authenticated_map_, device_id) && - device_id_to_status_authenticated_map_[device_id]; - RecordGattConnectionAttemptEffectiveSuccessRateWithRetries( - did_device_disconnect_after_success /* success */, - is_background_advertisement); - } - - device_id_to_started_scan_time_map_.erase(device_id); - device_id_to_received_advertisement_time_map_.erase(device_id); - device_id_to_status_connected_time_map_.erase(device_id); - device_id_to_status_authenticated_map_.erase(device_id); -} - -void BleConnectionMetricsLogger::RecordStartScanToReceiveAdvertisementDuration( - const std::string device_id, - bool is_background_advertisement) { - if (!base::ContainsKey(device_id_to_started_scan_time_map_, device_id) || - !base::ContainsKey(device_id_to_received_advertisement_time_map_, - device_id)) { - PA_LOG(ERROR) << "Failed to record start scan to advertisement duration: " - << "times are invalid"; - NOTREACHED(); - return; - } - - base::TimeDelta start_scan_to_received_advertisment_duration = - device_id_to_received_advertisement_time_map_[device_id] - - device_id_to_started_scan_time_map_[device_id]; - - if (is_background_advertisement) { - UMA_HISTOGRAM_TIMES( - "InstantTethering.Performance.StartScanToReceiveAdvertisementDuration." - "Background", - start_scan_to_received_advertisment_duration); - } else { - UMA_HISTOGRAM_TIMES( - "InstantTethering.Performance.StartScanToReceiveAdvertisementDuration", - start_scan_to_received_advertisment_duration); - } -} - -void BleConnectionMetricsLogger::RecordStartScanToConnectionDuration( - const std::string device_id, - bool is_background_advertisement) { - if (!base::ContainsKey(device_id_to_started_scan_time_map_, device_id) || - !base::ContainsKey(device_id_to_received_advertisement_time_map_, - device_id) || - !base::ContainsKey(device_id_to_status_connected_time_map_, device_id)) { - PA_LOG(ERROR) << "Failed to record start scan to connection duration: " - << "times are invalid"; - NOTREACHED(); - return; - } - - base::TimeDelta received_advertisment_to_connection_duration = - device_id_to_status_connected_time_map_[device_id] - - device_id_to_received_advertisement_time_map_[device_id]; - base::TimeDelta start_scan_to_connection_duration = - device_id_to_status_connected_time_map_[device_id] - - device_id_to_started_scan_time_map_[device_id]; - - if (is_background_advertisement) { - UMA_HISTOGRAM_MEDIUM_TIMES( - "InstantTethering.Performance.ReceiveAdvertisementToConnectionDuration." - "Background", - received_advertisment_to_connection_duration); - UMA_HISTOGRAM_MEDIUM_TIMES( - "InstantTethering.Performance.StartScanToConnectionDuration.Background", - start_scan_to_connection_duration); - } else { - UMA_HISTOGRAM_MEDIUM_TIMES( - "InstantTethering.Performance.ReceiveAdvertisementToConnectionDuration", - received_advertisment_to_connection_duration); - UMA_HISTOGRAM_MEDIUM_TIMES( - "InstantTethering.Performance.AdvertisementToConnectionDuration", - start_scan_to_connection_duration); - } - - device_id_to_started_scan_time_map_.erase(device_id); - device_id_to_received_advertisement_time_map_.erase(device_id); -} - -void BleConnectionMetricsLogger::RecordConnectionToAuthenticationDuration( - const std::string device_id, - bool is_background_advertisement) { - if (!base::ContainsKey(device_id_to_status_connected_time_map_, device_id)) { - PA_LOG(ERROR) << "Failed to record connection to authentication duration: " - << "connection start time is invalid"; - NOTREACHED(); - return; - } - - base::TimeDelta connection_to_authentication_duration = - clock_->Now() - device_id_to_status_connected_time_map_[device_id]; - if (is_background_advertisement) { - UMA_HISTOGRAM_TIMES( - "InstantTethering.Performance.ConnectionToAuthenticationDuration." - "Background", - connection_to_authentication_duration); - } else { - UMA_HISTOGRAM_TIMES( - "InstantTethering.Performance.ConnectionToAuthenticationDuration", - connection_to_authentication_duration); - } - - device_id_to_status_connected_time_map_.erase(device_id); -} - -void BleConnectionMetricsLogger::RecordGattConnectionAttemptSuccessRate( - bool success, - bool is_background_advertisement) { - if (is_background_advertisement) { - UMA_HISTOGRAM_BOOLEAN( - "InstantTethering.GattConnectionAttempt.SuccessRate.Background", - success); - } else { - UMA_HISTOGRAM_BOOLEAN("InstantTethering.GattConnectionAttempt.SuccessRate", - success); - } -} - -void BleConnectionMetricsLogger:: - RecordGattConnectionAttemptEffectiveSuccessRateWithRetries( - bool success, - bool is_background_advertisement) { - if (is_background_advertisement) { - UMA_HISTOGRAM_BOOLEAN( - "InstantTethering.GattConnectionAttempt." - "EffectiveSuccessRateWithRetries.Background", - success); - } else { - UMA_HISTOGRAM_BOOLEAN( - "InstantTethering.GattConnectionAttempt." - "EffectiveSuccessRateWithRetries", - success); - } -} - -void BleConnectionMetricsLogger::SetClockForTesting(base::Clock* test_clock) { - clock_ = test_clock; -} - -} // namespace tether - -} // namespace chromeos \ No newline at end of file
diff --git a/chromeos/components/tether/ble_connection_metrics_logger.h b/chromeos/components/tether/ble_connection_metrics_logger.h deleted file mode 100644 index 642c628..0000000 --- a/chromeos/components/tether/ble_connection_metrics_logger.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 CHROMEOS_COMPONENTS_TETHER_BLE_CONNECTION_METRICS_LOGGER_H_ -#define CHROMEOS_COMPONENTS_TETHER_BLE_CONNECTION_METRICS_LOGGER_H_ - -#include <map> -#include <string> - -#include "base/macros.h" -#include "chromeos/components/tether/ble_connection_manager.h" - -namespace base { -class Clock; -} - -namespace chromeos { - -namespace tether { - -// Responsible for logging metrics for various stages of a BLE connection to -// another device (both success and performance metrics). Listens on events -// BleConnectionManager to keep track of when events occur, and if they end in -// success or failure. -class BleConnectionMetricsLogger - : public BleConnectionManager::MetricsObserver { - public: - BleConnectionMetricsLogger(); - virtual ~BleConnectionMetricsLogger(); - - // BleConnectionManager::MetricsObserver: - void OnConnectionAttemptStarted(const std::string& device_id) override; - void OnAdvertisementReceived(const std::string& device_id, - bool is_background_advertisement) override; - void OnConnection(const std::string& device_id, - bool is_background_advertisement) override; - void OnSecureChannelCreated(const std::string& device_id, - bool is_background_advertisement) override; - void OnDeviceDisconnected( - const std::string& device_id, - BleConnectionManager::StateChangeDetail state_change_detail, - bool is_background_advertisement) override; - - private: - friend class BleConnectionMetricsLoggerTest; - - void RecordStartScanToReceiveAdvertisementDuration( - const std::string device_id, - bool is_background_advertisement); - void RecordStartScanToConnectionDuration(const std::string device_id, - bool is_background_advertisement); - void RecordConnectionToAuthenticationDuration( - const std::string device_id, - bool is_background_advertisement); - void RecordGattConnectionAttemptSuccessRate(bool success, - bool is_background_advertisement); - void RecordGattConnectionAttemptEffectiveSuccessRateWithRetries( - bool success, - bool is_background_advertisement); - - void SetClockForTesting(base::Clock* test_clock); - - base::Clock* clock_; - std::map<std::string, base::Time> device_id_to_started_scan_time_map_; - std::map<std::string, base::Time> - device_id_to_received_advertisement_time_map_; - std::map<std::string, base::Time> device_id_to_status_connected_time_map_; - std::map<std::string, bool> device_id_to_status_authenticated_map_; - - DISALLOW_COPY_AND_ASSIGN(BleConnectionMetricsLogger); -}; - -} // namespace tether - -} // namespace chromeos - -#endif // CHROMEOS_COMPONENTS_TETHER_BLE_CONNECTION_METRICS_LOGGER_H_ \ No newline at end of file
diff --git a/chromeos/components/tether/ble_connection_metrics_logger_unittest.cc b/chromeos/components/tether/ble_connection_metrics_logger_unittest.cc deleted file mode 100644 index 54f81e8..0000000 --- a/chromeos/components/tether/ble_connection_metrics_logger_unittest.cc +++ /dev/null
@@ -1,445 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chromeos/components/tether/ble_connection_metrics_logger.h" - -#include "base/memory/ptr_util.h" -#include "base/test/metrics/histogram_tester.h" -#include "base/test/simple_test_clock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace chromeos { - -namespace tether { - -constexpr base::TimeDelta kReceiveAdvertisementTime = - base::TimeDelta::FromSeconds(1); -constexpr base::TimeDelta kStatusConnectedTime = - base::TimeDelta::FromSeconds(3); -constexpr base::TimeDelta kStatusAuthenticatedTime = - base::TimeDelta::FromSeconds(7); - -static const size_t kNumFailedConnectionAttempts = 6u; - -std::string kDeviceId1 = "deviceId1"; -std::string kDeviceId2 = "deviceId2"; -std::string kDeviceId3 = "deviceId3"; - -class BleConnectionMetricsLoggerTest : public testing::Test { - protected: - BleConnectionMetricsLoggerTest() {} - - void SetUp() override { - ble_connection_metrics_logger_ = - base::WrapUnique(new BleConnectionMetricsLogger()); - - test_clock_.SetNow(base::Time::UnixEpoch()); - ble_connection_metrics_logger_->SetClockForTesting(&test_clock_); - } - - void AuthenticateAndDisconnectDeviceAndVerifyMetrics( - const std::string& device_id, - bool is_background_advertisement, - size_t num_previous_devices = 0u) { - size_t num_total_devices = num_previous_devices + 1; - - ble_connection_metrics_logger_->OnConnectionAttemptStarted(device_id); - - ReceiveAdvertisementAndAdvanceClock(device_id, is_background_advertisement); - - if (is_background_advertisement) { - histogram_tester_.ExpectTimeBucketCount( - "InstantTethering.Performance." - "StartScanToReceiveAdvertisementDuration.Background", - kReceiveAdvertisementTime, num_total_devices); - histogram_tester_.ExpectTotalCount( - "InstantTethering.Performance." - "StartScanToReceiveAdvertisementDuration", - 0); - } else { - histogram_tester_.ExpectTotalCount( - "InstantTethering.Performance." - "StartScanToReceiveAdvertisementDuration.Background", - 0); - histogram_tester_.ExpectTimeBucketCount( - "InstantTethering.Performance." - "StartScanToReceiveAdvertisementDuration", - kReceiveAdvertisementTime, num_total_devices); - } - - ConnectAndAdvanceClock(device_id, is_background_advertisement); - - if (is_background_advertisement) { - histogram_tester_.ExpectTimeBucketCount( - "InstantTethering.Performance." - "ReceiveAdvertisementToConnectionDuration.Background", - kStatusConnectedTime, num_total_devices); - histogram_tester_.ExpectTimeBucketCount( - "InstantTethering.Performance.StartScanToConnectionDuration." - "Background", - kReceiveAdvertisementTime + kStatusConnectedTime, num_total_devices); - - histogram_tester_.ExpectTotalCount( - "InstantTethering.Performance." - "ReceiveAdvertisementToConnectionDuration", - 0); - histogram_tester_.ExpectTotalCount( - "InstantTethering.Performance.AdvertisementToConnectionDuration", 0); - } else { - histogram_tester_.ExpectTotalCount( - "InstantTethering.Performance." - "ReceiveAdvertisementToConnectionDuration.Background", - 0); - histogram_tester_.ExpectTotalCount( - "InstantTethering.Performance.StartScanToConnectionDuration." - "Background", - 0); - - histogram_tester_.ExpectTimeBucketCount( - "InstantTethering.Performance." - "ReceiveAdvertisementToConnectionDuration", - kStatusConnectedTime, num_total_devices); - histogram_tester_.ExpectTimeBucketCount( - "InstantTethering.Performance.AdvertisementToConnectionDuration", - kReceiveAdvertisementTime + kStatusConnectedTime, num_total_devices); - } - - CreateSecureChannelAndAdvanceClock(device_id, is_background_advertisement); - - if (is_background_advertisement) { - histogram_tester_.ExpectTimeBucketCount( - "InstantTethering.Performance.ConnectionToAuthenticationDuration." - "Background", - kStatusAuthenticatedTime, num_total_devices); - } else { - histogram_tester_.ExpectTimeBucketCount( - "InstantTethering.Performance.ConnectionToAuthenticationDuration", - kStatusAuthenticatedTime, num_total_devices); - } - - ble_connection_metrics_logger_->OnDeviceDisconnected( - device_id, - BleConnectionManager::StateChangeDetail:: - STATE_CHANGE_DETAIL_DEVICE_WAS_UNREGISTERED, - is_background_advertisement); - - VerifyGattConnectionMetrics( - num_total_devices /* num_expected_successful_gatt_connections */, - 0u /* num_expected_failed_gatt_connections */, - num_total_devices /* num_expected_successful_effective_gatt_connections - */ - , - 0u /* num_expected_failed_effective_gatt_connections */, - is_background_advertisement); - } - - void VerifyGattConnectionMetrics( - size_t num_expected_successful_gatt_connections, - size_t num_expected_failed_gatt_connections, - size_t num_expected_successful_effective_gatt_connections, - size_t num_expected_failed_effective_gatt_connections, - bool is_background_advertisement) { - if (num_expected_successful_gatt_connections > 0u) { - if (is_background_advertisement) { - histogram_tester_.ExpectBucketCount( - "InstantTethering.GattConnectionAttempt.SuccessRate.Background", - true, num_expected_successful_gatt_connections); - } else { - histogram_tester_.ExpectBucketCount( - "InstantTethering.GattConnectionAttempt.SuccessRate", true, - num_expected_successful_gatt_connections); - } - } - - if (num_expected_failed_gatt_connections > 0u) { - if (is_background_advertisement) { - histogram_tester_.ExpectBucketCount( - "InstantTethering.GattConnectionAttempt.SuccessRate.Background", - false, num_expected_failed_gatt_connections); - } else { - histogram_tester_.ExpectBucketCount( - "InstantTethering.GattConnectionAttempt.SuccessRate", false, - num_expected_failed_gatt_connections); - } - } - - if (num_expected_successful_gatt_connections == 0u && - num_expected_failed_gatt_connections == 0u) { - histogram_tester_.ExpectTotalCount( - "InstantTethering.GattConnectionAttempt.SuccessRate.Background", 0u); - histogram_tester_.ExpectTotalCount( - "InstantTethering.GattConnectionAttempt.SuccessRate", 0u); - } - - if (num_expected_successful_effective_gatt_connections > 0u) { - if (is_background_advertisement) { - histogram_tester_.ExpectBucketCount( - "InstantTethering.GattConnectionAttempt." - "EffectiveSuccessRateWithRetries.Background", - true, num_expected_successful_effective_gatt_connections); - } else { - histogram_tester_.ExpectBucketCount( - "InstantTethering.GattConnectionAttempt." - "EffectiveSuccessRateWithRetries", - true, num_expected_successful_effective_gatt_connections); - } - } - - if (num_expected_failed_effective_gatt_connections > 0u) { - if (is_background_advertisement) { - histogram_tester_.ExpectBucketCount( - "InstantTethering.GattConnectionAttempt." - "EffectiveSuccessRateWithRetries.Background", - false, num_expected_failed_effective_gatt_connections); - } else { - histogram_tester_.ExpectBucketCount( - "InstantTethering.GattConnectionAttempt." - "EffectiveSuccessRateWithRetries", - false, num_expected_failed_effective_gatt_connections); - } - } - - if (num_expected_successful_effective_gatt_connections == 0u && - num_expected_failed_effective_gatt_connections == 0u) { - histogram_tester_.ExpectTotalCount( - "InstantTethering.GattConnectionAttempt." - "EffectiveSuccessRateWithRetries.Background", - 0u); - histogram_tester_.ExpectTotalCount( - "InstantTethering.GattConnectionAttempt." - "EffectiveSuccessRateWithRetries", - 0u); - } - } - - void FailAllGattConnectionAttemptsAndVerifyMetrics( - const std::string& device_id, - bool is_background_advertisement) { - AttemptGattConnectionsAndThenUnregister( - device_id, kNumFailedConnectionAttempts, - false /* succeed_on_additional_last_attempt */, - is_background_advertisement); - - VerifyGattConnectionMetrics( - 0u /* num_expected_successful_gatt_connections */, - kNumFailedConnectionAttempts /* num_expected_failed_gatt_connections */, - 0u /* num_expected_successful_effective_gatt_connections */, - 1u /* num_expected_failed_effective_gatt_connections */, - is_background_advertisement); - } - - void FailAlmostAllGattConnectionAttemptsAndVerifyMetrics( - const std::string& device_id, - bool is_background_advertisement) { - AttemptGattConnectionsAndThenUnregister( - device_id, kNumFailedConnectionAttempts, - true /* succeed_on_additional_last_attempt */, - is_background_advertisement); - - VerifyGattConnectionMetrics( - 1u /* num_expected_successful_gatt_connections */, - kNumFailedConnectionAttempts /* num_expected_failed_gatt_connections */, - 1u /* num_expected_successful_effective_gatt_connections */, - 0u /* num_expected_failed_effective_gatt_connections */, - is_background_advertisement); - } - - void AttemptGattConnectionsAndThenUnregister( - const std::string& device_id, - size_t num_failed_connection_attempts, - bool succeed_on_additional_last_attempt, - bool is_background_advertisement) { - for (size_t i = 0u; i < num_failed_connection_attempts; ++i) { - ble_connection_metrics_logger_->OnConnectionAttemptStarted(device_id); - ReceiveAdvertisementAndAdvanceClock(device_id, - is_background_advertisement); - - ble_connection_metrics_logger_->OnDeviceDisconnected( - device_id, - BleConnectionManager::StateChangeDetail:: - STATE_CHANGE_DETAIL_GATT_CONNECTION_WAS_ATTEMPTED, - is_background_advertisement); - } - - if (succeed_on_additional_last_attempt) { - // Now succeed on the last possible connection attempt: - ble_connection_metrics_logger_->OnConnectionAttemptStarted(device_id); - ReceiveAdvertisementAndAdvanceClock(device_id, - is_background_advertisement); - ConnectAndAdvanceClock(device_id, is_background_advertisement); - CreateSecureChannelAndAdvanceClock(device_id, - is_background_advertisement); - } - - ble_connection_metrics_logger_->OnDeviceDisconnected( - device_id, - BleConnectionManager::StateChangeDetail:: - STATE_CHANGE_DETAIL_DEVICE_WAS_UNREGISTERED, - is_background_advertisement); - } - - void ReceiveAdvertisementAndAdvanceClock(const std::string& device_id, - bool is_background_advertisement) { - test_clock_.Advance(kReceiveAdvertisementTime); - ble_connection_metrics_logger_->OnAdvertisementReceived( - device_id, is_background_advertisement); - } - - void ConnectAndAdvanceClock(const std::string& device_id, - bool is_background_advertisement) { - test_clock_.Advance(kStatusConnectedTime); - ble_connection_metrics_logger_->OnConnection(device_id, - is_background_advertisement); - } - - void CreateSecureChannelAndAdvanceClock(const std::string& device_id, - bool is_background_advertisement) { - test_clock_.Advance(kStatusAuthenticatedTime); - ble_connection_metrics_logger_->OnSecureChannelCreated( - device_id, is_background_advertisement); - } - - std::unique_ptr<BleConnectionMetricsLogger> ble_connection_metrics_logger_; - - base::SimpleTestClock test_clock_; - base::HistogramTester histogram_tester_; - - private: - DISALLOW_COPY_AND_ASSIGN(BleConnectionMetricsLoggerTest); -}; - -TEST_F(BleConnectionMetricsLoggerTest, TestRecordMetrics_OneDevice) { - AuthenticateAndDisconnectDeviceAndVerifyMetrics( - kDeviceId1, false /* is_background_advertisement */); -} - -TEST_F(BleConnectionMetricsLoggerTest, TestRecordMetrics_OneDevice_Background) { - AuthenticateAndDisconnectDeviceAndVerifyMetrics( - kDeviceId1, true /* is_background_advertisement */); -} - -TEST_F(BleConnectionMetricsLoggerTest, TestRecordMetrics_MultipleDevices) { - AuthenticateAndDisconnectDeviceAndVerifyMetrics( - kDeviceId1, false /* is_background_advertisement */, - 0u /* num_previous_devices */); - AuthenticateAndDisconnectDeviceAndVerifyMetrics( - kDeviceId2, false /* is_background_advertisement */, - 1u /* num_previous_devices */); - AuthenticateAndDisconnectDeviceAndVerifyMetrics( - kDeviceId3, false /* is_background_advertisement */, - 2u /* num_previous_devices */); -} - -TEST_F(BleConnectionMetricsLoggerTest, - TestRecordMetrics_MultipleDevices_Background) { - AuthenticateAndDisconnectDeviceAndVerifyMetrics( - kDeviceId1, true /* is_background_advertisement */, - 0u /* num_previous_devices */); - AuthenticateAndDisconnectDeviceAndVerifyMetrics( - kDeviceId2, true /* is_background_advertisement */, - 1u /* num_previous_devices */); - AuthenticateAndDisconnectDeviceAndVerifyMetrics( - kDeviceId3, true /* is_background_advertisement */, - 2u /* num_previous_devices */); -} - -TEST_F(BleConnectionMetricsLoggerTest, - TestRecordMetrics_NeverReceiveAdvertisement) { - ble_connection_metrics_logger_->OnConnectionAttemptStarted(kDeviceId1); - ble_connection_metrics_logger_->OnDeviceDisconnected( - kDeviceId1, - BleConnectionManager::StateChangeDetail:: - STATE_CHANGE_DETAIL_GATT_CONNECTION_WAS_ATTEMPTED, - false /* is_background_advertisement */); - - histogram_tester_.ExpectTotalCount( - "InstantTethering.Performance." - "StartScanToReceiveAdvertisementDuration", - 0); - histogram_tester_.ExpectTotalCount( - "InstantTethering.Performance." - "ReceiveAdvertisementToConnectionDuration", - 0); - histogram_tester_.ExpectTotalCount( - "InstantTethering.Performance.AdvertisementToConnectionDuration", 0); -} - -TEST_F(BleConnectionMetricsLoggerTest, TestRecordMetrics_NeverConnect) { - ble_connection_metrics_logger_->OnConnectionAttemptStarted(kDeviceId1); - ReceiveAdvertisementAndAdvanceClock(kDeviceId1, - false /* is_background_advertisement */); - ble_connection_metrics_logger_->OnDeviceDisconnected( - kDeviceId1, - BleConnectionManager::StateChangeDetail:: - STATE_CHANGE_DETAIL_GATT_CONNECTION_WAS_ATTEMPTED, - false /* is_background_advertisement */); - - histogram_tester_.ExpectTimeBucketCount( - "InstantTethering.Performance." - "StartScanToReceiveAdvertisementDuration", - kReceiveAdvertisementTime, 1); - histogram_tester_.ExpectTotalCount( - "InstantTethering.Performance." - "ReceiveAdvertisementToConnectionDuration", - 0); - histogram_tester_.ExpectTotalCount( - "InstantTethering.Performance.AdvertisementToConnectionDuration", 0); -} - -TEST_F(BleConnectionMetricsLoggerTest, - TestRecordMetrics_NeverCreateSecureChannel) { - ble_connection_metrics_logger_->OnConnectionAttemptStarted(kDeviceId1); - ReceiveAdvertisementAndAdvanceClock(kDeviceId1, - false /* is_background_advertisement */); - ConnectAndAdvanceClock(kDeviceId1, false /* is_background_advertisement */); - ble_connection_metrics_logger_->OnDeviceDisconnected( - kDeviceId1, - BleConnectionManager::StateChangeDetail:: - STATE_CHANGE_DETAIL_GATT_CONNECTION_WAS_ATTEMPTED, - false /* is_background_advertisement */); - - histogram_tester_.ExpectTimeBucketCount( - "InstantTethering.Performance." - "StartScanToReceiveAdvertisementDuration", - kReceiveAdvertisementTime, 1); - histogram_tester_.ExpectTimeBucketCount( - "InstantTethering.Performance." - "ReceiveAdvertisementToConnectionDuration", - kStatusConnectedTime, 1); - histogram_tester_.ExpectTimeBucketCount( - "InstantTethering.Performance.AdvertisementToConnectionDuration", - kReceiveAdvertisementTime + kStatusConnectedTime, 1); - histogram_tester_.ExpectTotalCount( - "InstantTethering.Performance.ConnectionToAuthenticationDuration", 0); -} - -TEST_F(BleConnectionMetricsLoggerTest, - TestRecordMetrics_CannotCompleteGattConnection_RetryLimitReached) { - FailAllGattConnectionAttemptsAndVerifyMetrics( - kDeviceId1, false /* is_background_advertisement */); -} - -TEST_F( - BleConnectionMetricsLoggerTest, - TestRecordMetrics_CannotCompleteGattConnection_RetryLimitReached_Background) { - FailAllGattConnectionAttemptsAndVerifyMetrics( - kDeviceId1, true /* is_background_advertisement */); -} - -TEST_F(BleConnectionMetricsLoggerTest, - TestRecordMetrics_CompleteGattConnection_RetryLimitAlmostReached) { - FailAlmostAllGattConnectionAttemptsAndVerifyMetrics( - kDeviceId1, false /* is_background_advertisement */); -} - -TEST_F( - BleConnectionMetricsLoggerTest, - TestRecordMetrics_CompleteGattConnection_RetryLimitAlmostReached_Background) { - FailAlmostAllGattConnectionAttemptsAndVerifyMetrics( - kDeviceId1, true /* is_background_advertisement */); -} - -} // namespace tether - -} // namespace chromeos
diff --git a/chromeos/components/tether/ble_scanner_impl.cc b/chromeos/components/tether/ble_scanner_impl.cc deleted file mode 100644 index 91b3590..0000000 --- a/chromeos/components/tether/ble_scanner_impl.cc +++ /dev/null
@@ -1,334 +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 "chromeos/components/tether/ble_scanner_impl.h" - -#include <memory> - -#include "base/bind.h" -#include "base/memory/ptr_util.h" -#include "base/strings/string_util.h" -#include "base/threading/thread_task_runner_handle.h" -#include "chromeos/chromeos_switches.h" -#include "chromeos/components/proximity_auth/logging/logging.h" -#include "chromeos/components/tether/tether_host_fetcher.h" -#include "chromeos/services/secure_channel/ble_constants.h" -#include "chromeos/services/secure_channel/ble_service_data_helper.h" -#include "chromeos/services/secure_channel/ble_synchronizer.h" -#include "chromeos/services/secure_channel/device_id_pair.h" -#include "components/cryptauth/proto/cryptauth_api.pb.h" -#include "components/cryptauth/remote_device_ref.h" -#include "device/bluetooth/bluetooth_device.h" -#include "device/bluetooth/bluetooth_discovery_session.h" -#include "device/bluetooth/bluetooth_uuid.h" - -namespace chromeos { - -namespace tether { - -namespace { - -// Instant Tethering does not make use of the "local device ID" argument, since -// all connections are from the same device. -// TODO(hansberry): Remove when SecureChannelClient migration is complete. -const char kStubLocalDeviceId[] = "N/A"; - -// Valid advertisement service data must be at least 2 bytes. -// As of March 2018, valid background advertisement service data is exactly 2 -// bytes, which identify the advertising device to the scanning device. -// Valid foreground advertisement service data must include at least 4 bytes: -// 2 bytes associated with the scanning device (used as a scan filter) and 2 -// bytes which identify the advertising device to the scanning device. -const size_t kMinNumBytesInServiceData = 2; - -} // namespace - -// static -BleScannerImpl::Factory* BleScannerImpl::Factory::factory_instance_ = nullptr; - -// static -std::unique_ptr<BleScanner> BleScannerImpl::Factory::NewInstance( - scoped_refptr<device::BluetoothAdapter> adapter, - secure_channel::BleServiceDataHelper* ble_service_data_helper, - secure_channel::BleSynchronizerBase* ble_synchronizer, - TetherHostFetcher* tether_host_fetcher) { - if (!factory_instance_) - factory_instance_ = new Factory(); - - return factory_instance_->BuildInstance( - adapter, ble_service_data_helper, ble_synchronizer, tether_host_fetcher); -} - -// static -void BleScannerImpl::Factory::SetInstanceForTesting(Factory* factory) { - factory_instance_ = factory; -} - -std::unique_ptr<BleScanner> BleScannerImpl::Factory::BuildInstance( - scoped_refptr<device::BluetoothAdapter> adapter, - secure_channel::BleServiceDataHelper* ble_service_data_helper, - secure_channel::BleSynchronizerBase* ble_synchronizer, - TetherHostFetcher* tether_host_fetcher) { - return base::WrapUnique(new BleScannerImpl( - adapter, ble_service_data_helper, ble_synchronizer, tether_host_fetcher)); -} - -BleScannerImpl::ServiceDataProviderImpl::ServiceDataProviderImpl() = default; - -BleScannerImpl::ServiceDataProviderImpl::~ServiceDataProviderImpl() = default; - -const std::vector<uint8_t>* -BleScannerImpl::ServiceDataProviderImpl::GetServiceDataForUUID( - device::BluetoothDevice* bluetooth_device) { - return bluetooth_device->GetServiceDataForUUID( - device::BluetoothUUID(secure_channel::kAdvertisingServiceUuid)); -} - -BleScannerImpl::BleScannerImpl( - scoped_refptr<device::BluetoothAdapter> adapter, - secure_channel::BleServiceDataHelper* ble_service_data_helper, - secure_channel::BleSynchronizerBase* ble_synchronizer, - TetherHostFetcher* tether_host_fetcher) - : adapter_(adapter), - ble_service_data_helper_(ble_service_data_helper), - ble_synchronizer_(ble_synchronizer), - tether_host_fetcher_(tether_host_fetcher), - service_data_provider_(std::make_unique<ServiceDataProviderImpl>()), - task_runner_(base::ThreadTaskRunnerHandle::Get()), - weak_ptr_factory_(this) { - adapter_->AddObserver(this); -} - -BleScannerImpl::~BleScannerImpl() { - adapter_->RemoveObserver(this); -} - -bool BleScannerImpl::RegisterScanFilterForDevice(const std::string& device_id) { - if (registered_remote_device_ids_.size() >= - secure_channel::kMaxConcurrentAdvertisements) { - // Each scan filter corresponds to an advertisement. Thus, the number of - // concurrent advertisements cannot exceed the maximum number of concurrent - // advertisements. - PA_LOG(WARNING) << "Attempted to start a scan for a new device when the " - << "maximum number of devices have already been " - << "registered."; - return false; - } - - registered_remote_device_ids_.push_back(device_id); - UpdateDiscoveryStatus(); - - return true; -} - -bool BleScannerImpl::UnregisterScanFilterForDevice( - const std::string& device_id) { - for (auto it = registered_remote_device_ids_.begin(); - it != registered_remote_device_ids_.end(); ++it) { - if (*it == device_id) { - registered_remote_device_ids_.erase(it); - UpdateDiscoveryStatus(); - return true; - } - } - - return false; -} - -bool BleScannerImpl::ShouldDiscoverySessionBeActive() { - return !registered_remote_device_ids_.empty(); -} - -bool BleScannerImpl::IsDiscoverySessionActive() { - ResetDiscoverySessionIfNotActive(); - - if (discovery_session_) { - // Once the session is stopped, the pointer is cleared. - DCHECK(discovery_session_->IsActive()); - return true; - } - - return false; -} - -void BleScannerImpl::SetTestDoubles( - std::unique_ptr<ServiceDataProvider> service_data_provider, - scoped_refptr<base::TaskRunner> test_task_runner) { - service_data_provider_ = std::move(service_data_provider); - task_runner_ = test_task_runner; -} - -bool BleScannerImpl::IsDeviceRegistered(const std::string& device_id) { - return base::ContainsValue(registered_remote_device_ids_, device_id); -} - -void BleScannerImpl::DeviceAdded(device::BluetoothAdapter* adapter, - device::BluetoothDevice* bluetooth_device) { - DCHECK_EQ(adapter_.get(), adapter); - HandleDeviceUpdated(bluetooth_device); -} - -void BleScannerImpl::DeviceChanged(device::BluetoothAdapter* adapter, - device::BluetoothDevice* bluetooth_device) { - DCHECK_EQ(adapter_.get(), adapter); - HandleDeviceUpdated(bluetooth_device); -} - -void BleScannerImpl::ResetDiscoverySessionIfNotActive() { - if (!discovery_session_ || discovery_session_->IsActive()) - return; - - PA_LOG(ERROR) << "BluetoothDiscoverySession became out of sync. Session is " - << "no longer active, but it was never stopped successfully. " - << "Resetting session."; - - // |discovery_session_| should be deleted whenever the session is no longer - // active. However, due to Bluetooth bugs, this does not always occur - // properly. When we detect that this situation has occurred, delete the - // pointer and reset discovery state. - discovery_session_.reset(); - discovery_session_weak_ptr_factory_.reset(); - is_initializing_discovery_session_ = false; - is_stopping_discovery_session_ = false; - weak_ptr_factory_.InvalidateWeakPtrs(); - - ScheduleStatusChangeNotification(false /* discovery_session_active */); -} - -void BleScannerImpl::UpdateDiscoveryStatus() { - if (ShouldDiscoverySessionBeActive()) - EnsureDiscoverySessionActive(); - else - EnsureDiscoverySessionNotActive(); -} - -void BleScannerImpl::EnsureDiscoverySessionActive() { - // If the session is active or is in the process of becoming active, there is - // nothing to do. - if (IsDiscoverySessionActive() || is_initializing_discovery_session_) - return; - - is_initializing_discovery_session_ = true; - - ble_synchronizer_->StartDiscoverySession( - base::Bind(&BleScannerImpl::OnDiscoverySessionStarted, - weak_ptr_factory_.GetWeakPtr()), - base::Bind(&BleScannerImpl::OnStartDiscoverySessionError, - weak_ptr_factory_.GetWeakPtr())); -} - -void BleScannerImpl::OnDiscoverySessionStarted( - std::unique_ptr<device::BluetoothDiscoverySession> discovery_session) { - is_initializing_discovery_session_ = false; - PA_LOG(VERBOSE) << "Started discovery session successfully."; - - discovery_session_ = std::move(discovery_session); - discovery_session_weak_ptr_factory_ = - std::make_unique<base::WeakPtrFactory<device::BluetoothDiscoverySession>>( - discovery_session_.get()); - - ScheduleStatusChangeNotification(true /* discovery_session_active */); - - UpdateDiscoveryStatus(); -} - -void BleScannerImpl::OnStartDiscoverySessionError() { - PA_LOG(ERROR) << "Error starting discovery session. Initialization failed."; - is_initializing_discovery_session_ = false; - UpdateDiscoveryStatus(); -} - -void BleScannerImpl::EnsureDiscoverySessionNotActive() { - // If there is no session, there is nothing to do. - if (!IsDiscoverySessionActive() || is_stopping_discovery_session_) - return; - - is_stopping_discovery_session_ = true; - - ble_synchronizer_->StopDiscoverySession( - discovery_session_weak_ptr_factory_->GetWeakPtr(), - base::Bind(&BleScannerImpl::OnDiscoverySessionStopped, - weak_ptr_factory_.GetWeakPtr()), - base::Bind(&BleScannerImpl::OnStopDiscoverySessionError, - weak_ptr_factory_.GetWeakPtr())); -} - -void BleScannerImpl::OnDiscoverySessionStopped() { - is_stopping_discovery_session_ = false; - PA_LOG(VERBOSE) << "Stopped discovery session successfully."; - - discovery_session_.reset(); - discovery_session_weak_ptr_factory_.reset(); - - ScheduleStatusChangeNotification(false /* discovery_session_active */); - - UpdateDiscoveryStatus(); -} - -void BleScannerImpl::OnStopDiscoverySessionError() { - PA_LOG(ERROR) << "Error stopping discovery session."; - is_stopping_discovery_session_ = false; - UpdateDiscoveryStatus(); -} - -void BleScannerImpl::HandleDeviceUpdated( - device::BluetoothDevice* bluetooth_device) { - DCHECK(bluetooth_device); - - const std::vector<uint8_t>* service_data = - service_data_provider_->GetServiceDataForUUID(bluetooth_device); - if (!service_data || service_data->size() < kMinNumBytesInServiceData) { - // If there is no service data or the service data is of insufficient - // length, there is not enough information to create a connection. - return; - } - - // Convert the service data from a std::vector<uint8_t> to a std::string. - std::string service_data_str; - char* string_contents_ptr = - base::WriteInto(&service_data_str, service_data->size() + 1); - memcpy(string_contents_ptr, service_data->data(), service_data->size()); - - CheckForMatchingScanFilters(bluetooth_device, service_data_str); -} - -void BleScannerImpl::CheckForMatchingScanFilters( - device::BluetoothDevice* bluetooth_device, - const std::string& service_data) { - secure_channel::DeviceIdPairSet device_id_pair_set; - for (const auto& remote_device_id : registered_remote_device_ids_) - device_id_pair_set.emplace(remote_device_id, kStubLocalDeviceId); - - base::Optional<secure_channel::BleServiceDataHelper::DeviceWithBackgroundBool> - device_with_background_bool = - ble_service_data_helper_->IdentifyRemoteDevice(service_data, - device_id_pair_set); - - // If the service data does not correspond to an advertisement from a device - // on this account, ignore it. - if (!device_with_background_bool) - return; - - NotifyReceivedAdvertisementFromDevice( - device_with_background_bool->first /* remote_device */, bluetooth_device, - device_with_background_bool->second /* is_background_advertisement */); -} - -void BleScannerImpl::ScheduleStatusChangeNotification( - bool discovery_session_active) { - // Schedule the task to run after the current task has completed. This is - // necessary because the completion of a Bluetooth task may cause the Tether - // component to be shut down; if that occurs, then we cannot reference - // instance variables in this class after the object has been deleted. - // Completing the current command as part of the next task ensures that this - // cannot occur. See crbug.com/776241. - task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&BleScannerImpl::NotifyDiscoverySessionStateChanged, - weak_ptr_factory_.GetWeakPtr(), discovery_session_active)); -} - -} // namespace tether - -} // namespace chromeos
diff --git a/chromeos/components/tether/ble_scanner_impl.h b/chromeos/components/tether/ble_scanner_impl.h deleted file mode 100644 index e062d3c..0000000 --- a/chromeos/components/tether/ble_scanner_impl.h +++ /dev/null
@@ -1,154 +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 CHROMEOS_COMPONENTS_TETHER_BLE_SCANNER_IMPL_H_ -#define CHROMEOS_COMPONENTS_TETHER_BLE_SCANNER_IMPL_H_ - -#include <map> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/optional.h" -#include "chromeos/components/tether/ble_scanner.h" -#include "components/cryptauth/remote_device_ref.h" -#include "device/bluetooth/bluetooth_adapter.h" - -namespace base { -class TaskRunner; -} // namespace base - -namespace device { -class BluetoothDevice; -class BluetoothDiscoverySession; -} // namespace device - -namespace chromeos { - -namespace secure_channel { -class BleServiceDataHelper; -class BleSynchronizerBase; -} // namespace secure_channel - -namespace tether { - -class TetherHostFetcher; - -// Concrete BleScanner implementation. -class BleScannerImpl : public BleScanner, - public device::BluetoothAdapter::Observer { - public: - class Factory { - public: - static std::unique_ptr<BleScanner> NewInstance( - scoped_refptr<device::BluetoothAdapter> adapter, - secure_channel::BleServiceDataHelper* ble_service_data_helper, - secure_channel::BleSynchronizerBase* ble_synchronizer, - TetherHostFetcher* tether_host_fetcher); - - static void SetInstanceForTesting(Factory* factory); - - protected: - virtual std::unique_ptr<BleScanner> BuildInstance( - scoped_refptr<device::BluetoothAdapter> adapter, - secure_channel::BleServiceDataHelper* ble_service_data_helper, - secure_channel::BleSynchronizerBase* ble_synchronizer, - TetherHostFetcher* tether_host_fetcher); - - private: - static Factory* factory_instance_; - }; - ~BleScannerImpl() override; - - // BleScanner: - bool RegisterScanFilterForDevice(const std::string& device_id) override; - bool UnregisterScanFilterForDevice(const std::string& device_id) override; - bool ShouldDiscoverySessionBeActive() override; - bool IsDiscoverySessionActive() override; - - protected: - BleScannerImpl(scoped_refptr<device::BluetoothAdapter> adapter, - secure_channel::BleServiceDataHelper* ble_service_data_helper, - secure_channel::BleSynchronizerBase* ble_synchronizer, - TetherHostFetcher* tether_host_fetcher); - - // device::BluetoothAdapter::Observer: - void DeviceAdded(device::BluetoothAdapter* adapter, - device::BluetoothDevice* bluetooth_device) override; - void DeviceChanged(device::BluetoothAdapter* adapter, - device::BluetoothDevice* bluetooth_device) override; - - private: - friend class BleScannerImplTest; - - class ServiceDataProvider { - public: - virtual ~ServiceDataProvider() {} - virtual const std::vector<uint8_t>* GetServiceDataForUUID( - device::BluetoothDevice* bluetooth_device) = 0; - }; - - class ServiceDataProviderImpl : public ServiceDataProvider { - public: - ServiceDataProviderImpl(); - ~ServiceDataProviderImpl() override; - const std::vector<uint8_t>* GetServiceDataForUUID( - device::BluetoothDevice* bluetooth_device) override; - }; - - void SetTestDoubles( - std::unique_ptr<ServiceDataProvider> service_data_provider, - scoped_refptr<base::TaskRunner> test_task_runner); - - bool IsDeviceRegistered(const std::string& device_id); - - // A discovery session should stay active until it has been stopped. However, - // due to bugs in Bluetooth code, it is possible for a discovery status to - // transition to being off without a Stop() call ever succeeding. This - // function corrects the state of Bluetooth if such a bug occurs. - void ResetDiscoverySessionIfNotActive(); - - void UpdateDiscoveryStatus(); - - void EnsureDiscoverySessionActive(); - void OnDiscoverySessionStarted( - std::unique_ptr<device::BluetoothDiscoverySession> discovery_session); - void OnStartDiscoverySessionError(); - - void EnsureDiscoverySessionNotActive(); - void OnDiscoverySessionStopped(); - void OnStopDiscoverySessionError(); - - void HandleDeviceUpdated(device::BluetoothDevice* bluetooth_device); - void CheckForMatchingScanFilters(device::BluetoothDevice* bluetooth_device, - const std::string& service_data); - - void ScheduleStatusChangeNotification(bool discovery_session_active); - - scoped_refptr<device::BluetoothAdapter> adapter_; - secure_channel::BleServiceDataHelper* ble_service_data_helper_; - secure_channel::BleSynchronizerBase* ble_synchronizer_; - TetherHostFetcher* tether_host_fetcher_; - - std::unique_ptr<ServiceDataProvider> service_data_provider_; - - std::vector<std::string> registered_remote_device_ids_; - - bool is_initializing_discovery_session_ = false; - bool is_stopping_discovery_session_ = false; - scoped_refptr<base::TaskRunner> task_runner_; - std::unique_ptr<device::BluetoothDiscoverySession> discovery_session_; - std::unique_ptr<base::WeakPtrFactory<device::BluetoothDiscoverySession>> - discovery_session_weak_ptr_factory_; - - base::WeakPtrFactory<BleScannerImpl> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(BleScannerImpl); -}; - -} // namespace tether - -} // namespace chromeos - -#endif // CHROMEOS_COMPONENTS_TETHER_BLE_SCANNER_IMPL_H_
diff --git a/chromeos/components/tether/ble_scanner_impl_unittest.cc b/chromeos/components/tether/ble_scanner_impl_unittest.cc deleted file mode 100644 index 329fc6a9..0000000 --- a/chromeos/components/tether/ble_scanner_impl_unittest.cc +++ /dev/null
@@ -1,719 +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. - -#include "chromeos/components/tether/ble_scanner_impl.h" - -#include <memory> - -#include "base/callback_forward.h" -#include "base/memory/ptr_util.h" -#include "base/test/scoped_task_environment.h" -#include "base/test/test_simple_task_runner.h" -#include "chromeos/components/tether/fake_tether_host_fetcher.h" -#include "chromeos/services/secure_channel/ble_constants.h" -#include "chromeos/services/secure_channel/fake_ble_service_data_helper.h" -#include "chromeos/services/secure_channel/fake_ble_synchronizer.h" -#include "components/cryptauth/proto/cryptauth_api.pb.h" -#include "components/cryptauth/remote_device_test_util.h" -#include "device/bluetooth/test/mock_bluetooth_adapter.h" -#include "device/bluetooth/test/mock_bluetooth_device.h" -#include "device/bluetooth/test/mock_bluetooth_discovery_session.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::_; -using testing::Eq; -using testing::Invoke; -using testing::NiceMock; -using testing::Return; - -namespace chromeos { - -namespace tether { - -namespace { - -class TestBleScannerObserver final : public BleScanner::Observer { - public: - TestBleScannerObserver() = default; - - const std::vector<std::string>& device_addresses() { - return device_addresses_; - } - - const cryptauth::RemoteDeviceRefList& devices() { return devices_; } - - std::vector<bool>& discovery_session_state_changes() { - return discovery_session_state_changes_; - } - - // BleScanner::Observer: - void OnReceivedAdvertisementFromDevice( - cryptauth::RemoteDeviceRef remote_device, - device::BluetoothDevice* bluetooth_device, - bool is_background_advertisement) override { - device_addresses_.push_back(bluetooth_device->GetAddress()); - devices_.push_back(remote_device); - } - - void OnDiscoverySessionStateChanged(bool discovery_session_active) override { - discovery_session_state_changes_.push_back(discovery_session_active); - } - - private: - std::vector<std::string> device_addresses_; - cryptauth::RemoteDeviceRefList devices_; - std::vector<bool> discovery_session_state_changes_; -}; - -// Deletes the BleScanner when notified. -class DeletingObserver final : public BleScanner::Observer { - public: - DeletingObserver(std::unique_ptr<BleScannerImpl>& ble_scanner) - : ble_scanner_(ble_scanner) { - ble_scanner_->AddObserver(this); - } - - // BleScanner::Observer: - void OnDiscoverySessionStateChanged(bool discovery_session_active) override { - // Only delete if the discovery session is no longer active. - if (discovery_session_active) - return; - - ble_scanner_->RemoveObserver(this); - ble_scanner_.reset(); - } - - void OnReceivedAdvertisementFromDevice( - cryptauth::RemoteDeviceRef remote_device, - device::BluetoothDevice* bluetooth_device, - bool is_background_advertisement) override {} - - private: - std::unique_ptr<BleScannerImpl>& ble_scanner_; -}; - -class MockBluetoothDeviceWithServiceData : public device::MockBluetoothDevice { - public: - MockBluetoothDeviceWithServiceData(device::MockBluetoothAdapter* adapter, - const std::string& device_address, - const std::string& service_data) - : device::MockBluetoothDevice(adapter, - /* bluetooth_class */ 0, - "name", - device_address, - false, - false) { - for (size_t i = 0; i < service_data.size(); i++) { - service_data_.push_back(static_cast<uint8_t>(service_data[i])); - } - } - - const std::vector<uint8_t>* service_data() { return &service_data_; } - - private: - std::vector<uint8_t> service_data_; -}; - -const size_t kNumBytesInBackgroundAdvertisementServiceData = 2; -const size_t kMinNumBytesInForegroundAdvertisementServiceData = 4; - -const char kDefaultBluetoothAddress[] = "11:22:33:44:55:66"; - -} // namespace - -class BleScannerImplTest : public testing::Test { - protected: - class TestServiceDataProvider : public BleScannerImpl::ServiceDataProvider { - public: - TestServiceDataProvider() = default; - - ~TestServiceDataProvider() override = default; - - // ServiceDataProvider: - const std::vector<uint8_t>* GetServiceDataForUUID( - device::BluetoothDevice* bluetooth_device) override { - return reinterpret_cast<MockBluetoothDeviceWithServiceData*>( - bluetooth_device) - ->service_data(); - } - }; - - BleScannerImplTest() - : test_devices_(cryptauth::CreateRemoteDeviceRefListForTest(3)) {} - - void SetUp() override { - // Note: This value is only used after the discovery session has been - // created (i.e., after a StartDiscoverySession() call completes - // successfully). - should_discovery_session_be_active_ = true; - - fake_ble_service_data_helper_ = - std::make_unique<secure_channel::FakeBleServiceDataHelper>(); - fake_ble_synchronizer_ = - std::make_unique<secure_channel::FakeBleSynchronizer>(); - fake_tether_host_fetcher_ = - std::make_unique<FakeTetherHostFetcher>(test_devices_); - - mock_adapter_ = - base::MakeRefCounted<NiceMock<device::MockBluetoothAdapter>>(); - ON_CALL(*mock_adapter_, IsPowered()).WillByDefault(Return(true)); - - mock_discovery_session_ = nullptr; - - ble_scanner_ = base::WrapUnique(new BleScannerImpl( - mock_adapter_, fake_ble_service_data_helper_.get(), - fake_ble_synchronizer_.get(), fake_tether_host_fetcher_.get())); - - test_service_data_provider_ = new TestServiceDataProvider(); - test_task_runner_ = base::MakeRefCounted<base::TestSimpleTaskRunner>(); - - ble_scanner_->SetTestDoubles(base::WrapUnique(test_service_data_provider_), - test_task_runner_); - - test_observer_ = std::make_unique<TestBleScannerObserver>(); - ble_scanner_->AddObserver(test_observer_.get()); - } - - void TearDown() override { - EXPECT_EQ(discovery_state_changes_so_far_, - test_observer_->discovery_session_state_changes()); - } - - void DeviceAdded(MockBluetoothDeviceWithServiceData* device) { - ble_scanner_->DeviceAdded(mock_adapter_.get(), device); - } - - void InvokeDiscoveryStartedCallback(bool success, size_t command_index) { - if (success) { - mock_discovery_session_ = new device::MockBluetoothDiscoverySession(); - ON_CALL(*mock_discovery_session_, IsActive()) - .WillByDefault( - Invoke(this, &BleScannerImplTest::MockDiscoveryIsActive)); - - fake_ble_synchronizer_->GetStartDiscoveryCallback(command_index) - .Run(base::WrapUnique(mock_discovery_session_)); - test_task_runner_->RunUntilIdle(); - VerifyDiscoveryStatusChange(true /* discovery_session_active */); - return; - } - - fake_ble_synchronizer_->GetStartDiscoveryErrorCallback(command_index).Run(); - } - - bool IsDeviceRegistered(const std::string& device_id) { - return ble_scanner_->IsDeviceRegistered(device_id); - } - - void VerifyDiscoveryStatusChange(bool discovery_session_active) { - discovery_state_changes_so_far_.push_back(discovery_session_active); - EXPECT_EQ(discovery_state_changes_so_far_, - test_observer_->discovery_session_state_changes()); - } - - bool MockDiscoveryIsActive() { return should_discovery_session_be_active_; } - - void InvokeStopDiscoveryCallback(bool success, size_t command_index) { - if (success) { - fake_ble_synchronizer_->GetStopDiscoveryCallback(command_index).Run(); - test_task_runner_->RunUntilIdle(); - VerifyDiscoveryStatusChange(false /* discovery_session_active */); - return; - } - - fake_ble_synchronizer_->GetStopDiscoveryErrorCallback(command_index).Run(); - } - - const base::test::ScopedTaskEnvironment scoped_task_environment_; - const cryptauth::RemoteDeviceRefList test_devices_; - - std::unique_ptr<secure_channel::FakeBleServiceDataHelper> - fake_ble_service_data_helper_; - std::unique_ptr<secure_channel::FakeBleSynchronizer> fake_ble_synchronizer_; - std::unique_ptr<FakeTetherHostFetcher> fake_tether_host_fetcher_; - - scoped_refptr<NiceMock<device::MockBluetoothAdapter>> mock_adapter_; - device::MockBluetoothDiscoverySession* mock_discovery_session_; - - TestServiceDataProvider* test_service_data_provider_; - scoped_refptr<base::TestSimpleTaskRunner> test_task_runner_; - - std::unique_ptr<TestBleScannerObserver> test_observer_; - - bool should_discovery_session_be_active_; - - std::vector<bool> discovery_state_changes_so_far_; - - std::unique_ptr<BleScannerImpl> ble_scanner_; - - private: - DISALLOW_COPY_AND_ASSIGN(BleScannerImplTest); -}; - -TEST_F(BleScannerImplTest, TestDiscoverySessionFailsToStart) { - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - - InvokeDiscoveryStartedCallback(false /* success */, 0u /* command_index */); - - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_EQ(0u, test_observer_->device_addresses().size()); -} - -TEST_F(BleScannerImplTest, TestDiscoveryStartsButNoDevicesFound) { - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - - InvokeDiscoveryStartedCallback(true /* success */, 0u /* command_index */); - - // No devices found. - - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_EQ(0u, test_observer_->device_addresses().size()); - - InvokeStopDiscoveryCallback(true /* success */, 1u /* command_index */); -} - -TEST_F(BleScannerImplTest, TestDiscovery_NoServiceData) { - std::string empty_service_data = ""; - - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - - InvokeDiscoveryStartedCallback(true /* success */, 0u /* command_index */); - - // Device with no service data connected. Service data is required to identify - // the advertising device. - MockBluetoothDeviceWithServiceData device( - mock_adapter_.get(), kDefaultBluetoothAddress, empty_service_data); - DeviceAdded(&device); - EXPECT_EQ(0u, test_observer_->device_addresses().size()); -} - -TEST_F(BleScannerImplTest, TestDiscovery_ServiceDataTooShort) { - std::string short_service_data = "abc"; - ASSERT_TRUE(short_service_data.size() < - kMinNumBytesInForegroundAdvertisementServiceData); - - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - - InvokeDiscoveryStartedCallback(true /* success */, 0u /* command_index */); - - // Device with short service data connected. Service data of at least 4 bytes - // is required to identify the advertising device. - MockBluetoothDeviceWithServiceData device( - mock_adapter_.get(), kDefaultBluetoothAddress, short_service_data); - DeviceAdded(&device); - EXPECT_EQ(0u, test_observer_->device_addresses().size()); -} - -TEST_F(BleScannerImplTest, TestDiscovery_LocalDeviceDataCannotBeFetched) { - std::string valid_service_data_for_other_device = "abcd"; - ASSERT_TRUE(valid_service_data_for_other_device.size() >= - kMinNumBytesInForegroundAdvertisementServiceData); - - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - - InvokeDiscoveryStartedCallback(true /* success */, 0u /* command_index */); - - // Device with valid service data connected, but the local device data - // cannot be fetched. - MockBluetoothDeviceWithServiceData device( - mock_adapter_.get(), kDefaultBluetoothAddress, - valid_service_data_for_other_device); - DeviceAdded(&device); - EXPECT_EQ(0u, test_observer_->device_addresses().size()); -} - -TEST_F(BleScannerImplTest, TestDiscovery_ScanSuccessfulButNoRegisteredDevice) { - std::string valid_service_data_for_other_device = "abcd"; - ASSERT_TRUE(valid_service_data_for_other_device.size() >= - kMinNumBytesInForegroundAdvertisementServiceData); - - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - - InvokeDiscoveryStartedCallback(true /* success */, 0u /* command_index */); - - // Device with valid service data connected, but there was no registered - // device corresponding to the one that just connected. - MockBluetoothDeviceWithServiceData device( - mock_adapter_.get(), kDefaultBluetoothAddress, - valid_service_data_for_other_device); - DeviceAdded(&device); - EXPECT_EQ(0u, test_observer_->device_addresses().size()); -} - -TEST_F(BleScannerImplTest, TestDiscovery_Success) { - std::string valid_service_data_for_registered_device = "abcde"; - ASSERT_TRUE(valid_service_data_for_registered_device.size() >= - kMinNumBytesInForegroundAdvertisementServiceData); - - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - - InvokeDiscoveryStartedCallback(true /* success */, 0u /* command_index */); - - // Registered device connects. - MockBluetoothDeviceWithServiceData device( - mock_adapter_.get(), kDefaultBluetoothAddress, - valid_service_data_for_registered_device); - - fake_ble_service_data_helper_->SetIdentifiedDevice( - valid_service_data_for_registered_device, test_devices_[0], - false /* is_background_advertisement */); - - DeviceAdded(&device); - EXPECT_EQ(1u, test_observer_->device_addresses().size()); - EXPECT_EQ(device.GetAddress(), test_observer_->device_addresses()[0]); - EXPECT_EQ(1u, test_observer_->devices().size()); - EXPECT_EQ(test_devices_[0], test_observer_->devices()[0]); - - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_EQ(1u, test_observer_->device_addresses().size()); - InvokeStopDiscoveryCallback(true /* success */, 1u /* command_index */); -} - -TEST_F(BleScannerImplTest, TestDiscovery_MultipleObservers) { - TestBleScannerObserver extra_observer; - ble_scanner_->AddObserver(&extra_observer); - - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - - InvokeDiscoveryStartedCallback(true /* success */, 0u /* command_index */); - - MockBluetoothDeviceWithServiceData mock_bluetooth_device( - mock_adapter_.get(), kDefaultBluetoothAddress, "fakeServiceData"); - fake_ble_service_data_helper_->SetIdentifiedDevice( - "fakeServiceData", test_devices_[0], - false /* is_background_advertisement */); - DeviceAdded(&mock_bluetooth_device); - - EXPECT_EQ(1u, test_observer_->device_addresses().size()); - EXPECT_EQ(mock_bluetooth_device.GetAddress(), - test_observer_->device_addresses()[0]); - EXPECT_EQ(1u, test_observer_->devices().size()); - EXPECT_EQ(test_devices_[0], test_observer_->devices()[0]); - - EXPECT_EQ(1u, extra_observer.device_addresses().size()); - EXPECT_EQ(mock_bluetooth_device.GetAddress(), - extra_observer.device_addresses()[0]); - EXPECT_EQ(1u, extra_observer.devices().size()); - EXPECT_EQ(test_devices_[0], extra_observer.devices()[0]); - - // Now, unregister both observers. - ble_scanner_->RemoveObserver(test_observer_.get()); - ble_scanner_->RemoveObserver(&extra_observer); - - // Now, simulate another scan being received. The observers should not be - // notified since they are unregistered, so they should still have a call - // count of 1. - DeviceAdded(&mock_bluetooth_device); - EXPECT_EQ(1u, test_observer_->device_addresses().size()); - EXPECT_EQ(1u, extra_observer.device_addresses().size()); - - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - - // Note: Cannot use InvokeStopDiscoveryCallback() since that function - // internally verifies observer callbacks, but the observers have been - // unregistered in this case. - fake_ble_synchronizer_->GetStopDiscoveryCallback(1u /* command_index */) - .Run(); -} - -TEST_F(BleScannerImplTest, TestRegistrationLimit) { - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[1].GetDeviceId())); - EXPECT_TRUE(IsDeviceRegistered(test_devices_[1].GetDeviceId())); - - // Attempt to register another device. Registration should fail since the - // maximum number of devices have already been registered. - ASSERT_EQ(2u, secure_channel::kMaxConcurrentAdvertisements); - EXPECT_FALSE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[2].GetDeviceId())); - EXPECT_FALSE(IsDeviceRegistered(test_devices_[2].GetDeviceId())); - - // Unregistering a device which is not registered should also return false. - EXPECT_FALSE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[2].GetDeviceId())); - EXPECT_FALSE(IsDeviceRegistered(test_devices_[2].GetDeviceId())); - - // Unregister device 0. - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_FALSE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - - // Now, device 2 can be registered. - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[2].GetDeviceId())); - EXPECT_TRUE(IsDeviceRegistered(test_devices_[2].GetDeviceId())); - - // Now, unregister the devices. - EXPECT_TRUE(IsDeviceRegistered(test_devices_[1].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[1].GetDeviceId())); - EXPECT_FALSE(IsDeviceRegistered(test_devices_[1].GetDeviceId())); - - EXPECT_TRUE(IsDeviceRegistered(test_devices_[2].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[2].GetDeviceId())); - EXPECT_FALSE(IsDeviceRegistered(test_devices_[2].GetDeviceId())); -} - -TEST_F(BleScannerImplTest, TestStartAndStopCallbacks_Success) { - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive()); - - EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive()); - InvokeDiscoveryStartedCallback(true /* success */, 0u /* command_index */); - EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive()); - - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[1].GetDeviceId())); - - // Registering device 1 should not have triggered a new discovery session from - // being created since one already existed. - EXPECT_EQ(1u, fake_ble_synchronizer_->GetNumCommands()); - EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive()); - EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive()); - - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - - // Unregistering device 0 should not have triggered a stopped session since - // a device is still registered. - EXPECT_EQ(1u, fake_ble_synchronizer_->GetNumCommands()); - EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive()); - EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive()); - - // Device 1 is the only device remaining, so unregistering it should trigger - // the session to stop. - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[1].GetDeviceId())); - EXPECT_FALSE(ble_scanner_->ShouldDiscoverySessionBeActive()); - EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive()); - - InvokeStopDiscoveryCallback(true /* success */, 1u /* command_index */); - EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive()); -} - -TEST_F(BleScannerImplTest, TestStartAndStopCallbacks_Errors) { - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive()); - EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive()); - - // Fail to start discovery session. - InvokeDiscoveryStartedCallback(false /* success */, 0u /* command_index */); - EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive()); - - // Since the previous try failed, a new one should have been attempted. Let - // that one fail as well. - InvokeDiscoveryStartedCallback(false /* success */, 1u /* command_index */); - EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive()); - - // Now, let it succeed. - InvokeDiscoveryStartedCallback(true /* success */, 2u /* command_index */); - EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive()); - - // Now, unregister it, but fail to stop the discovery session. - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_FALSE(ble_scanner_->ShouldDiscoverySessionBeActive()); - InvokeStopDiscoveryCallback(false /* success */, 3u /* command_index */); - EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive()); - - // Since the previous try failed, a new stop should have been attempted. Let - // that one fail as well. - InvokeStopDiscoveryCallback(false /* success */, 4u /* command_index */); - EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive()); - - // Now, let it succeed. - InvokeStopDiscoveryCallback(true /* success */, 5u /* command_index */); - EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive()); -} - -TEST_F(BleScannerImplTest, TestStartAndStopCallbacks_UnregisterBeforeStarted) { - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive()); - EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive()); - - // Before invoking the discovery callback, unregister the device. - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_FALSE(ble_scanner_->ShouldDiscoverySessionBeActive()); - - // Complete the start discovery successfully. - InvokeDiscoveryStartedCallback(true /* success */, 0u /* command_index */); - EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive()); - - // Because the session should not be active (i.e., there are no registered - // devices), a stop should be triggered. - InvokeStopDiscoveryCallback(true /* success */, 1u /* command_index */); - EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive()); -} - -TEST_F(BleScannerImplTest, - TestStartAndStopCallbacks_UnregisterBeforeStartFails) { - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive()); - EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive()); - - // Before invoking the discovery callback, unregister the device. - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_FALSE(ble_scanner_->ShouldDiscoverySessionBeActive()); - - // Fail to start discovery session. - InvokeDiscoveryStartedCallback(false /* success */, 0u /* command_index */); - EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive()); - - // Because the session should not be active (i.e., there are no registered - // devices), a new attempt should not have occurred. - EXPECT_EQ(1u, fake_ble_synchronizer_->GetNumCommands()); -} - -TEST_F(BleScannerImplTest, TestStartAndStopCallbacks_RegisterBeforeStopFails) { - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive()); - EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive()); - - // Start discovery session. - InvokeDiscoveryStartedCallback(true /* success */, 0u /* command_index */); - EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive()); - - // Unregister device to attempt a stop. - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_FALSE(ble_scanner_->ShouldDiscoverySessionBeActive()); - EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive()); - - // Before the stop completes, register the device again. - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive()); - EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive()); - - // Fail to stop. - InvokeStopDiscoveryCallback(false /* success */, 1u /* command_index */); - EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive()); - - // Since there is a device registered again, there should not be another - // attempt to stop. - EXPECT_EQ(2u, fake_ble_synchronizer_->GetNumCommands()); -} - -// Regression test for crbug.com/768521. -TEST_F(BleScannerImplTest, - TestStopCallback_DiscoverySessionInactiveButNotStopped) { - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->ShouldDiscoverySessionBeActive()); - EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive()); - - // Start discovery session. - InvokeDiscoveryStartedCallback(true /* success */, 0u /* command_index */); - test_task_runner_->RunUntilIdle(); - EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive()); - - // Unregister device to attempt a stop. - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_FALSE(ble_scanner_->ShouldDiscoverySessionBeActive()); - EXPECT_TRUE(ble_scanner_->IsDiscoverySessionActive()); - - // For this test, simulate the discovery session transitioning to - // IsActive() == false without Stop() ever succeeding. - should_discovery_session_be_active_ = false; - - // Fail to stop. Even though stopping failed, IsActive() will still return - // false. In this case, the discovery session should no longer be active. - InvokeStopDiscoveryCallback(false /* success */, 1u /* command_index */); - EXPECT_FALSE(ble_scanner_->IsDiscoverySessionActive()); - test_task_runner_->RunUntilIdle(); - VerifyDiscoveryStatusChange(false /* discovery_session_active */); - - // Since the discovery session was not active, there should not have been an - // additional call to Stop(). - EXPECT_EQ(2u, fake_ble_synchronizer_->GetNumCommands()); -} - -// Regression test for crbug.com/776241. This bug could cause a crash if, when -// BleScannerImpl notifies observers that all the discovery session has stopped, -// an observer deletes BleScannerImpl. The fix for this issue is simply -// notifying observers in a new task so that no further action will be taken if -// the object is deleted. Without the fix for crbug.com/776241, this test would -// crash. -TEST_F(BleScannerImplTest, ObserverDeletesObjectWhenNotified) { - DeletingObserver deleting_observer(ble_scanner_); - - ble_scanner_->RegisterScanFilterForDevice(test_devices_[0].GetDeviceId()); - InvokeDiscoveryStartedCallback(true /* success */, 0u /* command_index */); - test_task_runner_->RunUntilIdle(); - ble_scanner_->UnregisterScanFilterForDevice(test_devices_[0].GetDeviceId()); - InvokeStopDiscoveryCallback(true /* success */, 1u /* command_index */); - test_task_runner_->RunUntilIdle(); -} - -TEST_F(BleScannerImplTest, TestDiscovery_HostIsBackgroundAdvertising) { - std::string valid_service_data_for_registered_device = "ab"; - ASSERT_TRUE(valid_service_data_for_registered_device.size() == - kNumBytesInBackgroundAdvertisementServiceData); - - EXPECT_TRUE(ble_scanner_->RegisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - - InvokeDiscoveryStartedCallback(true /* success */, 0u /* command_index */); - - // Registered device connects. - MockBluetoothDeviceWithServiceData device( - mock_adapter_.get(), kDefaultBluetoothAddress, - valid_service_data_for_registered_device); - fake_ble_service_data_helper_->SetIdentifiedDevice( - valid_service_data_for_registered_device, test_devices_[0], - true /* is_background_advertisement */); - - DeviceAdded(&device); - EXPECT_EQ(1u, test_observer_->device_addresses().size()); - EXPECT_EQ(device.GetAddress(), test_observer_->device_addresses()[0]); - EXPECT_EQ(1u, test_observer_->devices().size()); - EXPECT_EQ(test_devices_[0], test_observer_->devices()[0]); - - EXPECT_TRUE(IsDeviceRegistered(test_devices_[0].GetDeviceId())); - EXPECT_TRUE(ble_scanner_->UnregisterScanFilterForDevice( - test_devices_[0].GetDeviceId())); - EXPECT_EQ(1u, test_observer_->device_addresses().size()); - InvokeStopDiscoveryCallback(true /* success */, 1u /* command_index */); -} - -} // namespace tether - -} // namespace chromeos
diff --git a/chromeos/components/tether/ble_service_data_helper_impl.cc b/chromeos/components/tether/ble_service_data_helper_impl.cc deleted file mode 100644 index c52d651..0000000 --- a/chromeos/components/tether/ble_service_data_helper_impl.cc +++ /dev/null
@@ -1,248 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chromeos/components/tether/ble_service_data_helper_impl.h" - -#include <algorithm> -#include <iterator> - -#include "base/memory/ptr_util.h" -#include "base/no_destructor.h" -#include "chromeos/chromeos_features.h" -#include "chromeos/chromeos_switches.h" -#include "chromeos/components/proximity_auth/logging/logging.h" -#include "chromeos/services/device_sync/public/cpp/device_sync_client.h" -#include "chromeos/services/secure_channel/ble_constants.h" -#include "components/cryptauth/background_eid_generator.h" -#include "components/cryptauth/ble/ble_advertisement_generator.h" -#include "components/cryptauth/foreground_eid_generator.h" -#include "components/cryptauth/local_device_data_provider.h" - -namespace chromeos { - -namespace tether { - -namespace { - -// Valid advertisement service data must be at least 2 bytes. -// As of March 2018, valid background advertisement service data is exactly 2 -// bytes, which identify the advertising device to the scanning device. -// Valid foreground advertisement service data must include at least 4 bytes: -// 2 bytes associated with the scanning device (used as a scan filter) and 2 -// bytes which identify the advertising device to the scanning device. -const size_t kMinNumBytesInServiceData = 2; -const size_t kMaxNumBytesInBackgroundServiceData = 3; -const size_t kMinNumBytesInForegroundServiceData = 4; - -} // namespace - -// static -BleServiceDataHelperImpl::Factory* - BleServiceDataHelperImpl::Factory::test_factory_ = nullptr; - -// static -BleServiceDataHelperImpl::Factory* BleServiceDataHelperImpl::Factory::Get() { - if (test_factory_) - return test_factory_; - - static base::NoDestructor<Factory> factory; - return factory.get(); -} - -// static -void BleServiceDataHelperImpl::Factory::SetFactoryForTesting( - Factory* test_factory) { - test_factory_ = test_factory; -} - -BleServiceDataHelperImpl::Factory::~Factory() = default; - -std::unique_ptr<secure_channel::BleServiceDataHelper> -BleServiceDataHelperImpl::Factory::BuildInstance( - TetherHostFetcher* tether_host_fetcher, - cryptauth::LocalDeviceDataProvider* local_device_data_provider, - device_sync::DeviceSyncClient* device_sync_client) { - return base::WrapUnique(new BleServiceDataHelperImpl( - tether_host_fetcher, local_device_data_provider, device_sync_client)); -} - -BleServiceDataHelperImpl::BleServiceDataHelperImpl( - TetherHostFetcher* tether_host_fetcher, - cryptauth::LocalDeviceDataProvider* local_device_data_provider, - device_sync::DeviceSyncClient* device_sync_client) - : tether_host_fetcher_(tether_host_fetcher), - local_device_data_provider_(local_device_data_provider), - device_sync_client_(device_sync_client), - background_eid_generator_( - std::make_unique<cryptauth::BackgroundEidGenerator>()), - foreground_eid_generator_( - std::make_unique<cryptauth::ForegroundEidGenerator>()), - weak_ptr_factory_(this) { - tether_host_fetcher_->AddObserver(this); - OnTetherHostsUpdated(); -} - -BleServiceDataHelperImpl::~BleServiceDataHelperImpl() { - tether_host_fetcher_->RemoveObserver(this); -} - -base::Optional<secure_channel::BleServiceDataHelper::DeviceWithBackgroundBool> -BleServiceDataHelperImpl::IdentifyRemoteDevice( - const std::string& service_data, - const std::vector<std::string>& remote_device_ids) { - base::Optional<std::string> local_device_public_key = - GetLocalDevicePublicKey(); - if (!local_device_public_key) - return base::nullopt; - - // BleServiceDataHelper::IdentifyRemoteDevice() verifies that the devices its - // subclasses return are actually in |device_id_pair_set|. However, clients of - // BleServiceDataHelperImpl don't have easy access to local device metadata; - // therefore, pass along that required data here. - secure_channel::DeviceIdPairSet device_id_pair_set; - for (const auto& remote_device_id : remote_device_ids) { - device_id_pair_set.insert(secure_channel::DeviceIdPair( - remote_device_id, cryptauth::RemoteDeviceRef::GenerateDeviceId( - *local_device_public_key))); - } - - return secure_channel::BleServiceDataHelper::IdentifyRemoteDevice( - service_data, device_id_pair_set); -} - -std::unique_ptr<cryptauth::DataWithTimestamp> -BleServiceDataHelperImpl::GenerateForegroundAdvertisement( - const secure_channel::DeviceIdPair& device_id_pair) { - base::Optional<std::string> local_device_public_key = - GetLocalDevicePublicKey(); - if (!local_device_public_key) { - PA_LOG(ERROR) << "Local device public key is invalid."; - return nullptr; - } - - base::Optional<cryptauth::RemoteDeviceRef> remote_device; - const auto remote_device_it = std::find_if( - tether_hosts_from_last_fetch_.begin(), - tether_hosts_from_last_fetch_.end(), - [&device_id_pair](auto remote_device) { - return device_id_pair.remote_device_id() == remote_device.GetDeviceId(); - }); - - if (remote_device_it == tether_hosts_from_last_fetch_.end()) { - PA_LOG(WARNING) << "Requested remote device ID is not a valid host: " - << cryptauth::RemoteDeviceRef::TruncateDeviceIdForLogs( - device_id_pair.remote_device_id()); - return nullptr; - } - - return cryptauth::BleAdvertisementGenerator::GenerateBleAdvertisement( - *remote_device_it, *local_device_public_key); -} - -base::Optional<secure_channel::BleServiceDataHelper::DeviceWithBackgroundBool> -BleServiceDataHelperImpl::PerformIdentifyRemoteDevice( - const std::string& service_data, - const secure_channel::DeviceIdPairSet& device_id_pair_set) { - std::vector<std::string> remote_device_ids; - for (const auto& device_id_pair : device_id_pair_set) { - // It's fine to ignore device_id_pair.local_device_id(); it's the same for - // each entry. - remote_device_ids.push_back(device_id_pair.remote_device_id()); - } - - std::string device_id; - bool is_background_advertisement = false; - - // First try, identifying |service_data| as a foreground advertisement. - if (service_data.size() >= kMinNumBytesInForegroundServiceData) { - std::vector<cryptauth::BeaconSeed> beacon_seeds; - if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) { - beacon_seeds = - device_sync_client_->GetLocalDeviceMetadata()->beacon_seeds(); - } else if (!local_device_data_provider_->GetLocalDeviceData( - nullptr, &beacon_seeds)) { - PA_LOG(ERROR) << "Cannot fetch local beacon seeds."; - return base::nullopt; - } - - device_id = foreground_eid_generator_->IdentifyRemoteDeviceByAdvertisement( - service_data, remote_device_ids, beacon_seeds); - } - - // If the device has not yet been identified, try identifying |service_data| - // as a background advertisement. - if (chromeos::switches::IsInstantTetheringBackgroundAdvertisingSupported() && - device_id.empty() && service_data.size() >= kMinNumBytesInServiceData && - service_data.size() <= kMaxNumBytesInBackgroundServiceData) { - cryptauth::RemoteDeviceRefList remote_devices; - for (auto remote_device : tether_hosts_from_last_fetch_) { - if (base::ContainsValue(remote_device_ids, remote_device.GetDeviceId())) - remote_devices.push_back(remote_device); - } - - device_id = background_eid_generator_->IdentifyRemoteDeviceByAdvertisement( - service_data, remote_devices); - is_background_advertisement = true; - } - - // If the service data does not correspond to an advertisement from a device - // on this account, ignore it. - if (device_id.empty()) - return base::nullopt; - - for (const auto& remote_device_ref : tether_hosts_from_last_fetch_) { - if (remote_device_ref.GetDeviceId() == device_id) { - return secure_channel::BleServiceDataHelper::DeviceWithBackgroundBool( - remote_device_ref, is_background_advertisement); - } - } - - PA_LOG(ERROR) << "Identified remote device ID is not a valid host: " - << cryptauth::RemoteDeviceRef::TruncateDeviceIdForLogs( - device_id); - NOTREACHED(); - return base::nullopt; -} - -void BleServiceDataHelperImpl::OnTetherHostsUpdated() { - tether_host_fetcher_->FetchAllTetherHosts( - base::Bind(&BleServiceDataHelperImpl::OnTetherHostsFetched, - weak_ptr_factory_.GetWeakPtr())); -} - -void BleServiceDataHelperImpl::OnTetherHostsFetched( - const cryptauth::RemoteDeviceRefList& tether_hosts) { - tether_hosts_from_last_fetch_ = tether_hosts; -} - -base::Optional<std::string> -BleServiceDataHelperImpl::GetLocalDevicePublicKey() { - std::string local_device_public_key; - if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) { - if (!device_sync_client_->GetLocalDeviceMetadata()) - return base::nullopt; - local_device_public_key = - device_sync_client_->GetLocalDeviceMetadata()->public_key(); - } else if (!local_device_data_provider_->GetLocalDeviceData( - &local_device_public_key, nullptr)) { - return base::nullopt; - } - - if (local_device_public_key.empty()) - return base::nullopt; - - return local_device_public_key; -} - -void BleServiceDataHelperImpl::SetTestDoubles( - std::unique_ptr<cryptauth::BackgroundEidGenerator> background_eid_generator, - std::unique_ptr<cryptauth::ForegroundEidGenerator> - foreground_eid_generator) { - background_eid_generator_ = std::move(background_eid_generator); - foreground_eid_generator_ = std::move(foreground_eid_generator); -} - -} // namespace tether - -} // namespace chromeos
diff --git a/chromeos/components/tether/ble_service_data_helper_impl.h b/chromeos/components/tether/ble_service_data_helper_impl.h deleted file mode 100644 index 246a130..0000000 --- a/chromeos/components/tether/ble_service_data_helper_impl.h +++ /dev/null
@@ -1,104 +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 CHROMEOS_COMPONENTS_TETHER_BLE_SERVICE_DATA_HELPER_IMPL_H_ -#define CHROMEOS_COMPONENTS_TETHER_BLE_SERVICE_DATA_HELPER_IMPL_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/optional.h" -#include "chromeos/components/tether/tether_host_fetcher.h" -#include "chromeos/services/secure_channel/ble_service_data_helper.h" -#include "chromeos/services/secure_channel/device_id_pair.h" -#include "components/cryptauth/data_with_timestamp.h" -#include "components/cryptauth/remote_device_ref.h" - -namespace cryptauth { -class BackgroundEidGenerator; -class ForegroundEidGenerator; -class LocalDeviceDataProvider; -} // namespace cryptauth - -namespace chromeos { - -namespace device_sync { -class DeviceSyncClient; -} // namespace device_sync - -namespace tether { - -// chromeos::tether BleServiceDataHelper implementation. -class BleServiceDataHelperImpl : public secure_channel::BleServiceDataHelper, - public TetherHostFetcher::Observer { - public: - class Factory { - public: - static Factory* Get(); - static void SetFactoryForTesting(Factory* test_factory); - virtual ~Factory(); - virtual std::unique_ptr<secure_channel::BleServiceDataHelper> BuildInstance( - TetherHostFetcher* tether_host_fetcher, - cryptauth::LocalDeviceDataProvider* local_device_data_provider, - device_sync::DeviceSyncClient* device_sync_client); - - private: - static Factory* test_factory_; - }; - - ~BleServiceDataHelperImpl() override; - - base::Optional<DeviceWithBackgroundBool> IdentifyRemoteDevice( - const std::string& service_data, - const std::vector<std::string>& remote_device_ids); - - private: - friend class BleServiceDataHelperImplTest; - - BleServiceDataHelperImpl( - TetherHostFetcher* tether_host_fetcher, - cryptauth::LocalDeviceDataProvider* local_device_data_provider, - device_sync::DeviceSyncClient* device_sync_client); - - // secure_channel::BleServiceDataHelper: - std::unique_ptr<cryptauth::DataWithTimestamp> GenerateForegroundAdvertisement( - const secure_channel::DeviceIdPair& device_id_pair) override; - base::Optional<DeviceWithBackgroundBool> PerformIdentifyRemoteDevice( - const std::string& service_data, - const secure_channel::DeviceIdPairSet& device_id_pair_set) override; - - // TetherHostFetcher::Observer: - void OnTetherHostsUpdated() override; - - void OnTetherHostsFetched(const cryptauth::RemoteDeviceRefList& tether_hosts); - - base::Optional<std::string> GetLocalDevicePublicKey(); - - void SetTestDoubles(std::unique_ptr<cryptauth::BackgroundEidGenerator> - background_eid_generator, - std::unique_ptr<cryptauth::ForegroundEidGenerator> - foreground_eid_generator); - - TetherHostFetcher* tether_host_fetcher_; - cryptauth::LocalDeviceDataProvider* local_device_data_provider_; - device_sync::DeviceSyncClient* device_sync_client_; - - std::unique_ptr<cryptauth::BackgroundEidGenerator> background_eid_generator_; - std::unique_ptr<cryptauth::ForegroundEidGenerator> foreground_eid_generator_; - - cryptauth::RemoteDeviceRefList tether_hosts_from_last_fetch_; - - base::WeakPtrFactory<BleServiceDataHelperImpl> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(BleServiceDataHelperImpl); -}; - -} // namespace tether - -} // namespace chromeos - -#endif // CHROMEOS_COMPONENTS_TETHER_BLE_SERVICE_DATA_HELPER_IMPL_H_
diff --git a/chromeos/components/tether/ble_service_data_helper_impl_unittest.cc b/chromeos/components/tether/ble_service_data_helper_impl_unittest.cc deleted file mode 100644 index 9e90cd6b..0000000 --- a/chromeos/components/tether/ble_service_data_helper_impl_unittest.cc +++ /dev/null
@@ -1,436 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chromeos/components/tether/ble_service_data_helper_impl.h" - -#include <memory> - -#include "base/macros.h" -#include "base/test/scoped_feature_list.h" -#include "chromeos/chromeos_features.h" -#include "chromeos/components/tether/fake_tether_host_fetcher.h" -#include "chromeos/services/device_sync/public/cpp/fake_device_sync_client.h" -#include "chromeos/services/secure_channel/device_id_pair.h" -#include "components/cryptauth/ble/ble_advertisement_generator.h" -#include "components/cryptauth/ble/fake_ble_advertisement_generator.h" -#include "components/cryptauth/fake_background_eid_generator.h" -#include "components/cryptauth/mock_foreground_eid_generator.h" -#include "components/cryptauth/mock_local_device_data_provider.h" -#include "components/cryptauth/remote_device_cache.h" -#include "components/cryptauth/remote_device_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace chromeos { - -namespace tether { - -namespace { - -const size_t kNumTestDevices = 3; - -const size_t kNumBytesInBackgroundAdvertisementServiceData = 2; -const size_t kMinNumBytesInForegroundAdvertisementServiceData = 4; - -const char current_eid_data[] = "currentEidData"; -const int64_t current_eid_start_ms = 1000L; -const int64_t current_eid_end_ms = 2000L; - -const char adjacent_eid_data[] = "adjacentEidData"; -const int64_t adjacent_eid_start_ms = 2000L; -const int64_t adjacent_eid_end_ms = 3000L; - -const char fake_beacon_seed1_data[] = "fakeBeaconSeed1Data"; -const int64_t fake_beacon_seed1_start_ms = current_eid_start_ms; -const int64_t fake_beacon_seed1_end_ms = current_eid_end_ms; - -const char fake_beacon_seed2_data[] = "fakeBeaconSeed2Data"; -const int64_t fake_beacon_seed2_start_ms = adjacent_eid_start_ms; -const int64_t fake_beacon_seed2_end_ms = adjacent_eid_end_ms; - -std::unique_ptr<cryptauth::ForegroundEidGenerator::EidData> -CreateFakeBackgroundScanFilter() { - cryptauth::DataWithTimestamp current(current_eid_data, current_eid_start_ms, - current_eid_end_ms); - - std::unique_ptr<cryptauth::DataWithTimestamp> adjacent = - std::make_unique<cryptauth::DataWithTimestamp>( - adjacent_eid_data, adjacent_eid_start_ms, adjacent_eid_end_ms); - - return std::make_unique<cryptauth::ForegroundEidGenerator::EidData>( - current, std::move(adjacent)); -} - -std::vector<cryptauth::BeaconSeed> CreateFakeBeaconSeeds() { - cryptauth::BeaconSeed seed1; - seed1.set_data(fake_beacon_seed1_data); - seed1.set_start_time_millis(fake_beacon_seed1_start_ms); - seed1.set_start_time_millis(fake_beacon_seed1_end_ms); - - cryptauth::BeaconSeed seed2; - seed2.set_data(fake_beacon_seed2_data); - seed2.set_start_time_millis(fake_beacon_seed2_start_ms); - seed2.set_start_time_millis(fake_beacon_seed2_end_ms); - - std::vector<cryptauth::BeaconSeed> seeds = {seed1, seed2}; - return seeds; -} - -cryptauth::RemoteDeviceRef CreateLocalDevice() { - return cryptauth::RemoteDeviceRefBuilder() - .SetPublicKey("local public key") - .SetBeaconSeeds(CreateFakeBeaconSeeds()) - .Build(); -} - -} // namespace - -class BleServiceDataHelperImplTest : public testing::Test { - protected: - BleServiceDataHelperImplTest() - : test_local_device_(CreateLocalDevice()), - test_remote_devices_( - cryptauth::CreateRemoteDeviceRefListForTest(kNumTestDevices)), - fake_advertisement_( - cryptauth::DataWithTimestamp("advertisement1", 1000L, 2000L)) { - std::transform(test_remote_devices_.begin(), test_remote_devices_.end(), - std::back_inserter(test_remote_device_ids_), - [](const auto& device) { return device.GetDeviceId(); }); - }; - ~BleServiceDataHelperImplTest() override = default; - - // testing::Test: - void SetUp() override { - fake_ble_advertisement_generator_ = - std::make_unique<cryptauth::FakeBleAdvertisementGenerator>(); - cryptauth::BleAdvertisementGenerator::SetInstanceForTesting( - fake_ble_advertisement_generator_.get()); - fake_ble_advertisement_generator_->set_advertisement( - std::make_unique<cryptauth::DataWithTimestamp>(fake_advertisement_)); - - fake_tether_host_fetcher_ = std::make_unique<FakeTetherHostFetcher>(); - fake_tether_host_fetcher_->set_tether_hosts({test_remote_devices_[0], - test_remote_devices_[1], - test_remote_devices_[2]}); - - mock_local_device_data_provider_ = - std::make_unique<cryptauth::MockLocalDeviceDataProvider>(); - mock_local_device_data_provider_->SetBeaconSeeds( - std::make_unique<std::vector<cryptauth::BeaconSeed>>( - test_local_device_.beacon_seeds())); - - fake_device_sync_client_ = - std::make_unique<device_sync::FakeDeviceSyncClient>(); - - mock_foreground_eid_generator_ = - new cryptauth::MockForegroundEidGenerator(); - mock_foreground_eid_generator_->set_background_scan_filter( - CreateFakeBackgroundScanFilter()); - fake_background_eid_generator_ = - new cryptauth::FakeBackgroundEidGenerator(); - } - - void TearDown() override { - cryptauth::BleAdvertisementGenerator::SetInstanceForTesting(nullptr); - } - - void InitializeTest() { - helper_ = base::WrapUnique(new BleServiceDataHelperImpl( - fake_tether_host_fetcher_.get(), - base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) - ? nullptr - : mock_local_device_data_provider_.get(), - base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) - ? fake_device_sync_client_.get() - : nullptr)); - - helper_->SetTestDoubles(base::WrapUnique(fake_background_eid_generator_), - base::WrapUnique(mock_foreground_eid_generator_)); - - SetLocalDeviceMetadata(test_local_device_); - } - - void SetMultiDeviceApiEnabled() { - scoped_feature_list_.InitAndEnableFeature(features::kMultiDeviceApi); - } - - void SetLocalDeviceMetadata( - base::Optional<cryptauth::RemoteDeviceRef> local_device) { - if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) { - fake_device_sync_client_->set_local_device_metadata(local_device); - } else { - mock_local_device_data_provider_->SetPublicKey( - local_device - ? std::make_unique<std::string>(local_device->public_key()) - : nullptr); - } - } - - void TestIdentifyRemoteDevice_InvalidAdvertisementLength() { - InitializeTest(); - - std::string invalid_service_data = "a"; - mock_foreground_eid_generator_->set_identified_device_id( - test_remote_devices_[0].GetDeviceId()); - - auto device_with_background_bool = helper_->IdentifyRemoteDevice( - invalid_service_data, test_remote_device_ids_); - - EXPECT_EQ(0, mock_foreground_eid_generator_->num_identify_calls()); - EXPECT_EQ(0, fake_background_eid_generator_->num_identify_calls()); - EXPECT_FALSE(device_with_background_bool); - } - - void TestIdentifyRemoteDevice_ForegroundAdvertisement() { - InitializeTest(); - - std::string valid_service_data_for_registered_device = "abcde"; - ASSERT_TRUE(valid_service_data_for_registered_device.size() >= - kMinNumBytesInForegroundAdvertisementServiceData); - - mock_foreground_eid_generator_->set_identified_device_id( - test_remote_devices_[0].GetDeviceId()); - - auto device_with_background_bool = helper_->IdentifyRemoteDevice( - valid_service_data_for_registered_device, test_remote_device_ids_); - - EXPECT_EQ(1, mock_foreground_eid_generator_->num_identify_calls()); - EXPECT_EQ(0, fake_background_eid_generator_->num_identify_calls()); - EXPECT_EQ(test_remote_devices_[0].GetDeviceId(), - device_with_background_bool->first.GetDeviceId()); - EXPECT_FALSE(device_with_background_bool->second); - } - - void TestIdentifyRemoteDevice_ForegroundAdvertisement_NoRegisteredDevice() { - InitializeTest(); - - std::string valid_service_data = "abcde"; - ASSERT_TRUE(valid_service_data.size() >= - kMinNumBytesInForegroundAdvertisementServiceData); - - auto device_with_background_bool = helper_->IdentifyRemoteDevice( - valid_service_data, test_remote_device_ids_); - - EXPECT_EQ(1, mock_foreground_eid_generator_->num_identify_calls()); - EXPECT_EQ(0, fake_background_eid_generator_->num_identify_calls()); - EXPECT_FALSE(device_with_background_bool); - } - - void TestIdentifyRemoteDevice_BackgroundAdvertisement() { - InitializeTest(); - - std::string valid_service_data_for_registered_device = "ab"; - ASSERT_TRUE(valid_service_data_for_registered_device.size() >= - kNumBytesInBackgroundAdvertisementServiceData); - - fake_background_eid_generator_->set_identified_device_id( - test_remote_devices_[0].GetDeviceId()); - - auto device_with_background_bool = helper_->IdentifyRemoteDevice( - valid_service_data_for_registered_device, test_remote_device_ids_); - - EXPECT_EQ(0, mock_foreground_eid_generator_->num_identify_calls()); - EXPECT_EQ(1, fake_background_eid_generator_->num_identify_calls()); - EXPECT_EQ(test_remote_devices_[0].GetDeviceId(), - device_with_background_bool->first.GetDeviceId()); - EXPECT_TRUE(device_with_background_bool->second); - } - - void TestIdentifyRemoteDevice_BackgroundAdvertisement_NoRegisteredDevice() { - InitializeTest(); - - std::string valid_service_data_for_registered_device = "ab"; - ASSERT_TRUE(valid_service_data_for_registered_device.size() >= - kNumBytesInBackgroundAdvertisementServiceData); - - auto device_with_background_bool = helper_->IdentifyRemoteDevice( - valid_service_data_for_registered_device, test_remote_device_ids_); - - EXPECT_EQ(0, mock_foreground_eid_generator_->num_identify_calls()); - EXPECT_EQ(1, fake_background_eid_generator_->num_identify_calls()); - EXPECT_FALSE(device_with_background_bool); - } - - std::unique_ptr<cryptauth::DataWithTimestamp> - CallGenerateForegroundAdvertisement(const std::string& remote_device_id) { - return helper_->GenerateForegroundAdvertisement( - secure_channel::DeviceIdPair(remote_device_id, - std::string() /* local_device_id */)); - } - - std::unique_ptr<cryptauth::FakeBleAdvertisementGenerator> - fake_ble_advertisement_generator_; - std::unique_ptr<FakeTetherHostFetcher> fake_tether_host_fetcher_; - std::unique_ptr<cryptauth::MockLocalDeviceDataProvider> - mock_local_device_data_provider_; - std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_; - - cryptauth::MockForegroundEidGenerator* mock_foreground_eid_generator_; - cryptauth::FakeBackgroundEidGenerator* fake_background_eid_generator_; - - std::unique_ptr<BleServiceDataHelperImpl> helper_; - - cryptauth::RemoteDeviceRef test_local_device_; - cryptauth::RemoteDeviceRefList test_remote_devices_; - std::vector<std::string> test_remote_device_ids_; - cryptauth::DataWithTimestamp fake_advertisement_; - - private: - base::test::ScopedFeatureList scoped_feature_list_; - - DISALLOW_COPY_AND_ASSIGN(BleServiceDataHelperImplTest); -}; - -TEST_F(BleServiceDataHelperImplTest, - TestGenerateForegroundAdvertisement_CannotGenerateAdvertisement) { - InitializeTest(); - fake_ble_advertisement_generator_->set_advertisement(nullptr); - EXPECT_FALSE(CallGenerateForegroundAdvertisement( - test_remote_devices_[1].GetDeviceId())); -} - -TEST_F( - BleServiceDataHelperImplTest, - TestGenerateForegroundAdvertisement_CannotGenerateAdvertisement_MultideviceApiEnabled) { - SetMultiDeviceApiEnabled(); - - InitializeTest(); - fake_ble_advertisement_generator_->set_advertisement(nullptr); - EXPECT_FALSE(CallGenerateForegroundAdvertisement( - test_remote_devices_[1].GetDeviceId())); -} - -TEST_F(BleServiceDataHelperImplTest, TestGenerateForegroundAdvertisement) { - InitializeTest(); - auto data_with_timestamp = CallGenerateForegroundAdvertisement( - test_remote_devices_[1].GetDeviceId()); - EXPECT_EQ(fake_advertisement_, *data_with_timestamp); -} - -TEST_F(BleServiceDataHelperImplTest, - TestGenerateForegroundAdvertisement_MultideviceApiEnabled) { - SetMultiDeviceApiEnabled(); - - InitializeTest(); - auto data_with_timestamp = CallGenerateForegroundAdvertisement( - test_remote_devices_[1].GetDeviceId()); - EXPECT_EQ(fake_advertisement_, *data_with_timestamp); -} - -TEST_F(BleServiceDataHelperImplTest, - TestGenerateForegroundAdvertisement_NoLocalDeviceMetadata) { - InitializeTest(); - SetLocalDeviceMetadata(base::nullopt); - EXPECT_FALSE(CallGenerateForegroundAdvertisement( - test_remote_devices_[0].GetDeviceId())); -} - -TEST_F( - BleServiceDataHelperImplTest, - TestGenerateForegroundAdvertisement_NoLocalDeviceMetadata_MultideviceApiEnabled) { - SetMultiDeviceApiEnabled(); - - InitializeTest(); - SetLocalDeviceMetadata(base::nullopt); - EXPECT_FALSE(CallGenerateForegroundAdvertisement( - test_remote_devices_[0].GetDeviceId())); -} - -TEST_F(BleServiceDataHelperImplTest, - TestGenerateForegroundAdvertisement_EmptyLocalPublicKey) { - InitializeTest(); - - SetLocalDeviceMetadata( - cryptauth::RemoteDeviceRefBuilder().SetPublicKey(std::string()).Build()); - EXPECT_FALSE(CallGenerateForegroundAdvertisement( - test_remote_devices_[0].GetDeviceId())); -} - -TEST_F( - BleServiceDataHelperImplTest, - TestGenerateForegroundAdvertisement_EmptyLocalPublicKey_MultideviceApiEnabled) { - SetMultiDeviceApiEnabled(); - - InitializeTest(); - SetLocalDeviceMetadata( - cryptauth::RemoteDeviceRefBuilder().SetPublicKey(std::string()).Build()); - EXPECT_FALSE(CallGenerateForegroundAdvertisement( - test_remote_devices_[0].GetDeviceId())); -} - -TEST_F(BleServiceDataHelperImplTest, - TestGenerateForegroundAdvertisement_RemoteDeviceNotInTetherHostList) { - InitializeTest(); - EXPECT_FALSE(CallGenerateForegroundAdvertisement("invalid device id")); -} - -TEST_F( - BleServiceDataHelperImplTest, - TestGenerateForegroundAdvertisement_RemoteDeviceNotInTetherHostList_MultideviceApiEnabled) { - SetMultiDeviceApiEnabled(); - - InitializeTest(); - EXPECT_FALSE(CallGenerateForegroundAdvertisement("invalid device id")); -} - -TEST_F(BleServiceDataHelperImplTest, - TestIdentifyRemoteDevice_InvalidAdvertisementLength) { - TestIdentifyRemoteDevice_InvalidAdvertisementLength(); -} - -TEST_F( - BleServiceDataHelperImplTest, - TestIdentifyRemoteDevice_InvalidAdvertisementLength_MultideviceApiEnabled) { - SetMultiDeviceApiEnabled(); - TestIdentifyRemoteDevice_InvalidAdvertisementLength(); -} - -TEST_F(BleServiceDataHelperImplTest, - TestIdentifyRemoteDevice_ForegroundAdvertisement) { - TestIdentifyRemoteDevice_ForegroundAdvertisement(); -} - -TEST_F(BleServiceDataHelperImplTest, - TestIdentifyRemoteDevice_ForegroundAdvertisement_MultideviceApiEnabled) { - SetMultiDeviceApiEnabled(); - TestIdentifyRemoteDevice_ForegroundAdvertisement(); -} - -TEST_F(BleServiceDataHelperImplTest, - TestIdentifyRemoteDevice_ForegroundAdvertisement_NoRegisteredDevice) { - TestIdentifyRemoteDevice_ForegroundAdvertisement_NoRegisteredDevice(); -} - -TEST_F( - BleServiceDataHelperImplTest, - TestIdentifyRemoteDevice_ForegroundAdvertisement_NoRegisteredDevice_MultideviceApiEnabled) { - SetMultiDeviceApiEnabled(); - TestIdentifyRemoteDevice_ForegroundAdvertisement_NoRegisteredDevice(); -} - -TEST_F(BleServiceDataHelperImplTest, - TestIdentifyRemoteDevice_BackgroundAdvertisement) { - TestIdentifyRemoteDevice_BackgroundAdvertisement(); -} - -TEST_F(BleServiceDataHelperImplTest, - TestIdentifyRemoteDevice_BackgroundAdvertisement_MultideviceApiEnabled) { - SetMultiDeviceApiEnabled(); - TestIdentifyRemoteDevice_BackgroundAdvertisement(); -} - -TEST_F(BleServiceDataHelperImplTest, - TestIdentifyRemoteDevice_BackgroundAdvertisement_NoRegisteredDevice) { - TestIdentifyRemoteDevice_BackgroundAdvertisement_NoRegisteredDevice(); -} - -TEST_F( - BleServiceDataHelperImplTest, - TestIdentifyRemoteDevice_BackgroundAdvertisement_NoRegisteredDevice_MultideviceApiEnabled) { - SetMultiDeviceApiEnabled(); - TestIdentifyRemoteDevice_BackgroundAdvertisement_NoRegisteredDevice(); -} - -} // namespace tether - -} // namespace chromeos
diff --git a/chromeos/components/tether/connect_tethering_operation_unittest.cc b/chromeos/components/tether/connect_tethering_operation_unittest.cc index d262164..8336e47 100644 --- a/chromeos/components/tether/connect_tethering_operation_unittest.cc +++ b/chromeos/components/tether/connect_tethering_operation_unittest.cc
@@ -11,10 +11,8 @@ #include "base/memory/ptr_util.h" #include "base/optional.h" #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "base/test/simple_test_clock.h" -#include "chromeos/chromeos_features.h" #include "chromeos/components/tether/fake_ble_connection_manager.h" #include "chromeos/components/tether/message_wrapper.h" #include "chromeos/components/tether/mock_tether_host_response_recorder.h" @@ -125,8 +123,6 @@ test_device_(cryptauth::CreateRemoteDeviceRefListForTest(1)[0]) {} void SetUp() override { - scoped_feature_list_.InitAndDisableFeature(features::kMultiDeviceApi); - fake_device_sync_client_ = std::make_unique<device_sync::FakeDeviceSyncClient>(); fake_secure_channel_client_ = @@ -223,7 +219,6 @@ const std::string connect_tethering_request_string_; const cryptauth::RemoteDeviceRef test_device_; - base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_; std::unique_ptr<secure_channel::SecureChannelClient>
diff --git a/chromeos/components/tether/disconnect_tethering_operation_unittest.cc b/chromeos/components/tether/disconnect_tethering_operation_unittest.cc index e8b8fa6..fe553ada 100644 --- a/chromeos/components/tether/disconnect_tethering_operation_unittest.cc +++ b/chromeos/components/tether/disconnect_tethering_operation_unittest.cc
@@ -9,10 +9,8 @@ #include "base/memory/ptr_util.h" #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "base/test/simple_test_clock.h" -#include "chromeos/chromeos_features.h" #include "chromeos/components/tether/fake_ble_connection_manager.h" #include "chromeos/components/tether/message_wrapper.h" #include "chromeos/components/tether/proto/tether.pb.h" @@ -69,8 +67,6 @@ test_device_(cryptauth::CreateRemoteDeviceRefListForTest(1)[0]) {} void SetUp() override { - scoped_feature_list_.InitAndDisableFeature(features::kMultiDeviceApi); - fake_device_sync_client_ = std::make_unique<device_sync::FakeDeviceSyncClient>(); fake_secure_channel_client_ = @@ -120,7 +116,6 @@ const std::string disconnect_tethering_request_string_; const cryptauth::RemoteDeviceRef test_device_; - base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_; std::unique_ptr<secure_channel::SecureChannelClient>
diff --git a/chromeos/components/tether/disconnect_tethering_request_sender_impl_unittest.cc b/chromeos/components/tether/disconnect_tethering_request_sender_impl_unittest.cc index ab14a01..5b9d556 100644 --- a/chromeos/components/tether/disconnect_tethering_request_sender_impl_unittest.cc +++ b/chromeos/components/tether/disconnect_tethering_request_sender_impl_unittest.cc
@@ -7,9 +7,7 @@ #include <memory> #include "base/memory/ptr_util.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" -#include "chromeos/chromeos_features.h" #include "chromeos/components/tether/disconnect_tethering_operation.h" #include "chromeos/components/tether/disconnect_tethering_request_sender.h" #include "chromeos/components/tether/fake_tether_host_fetcher.h" @@ -103,8 +101,6 @@ ~DisconnectTetheringRequestSenderTest() override = default; void SetUp() override { - scoped_feature_list_.InitAndDisableFeature(features::kMultiDeviceApi); - fake_device_sync_client_ = std::make_unique<device_sync::FakeDeviceSyncClient>(); fake_secure_channel_client_ = @@ -187,7 +183,6 @@ } const cryptauth::RemoteDeviceRefList test_devices_; - base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_; std::unique_ptr<secure_channel::SecureChannelClient>
diff --git a/chromeos/components/tether/host_connection_metrics_logger_unittest.cc b/chromeos/components/tether/host_connection_metrics_logger_unittest.cc index c19af5d..d4e8bda 100644 --- a/chromeos/components/tether/host_connection_metrics_logger_unittest.cc +++ b/chromeos/components/tether/host_connection_metrics_logger_unittest.cc
@@ -7,9 +7,7 @@ #include <memory> #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "base/test/simple_test_clock.h" -#include "chromeos/chromeos_features.h" #include "chromeos/components/tether/fake_active_host.h" #include "components/cryptauth/remote_device_ref.h" #include "components/cryptauth/remote_device_test_util.h" @@ -117,8 +115,6 @@ base::HistogramTester histogram_tester_; base::SimpleTestClock test_clock_; - base::test::ScopedFeatureList scoped_feature_list_; - private: DISALLOW_COPY_AND_ASSIGN(HostConnectionMetricsLoggerTest); };
diff --git a/chromeos/components/tether/host_scan_scheduler_impl.cc b/chromeos/components/tether/host_scan_scheduler_impl.cc index 7362d68..e227c9b 100644 --- a/chromeos/components/tether/host_scan_scheduler_impl.cc +++ b/chromeos/components/tether/host_scan_scheduler_impl.cc
@@ -10,7 +10,6 @@ #include "base/metrics/histogram_macros.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/default_clock.h" -#include "chromeos/chromeos_features.h" #include "chromeos/chromeos_switches.h" #include "chromeos/components/proximity_auth/logging/logging.h" #include "chromeos/network/network_handler.h"
diff --git a/chromeos/components/tether/host_scan_scheduler_impl_unittest.cc b/chromeos/components/tether/host_scan_scheduler_impl_unittest.cc index 10cc903..8f463484 100644 --- a/chromeos/components/tether/host_scan_scheduler_impl_unittest.cc +++ b/chromeos/components/tether/host_scan_scheduler_impl_unittest.cc
@@ -9,12 +9,10 @@ #include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "base/test/simple_test_clock.h" #include "base/test/test_simple_task_runner.h" #include "base/timer/mock_timer.h" -#include "chromeos/chromeos_features.h" #include "chromeos/components/tether/fake_host_scanner.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/power_manager_client.h" @@ -173,8 +171,6 @@ std::unique_ptr<base::HistogramTester> histogram_tester_; std::unique_ptr<HostScanSchedulerImpl> host_scan_scheduler_; - - base::test::ScopedFeatureList scoped_feature_list_; }; TEST_F(HostScanSchedulerImplTest, AttemptScanIfOffline) {
diff --git a/chromeos/components/tether/host_scanner_impl_unittest.cc b/chromeos/components/tether/host_scanner_impl_unittest.cc index c8323aa9..394a02e2 100644 --- a/chromeos/components/tether/host_scanner_impl_unittest.cc +++ b/chromeos/components/tether/host_scanner_impl_unittest.cc
@@ -11,11 +11,9 @@ #include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "base/test/simple_test_clock.h" #include "base/time/time.h" -#include "chromeos/chromeos_features.h" #include "chromeos/components/tether/device_id_tether_network_guid_map.h" #include "chromeos/components/tether/fake_connection_preserver.h" #include "chromeos/components/tether/fake_host_scan_cache.h" @@ -202,8 +200,6 @@ } void SetUp() override { - scoped_feature_list_.InitAndDisableFeature(features::kMultiDeviceApi); - DBusThreadManager::Initialize(); NetworkHandler::Initialize(); NetworkStateTest::SetUp(); @@ -407,7 +403,6 @@ const cryptauth::RemoteDeviceRefList test_devices_; const std::vector<HostScannerOperation::ScannedDeviceInfo> test_scanned_device_infos; - base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_; std::unique_ptr<secure_channel::SecureChannelClient>
diff --git a/chromeos/components/tether/host_scanner_operation_unittest.cc b/chromeos/components/tether/host_scanner_operation_unittest.cc index 15d6b5f..a4d662a 100644 --- a/chromeos/components/tether/host_scanner_operation_unittest.cc +++ b/chromeos/components/tether/host_scanner_operation_unittest.cc
@@ -11,11 +11,9 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "base/test/simple_test_clock.h" #include "base/test/test_simple_task_runner.h" -#include "chromeos/chromeos_features.h" #include "chromeos/components/tether/fake_ble_connection_manager.h" #include "chromeos/components/tether/fake_connection_preserver.h" #include "chromeos/components/tether/host_scan_device_prioritizer.h" @@ -138,8 +136,6 @@ test_devices_(cryptauth::CreateRemoteDeviceRefListForTest(5)) {} void SetUp() override { - scoped_feature_list_.InitAndDisableFeature(features::kMultiDeviceApi); - fake_device_sync_client_ = std::make_unique<device_sync::FakeDeviceSyncClient>(); fake_secure_channel_client_ = @@ -273,7 +269,6 @@ const std::string tether_availability_request_string_; const cryptauth::RemoteDeviceRefList test_devices_; - base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_; std::unique_ptr<secure_channel::SecureChannelClient>
diff --git a/chromeos/components/tether/keep_alive_operation_unittest.cc b/chromeos/components/tether/keep_alive_operation_unittest.cc index 178fd722..315bc066 100644 --- a/chromeos/components/tether/keep_alive_operation_unittest.cc +++ b/chromeos/components/tether/keep_alive_operation_unittest.cc
@@ -10,10 +10,8 @@ #include "base/memory/ptr_util.h" #include "base/optional.h" #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "base/test/simple_test_clock.h" -#include "chromeos/chromeos_features.h" #include "chromeos/components/tether/fake_ble_connection_manager.h" #include "chromeos/components/tether/message_wrapper.h" #include "chromeos/components/tether/proto/tether.pb.h" @@ -83,8 +81,6 @@ test_device_(cryptauth::CreateRemoteDeviceRefListForTest(1)[0]) {} void SetUp() override { - scoped_feature_list_.InitAndDisableFeature(features::kMultiDeviceApi); - fake_device_sync_client_ = std::make_unique<device_sync::FakeDeviceSyncClient>(); fake_secure_channel_client_ = @@ -118,7 +114,6 @@ const base::test::ScopedTaskEnvironment scoped_task_environment_; const std::string keep_alive_tickle_string_; const cryptauth::RemoteDeviceRef test_device_; - base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_; std::unique_ptr<secure_channel::SecureChannelClient>
diff --git a/chromeos/components/tether/keep_alive_scheduler_unittest.cc b/chromeos/components/tether/keep_alive_scheduler_unittest.cc index 30d7d66..fad1bf5 100644 --- a/chromeos/components/tether/keep_alive_scheduler_unittest.cc +++ b/chromeos/components/tether/keep_alive_scheduler_unittest.cc
@@ -8,9 +8,7 @@ #include <vector> #include "base/memory/ptr_util.h" -#include "base/test/scoped_feature_list.h" #include "base/timer/mock_timer.h" -#include "chromeos/chromeos_features.h" #include "chromeos/components/tether/device_id_tether_network_guid_map.h" #include "chromeos/components/tether/fake_active_host.h" #include "chromeos/components/tether/fake_host_scan_cache.h" @@ -101,8 +99,6 @@ : test_devices_(cryptauth::CreateRemoteDeviceRefListForTest(2)) {} void SetUp() override { - scoped_feature_list_.InitAndDisableFeature(features::kMultiDeviceApi); - fake_device_sync_client_ = std::make_unique<device_sync::FakeDeviceSyncClient>(); fake_secure_channel_client_ = @@ -158,7 +154,6 @@ } const cryptauth::RemoteDeviceRefList test_devices_; - base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_; std::unique_ptr<secure_channel::SecureChannelClient>
diff --git a/chromeos/components/tether/message_transfer_operation_unittest.cc b/chromeos/components/tether/message_transfer_operation_unittest.cc index e65e482..ae79ee4 100644 --- a/chromeos/components/tether/message_transfer_operation_unittest.cc +++ b/chromeos/components/tether/message_transfer_operation_unittest.cc
@@ -8,7 +8,6 @@ #include "base/memory/ptr_util.h" #include "base/timer/mock_timer.h" -#include "chromeos/chromeos_features.h" #include "chromeos/components/tether/message_wrapper.h" #include "chromeos/components/tether/proto_test_util.h" #include "chromeos/components/tether/timer_factory.h"
diff --git a/chromeos/components/tether/tether_component_impl.cc b/chromeos/components/tether/tether_component_impl.cc index 1357d64..4ff7b81 100644 --- a/chromeos/components/tether/tether_component_impl.cc +++ b/chromeos/components/tether/tether_component_impl.cc
@@ -152,7 +152,6 @@ session_manager::SessionManager* session_manager) : asynchronous_shutdown_object_container_( AsynchronousShutdownObjectContainerImpl::Factory::NewInstance( - adapter, cryptauth_service, device_sync_client, secure_channel_client,
diff --git a/chromeos/components/tether/tether_component_impl_unittest.cc b/chromeos/components/tether/tether_component_impl_unittest.cc index cf30d67..65174ea5 100644 --- a/chromeos/components/tether/tether_component_impl_unittest.cc +++ b/chromeos/components/tether/tether_component_impl_unittest.cc
@@ -50,7 +50,6 @@ // AsynchronousShutdownObjectContainerImpl::Factory: std::unique_ptr<AsynchronousShutdownObjectContainer> BuildInstance( - scoped_refptr<device::BluetoothAdapter> adapter, cryptauth::CryptAuthService* cryptauth_service, device_sync::DeviceSyncClient* device_sync_client, secure_channel::SecureChannelClient* secure_channel_client,
diff --git a/chromeos/components/tether/tether_connector_impl_unittest.cc b/chromeos/components/tether/tether_connector_impl_unittest.cc index 23c38c0..b82b0b67 100644 --- a/chromeos/components/tether/tether_connector_impl_unittest.cc +++ b/chromeos/components/tether/tether_connector_impl_unittest.cc
@@ -9,8 +9,6 @@ #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" -#include "chromeos/chromeos_features.h" #include "chromeos/components/tether/connect_tethering_operation.h" #include "chromeos/components/tether/device_id_tether_network_guid_map.h" #include "chromeos/components/tether/fake_active_host.h" @@ -143,8 +141,6 @@ ~TetherConnectorImplTest() override = default; void SetUp() override { - scoped_feature_list_.InitAndDisableFeature(features::kMultiDeviceApi); - DBusThreadManager::Initialize(); NetworkStateTest::SetUp(); network_state_handler()->SetTetherTechnologyState( @@ -350,7 +346,6 @@ std::string result_; base::HistogramTester histogram_tester_; - base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<TetherConnectorImpl> tether_connector_;
diff --git a/chromeos/components/tether/tether_host_fetcher_impl.cc b/chromeos/components/tether/tether_host_fetcher_impl.cc index 5530c84..e6d0d9df 100644 --- a/chromeos/components/tether/tether_host_fetcher_impl.cc +++ b/chromeos/components/tether/tether_host_fetcher_impl.cc
@@ -7,7 +7,6 @@ #include <memory> #include "base/memory/ptr_util.h" -#include "chromeos/chromeos_features.h" #include "components/cryptauth/remote_device.h" namespace chromeos {
diff --git a/chromeos/resources/chromeos_resources.grd b/chromeos/resources/chromeos_resources.grd index 9e0a036..9dfa5fae 100644 --- a/chromeos/resources/chromeos_resources.grd +++ b/chromeos/resources/chromeos_resources.grd
@@ -5,7 +5,7 @@ <emit emit_type='prepend'></emit> </output> <output filename="grit/chromeos_resources_map.cc" - type="gzipped_resource_file_map_source" /> + type="gzipped_resource_map_source" /> <output filename="grit/chromeos_resources_map.h" type="gzipped_resource_map_header" /> <output filename="chromeos_resources.pak" type="data_package" />
diff --git a/chromeos/services/BUILD.gn b/chromeos/services/BUILD.gn index 3ed8fc8..1e9b53a 100644 --- a/chromeos/services/BUILD.gn +++ b/chromeos/services/BUILD.gn
@@ -5,8 +5,6 @@ import("//build/config/ui.gni") import("//chromeos/assistant/assistant.gni") import("//chromeos/services/ime/public/features.gni") -import("//services/catalog/public/tools/catalog.gni") -import("//services/service_manager/public/tools/test/service_test.gni") import("//testing/test.gni") assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos") @@ -32,28 +30,13 @@ # Use this target for adding new service tests. To add a unit test to this # target, create a "tests" source_set in your service and add it as a dependency # here. -# -# If your unit tests use the ServiceTest framework, you must also include -# corresponding catalog entries in the "chromeos_services_unittests_catalog" -# target below. -service_test("chromeos_services_unittests") { +test("chromeos_services_unittests") { deps = [ "//chromeos/services/ime:services_unittests", + "//mojo/core/test:run_all_unittests", ] if (enable_cros_assistant) { deps += [ "//chromeos/services/assistant:tests" ] } - - catalog = ":chromeos_services_unittests_catalog" -} - -catalog("chromeos_services_unittests_catalog") { - testonly = true - - catalog_deps = [ "//chromeos/services/ime:tests_catalog" ] - - if (enable_cros_assistant) { - catalog_deps += [ "//chromeos/services/assistant:tests_catalog" ] - } }
diff --git a/chromeos/services/assistant/BUILD.gn b/chromeos/services/assistant/BUILD.gn index bdb34f6..8954204 100644 --- a/chromeos/services/assistant/BUILD.gn +++ b/chromeos/services/assistant/BUILD.gn
@@ -3,8 +3,6 @@ # found in the LICENSE file. import("//chromeos/assistant/assistant.gni") -import("//services/catalog/public/tools/catalog.gni") -import("//services/service_manager/public/cpp/service.gni") import("//services/service_manager/public/service_manifest.gni") assert(is_chromeos) @@ -115,7 +113,7 @@ "//services/device/public/mojom", "//services/identity/public/mojom", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp:service_test_support", + "//services/service_manager/public/cpp/test:test_support", "//testing/gmock", "//testing/gtest", ] @@ -133,17 +131,6 @@ } } -service_manifest("unittest_manifest") { - name = "assistant_unittests" - source = "unittest_manifest.json" - packaged_services = [ ":manifest" ] -} - -catalog("tests_catalog") { - testonly = true - embedded_services = [ ":unittest_manifest" ] -} - static_library("test_support") { testonly = true sources = [
diff --git a/chromeos/services/assistant/OWNERS b/chromeos/services/assistant/OWNERS index b8c8d550..03ef6f4 100644 --- a/chromeos/services/assistant/OWNERS +++ b/chromeos/services/assistant/OWNERS
@@ -4,6 +4,3 @@ per-file manifest.json=set noparent per-file manifest.json=file://ipc/SECURITY_OWNERS - -per-file unittest_manifest.json=set noparent -per-file unittest_manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc index ebf7ff9..b48873b 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -344,11 +344,15 @@ /*assistant_tree=*/nullptr)); } -void AssistantManagerServiceImpl::SendTextQuery(const std::string& query) { +void AssistantManagerServiceImpl::StartTextInteraction(const std::string& query, + bool allow_tts) { assistant_client::VoicelessOptions options; options.is_user_initiated = true; - options.modality = - assistant_client::VoicelessOptions::Modality::TYPING_MODALITY; + + if (!allow_tts) { + options.modality = + assistant_client::VoicelessOptions::Modality::TYPING_MODALITY; + } std::string interaction = CreateTextQueryInteraction(query); assistant_manager_internal_->SendVoicelessInteraction(
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.h b/chromeos/services/assistant/assistant_manager_service_impl.h index 420fbb1..4bbc180 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.h +++ b/chromeos/services/assistant/assistant_manager_service_impl.h
@@ -92,9 +92,9 @@ // mojom::Assistant overrides: void StartCachedScreenContextInteraction() override; void StartMetalayerInteraction(const gfx::Rect& region) override; + void StartTextInteraction(const std::string& query, bool allow_tts) override; void StartVoiceInteraction() override; void StopActiveInteraction(bool cancel_conversation) override; - void SendTextQuery(const std::string& query) override; void AddAssistantInteractionSubscriber( mojom::AssistantInteractionSubscriberPtr subscriber) override; void AddAssistantNotificationSubscriber(
diff --git a/chromeos/services/assistant/fake_assistant_manager_service_impl.cc b/chromeos/services/assistant/fake_assistant_manager_service_impl.cc index a5f32b46..323b7b9 100644 --- a/chromeos/services/assistant/fake_assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/fake_assistant_manager_service_impl.cc
@@ -61,13 +61,15 @@ void FakeAssistantManagerServiceImpl::StartMetalayerInteraction( const gfx::Rect& region) {} +void FakeAssistantManagerServiceImpl::StartTextInteraction( + const std::string& query, + bool allow_tts) {} + void FakeAssistantManagerServiceImpl::StartVoiceInteraction() {} void FakeAssistantManagerServiceImpl::StopActiveInteraction( bool cancel_conversation) {} -void FakeAssistantManagerServiceImpl::SendTextQuery(const std::string& query) {} - void FakeAssistantManagerServiceImpl::AddAssistantInteractionSubscriber( mojom::AssistantInteractionSubscriberPtr subscriber) {}
diff --git a/chromeos/services/assistant/fake_assistant_manager_service_impl.h b/chromeos/services/assistant/fake_assistant_manager_service_impl.h index d4345ba..b27b8ed 100644 --- a/chromeos/services/assistant/fake_assistant_manager_service_impl.h +++ b/chromeos/services/assistant/fake_assistant_manager_service_impl.h
@@ -48,9 +48,9 @@ // mojom::Assistant overrides: void StartCachedScreenContextInteraction() override; void StartMetalayerInteraction(const gfx::Rect& region) override; + void StartTextInteraction(const std::string& query, bool allow_tts) override; void StartVoiceInteraction() override; void StopActiveInteraction(bool cancel_conversation) override; - void SendTextQuery(const std::string& query) override; void AddAssistantInteractionSubscriber( mojom::AssistantInteractionSubscriberPtr subscriber) override; void AddAssistantNotificationSubscriber(
diff --git a/chromeos/services/assistant/public/mojom/assistant.mojom b/chromeos/services/assistant/public/mojom/assistant.mojom index 321e6e8..f6d4799 100644 --- a/chromeos/services/assistant/public/mojom/assistant.mojom +++ b/chromeos/services/assistant/public/mojom/assistant.mojom
@@ -23,6 +23,12 @@ // |AssistantInteractionSubscriber| interface to registered subscribers. StartMetalayerInteraction(gfx.mojom.Rect region); + // Starts a new Assistant text interaction. If |allow_tts| is true, the + // result will contain TTS. Otherwise TTS will not be present in the + // generated server response. Results will be returned through registered + // |AssistantInteractionSubscriber|. + StartTextInteraction(string query, bool allow_tts); + // Starts a new Assistant voice interaction. StartVoiceInteraction(); @@ -31,10 +37,6 @@ // is a no-op. StopActiveInteraction(bool cancel_conversation); - // Send text query to assistant. Result will be returned through registered - // |AssistantInteractionSubscriber|. - SendTextQuery(string query); - // Registers assistant interaction event subscriber. Subscribers' // implementation is responsible for selecting events of interest. AddAssistantInteractionSubscriber(AssistantInteractionSubscriber subscriber);
diff --git a/chromeos/services/assistant/service.cc b/chromeos/services/assistant/service.cc index 211dc72c..0895eba4 100644 --- a/chromeos/services/assistant/service.cc +++ b/chromeos/services/assistant/service.cc
@@ -52,8 +52,10 @@ } // namespace -Service::Service(network::NetworkConnectionTracker* network_connection_tracker) - : platform_binding_(this), +Service::Service(service_manager::mojom::ServiceRequest request, + network::NetworkConnectionTracker* network_connection_tracker) + : service_binding_(this, std::move(request)), + platform_binding_(this), session_observer_binding_(this), token_refresh_timer_(std::make_unique<base::OneShotTimer>()), main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), @@ -211,14 +213,14 @@ mojom::DeviceActionsPtr device_actions) { client_ = std::move(client); device_actions_ = std::move(device_actions); - assistant_state_.Init(context()->connector()); + assistant_state_.Init(service_binding_.GetConnector()); assistant_state_.AddObserver(this); RequestAccessToken(); } identity::mojom::IdentityManager* Service::GetIdentityManager() { if (!identity_manager_) { - context()->connector()->BindInterface( + service_binding_.GetConnector()->BindInterface( identity::mojom::kServiceName, mojo::MakeRequest(&identity_manager_)); } return identity_manager_.get(); @@ -273,15 +275,15 @@ void Service::CreateAssistantManagerService() { #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) device::mojom::BatteryMonitorPtr battery_monitor; - context()->connector()->BindInterface(device::mojom::kServiceName, - mojo::MakeRequest(&battery_monitor)); + service_binding_.GetConnector()->BindInterface( + device::mojom::kServiceName, mojo::MakeRequest(&battery_monitor)); assistant_manager_service_ = std::make_unique<AssistantManagerServiceImpl>( - context()->connector(), std::move(battery_monitor), this, + service_binding_.GetConnector(), std::move(battery_monitor), this, network_connection_tracker_); // Bind to Assistant controller in ash. - context()->connector()->BindInterface(ash::mojom::kServiceName, - &assistant_controller_); + service_binding_.GetConnector()->BindInterface(ash::mojom::kServiceName, + &assistant_controller_); assistant_settings_manager_ = assistant_manager_service_.get()->GetAssistantSettingsManager(); #else @@ -322,8 +324,8 @@ void Service::AddAshSessionObserver() { ash::mojom::SessionControllerPtr session_controller; - context()->connector()->BindInterface(ash::mojom::kServiceName, - &session_controller); + service_binding_.GetConnector()->BindInterface(ash::mojom::kServiceName, + &session_controller); ash::mojom::SessionActivationObserverPtr observer; session_observer_binding_.Bind(mojo::MakeRequest(&observer)); session_controller->AddSessionActivationObserverForAccountId(
diff --git a/chromeos/services/assistant/service.h b/chromeos/services/assistant/service.h index 71fc441e..40e9329 100644 --- a/chromeos/services/assistant/service.h +++ b/chromeos/services/assistant/service.h
@@ -28,6 +28,8 @@ #include "services/identity/public/mojom/identity_manager.mojom.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/cpp/service_binding.h" +#include "services/service_manager/public/mojom/service.mojom.h" class GoogleServiceAuthError; @@ -51,8 +53,8 @@ public mojom::AssistantPlatform, public ash::DefaultVoiceInteractionObserver { public: - explicit Service( - network::NetworkConnectionTracker* network_connection_tracker); + Service(service_manager::mojom::ServiceRequest request, + network::NetworkConnectionTracker* network_connection_tracker); ~Service() override; mojom::Client* client() { return client_.get(); } @@ -123,6 +125,7 @@ void UpdateListeningState(); + service_manager::ServiceBinding service_binding_; service_manager::BinderRegistry registry_; mojo::BindingSet<mojom::Assistant> bindings_;
diff --git a/chromeos/services/assistant/service_unittest.cc b/chromeos/services/assistant/service_unittest.cc index fb65b9a..3c7308c 100644 --- a/chromeos/services/assistant/service_unittest.cc +++ b/chromeos/services/assistant/service_unittest.cc
@@ -17,10 +17,10 @@ #include "chromeos/dbus/fake_power_manager_client.h" #include "chromeos/services/assistant/fake_assistant_manager_service_impl.h" #include "chromeos/services/assistant/public/mojom/constants.mojom.h" +#include "chromeos/services/assistant/service.h" #include "services/identity/public/mojom/identity_manager.mojom.h" -#include "services/service_manager/public/cpp/service_context.h" -#include "services/service_manager/public/cpp/service_test.h" -#include "services/service_manager/public/mojom/service_factory.mojom.h" +#include "services/service_manager/public/cpp/service_binding.h" +#include "services/service_manager/public/cpp/test/test_connector_factory.h" #include "testing/gtest/include/gtest/gtest.h" namespace chromeos { @@ -149,119 +149,60 @@ DISALLOW_COPY_AND_ASSIGN(FakeDeviceActions); }; -class ServiceTestClient : public service_manager::test::ServiceTestClient, - public service_manager::mojom::ServiceFactory { +class AssistantServiceTest : public testing::Test { public: - ServiceTestClient(service_manager::test::ServiceTest* test, - FakeIdentityManager* fake_identity_manager, - FakeAssistantManagerServiceImpl* fake_assistant_manager_ptr, - base::TestMockTimeTaskRunner* mock_task_runner) - : service_manager::test::ServiceTestClient(test), - fake_identity_manager_(fake_identity_manager), - fake_assistant_manager_ptr_(fake_assistant_manager_ptr), - mock_task_runner_(mock_task_runner) { - registry_.AddInterface<service_manager::mojom::ServiceFactory>( - base::BindRepeating(&ServiceTestClient::Create, - base::Unretained(this))); - } - - protected: - void OnBindInterface(const service_manager::BindSourceInfo& source_info, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle interface_pipe) override { - registry_.BindInterface(interface_name, std::move(interface_pipe)); - } - - void CreateService( - service_manager::mojom::ServiceRequest request, - const std::string& name, - service_manager::mojom::PIDReceiverPtr pid_receiver) override { - if (name == mojom::kServiceName) { - auto service = std::make_unique<chromeos::assistant::Service>( - nullptr /* network_connection_tracker */); - - auto mock_timer = std::make_unique<base::OneShotTimer>( - mock_task_runner_->GetMockTickClock()); - mock_timer->SetTaskRunner(mock_task_runner_); - service->SetTimerForTesting(std::move(mock_timer)); - - service->SetIdentityManagerForTesting( - fake_identity_manager_->CreateInterfacePtrAndBind()); - service->SetAssistantManagerForTesting( - base::WrapUnique(fake_assistant_manager_ptr_)); - - service_context_ = std::make_unique<service_manager::ServiceContext>( - std::move(service), std::move(request)); - } - } - - void Create(service_manager::mojom::ServiceFactoryRequest request) { - service_factory_bindings_.AddBinding(this, std::move(request)); - } - - private: - service_manager::BinderRegistry registry_; - mojo::BindingSet<service_manager::mojom::ServiceFactory> - service_factory_bindings_; - - FakeIdentityManager* fake_identity_manager_; - FakeAssistantManagerServiceImpl* fake_assistant_manager_ptr_; - base::TestMockTimeTaskRunner* mock_task_runner_; - - std::unique_ptr<service_manager::ServiceContext> service_context_; - DISALLOW_COPY_AND_ASSIGN(ServiceTestClient); -}; - -class ServiceTest : public service_manager::test::ServiceTest { - public: - ServiceTest() : service_manager::test::ServiceTest("assistant_unittests") {} - - void SetUp() override { - service_manager::test::ServiceTest::SetUp(); - - GetService()->Init(fake_assistant_client_->CreateInterfacePtrAndBind(), - fake_device_actions_->CreateInterfacePtrAndBind()); - platform_service_.FlushForTesting(); - base::RunLoop().RunUntilIdle(); - } - - // service_manager::test::ServiceTest: - std::unique_ptr<service_manager::Service> CreateService() override { - fake_identity_manager_ = std::make_unique<FakeIdentityManager>(); - fake_assistant_client_ = std::make_unique<FakeAssistantClient>(); - fake_device_actions_ = std::make_unique<FakeDeviceActions>(); - fake_assistant_manager_ptr_ = new FakeAssistantManagerServiceImpl(); - - std::unique_ptr<chromeos::DBusThreadManagerSetter> dbus_setter = - chromeos::DBusThreadManager::GetSetterForTesting(); + AssistantServiceTest() + : connector_(test_connector_factory_.CreateConnector()) { + // The assistant service may attempt to connect to a number of services + // which are irrelevant for these tests. + test_connector_factory_.set_ignore_unknown_service_requests(true); auto power_manager_client = std::make_unique<chromeos::FakePowerManagerClient>(); power_manager_client->SetTabletMode( chromeos::PowerManagerClient::TabletMode::OFF, base::TimeTicks()); power_manager_client_ = power_manager_client.get(); + + auto dbus_setter = chromeos::DBusThreadManager::GetSetterForTesting(); dbus_setter->SetPowerManagerClient(std::move(power_manager_client)); + service_ = std::make_unique<Service>( + test_connector_factory_.RegisterInstance(mojom::kServiceName), + nullptr /* network_connection_tracker */); + mock_task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>( base::Time::Now(), base::TimeTicks::Now()); + auto mock_timer = std::make_unique<base::OneShotTimer>( + mock_task_runner_->GetMockTickClock()); + mock_timer->SetTaskRunner(mock_task_runner_); + service_->SetTimerForTesting(std::move(mock_timer)); - return std::make_unique<ServiceTestClient>(this, identity_manager(), - assistant_manager_service(), - mock_task_runner()); + service_->SetIdentityManagerForTesting( + fake_identity_manager_.CreateInterfacePtrAndBind()); + + auto fake_assistant_manager = + std::make_unique<FakeAssistantManagerServiceImpl>(); + fake_assistant_manager_ = fake_assistant_manager.get(); + service_->SetAssistantManagerForTesting(std::move(fake_assistant_manager)); } - mojom::AssistantPlatform* GetService() { - if (!platform_service_) - connector()->BindInterface(mojom::kServiceName, &platform_service_); - return platform_service_.get(); + void SetUp() override { + GetPlatform()->Init(fake_assistant_client_.CreateInterfacePtrAndBind(), + fake_device_actions_.CreateInterfacePtrAndBind()); + platform_.FlushForTesting(); + base::RunLoop().RunUntilIdle(); } - FakeIdentityManager* identity_manager() { - return fake_identity_manager_.get(); + mojom::AssistantPlatform* GetPlatform() { + if (!platform_) + connector_->BindInterface(mojom::kServiceName, &platform_); + return platform_.get(); } + FakeIdentityManager* identity_manager() { return &fake_identity_manager_; } + FakeAssistantManagerServiceImpl* assistant_manager_service() { - return fake_assistant_manager_ptr_; + return fake_assistant_manager_; } chromeos::FakePowerManagerClient* power_manager_client() { @@ -273,24 +214,27 @@ } private: - mojom::AssistantPlatformPtr platform_service_; + base::test::ScopedTaskEnvironment task_environment_; + service_manager::TestConnectorFactory test_connector_factory_; + std::unique_ptr<service_manager::Connector> connector_; - std::unique_ptr<FakeIdentityManager> fake_identity_manager_; - std::unique_ptr<FakeAssistantClient> fake_assistant_client_; + std::unique_ptr<chromeos::assistant::Service> service_; + mojom::AssistantPlatformPtr platform_; - std::unique_ptr<FakeDeviceActions> fake_device_actions_; + FakeIdentityManager fake_identity_manager_; + FakeAssistantClient fake_assistant_client_; + FakeDeviceActions fake_device_actions_; - FakeAssistantManagerServiceImpl* fake_assistant_manager_ptr_; - + FakeAssistantManagerServiceImpl* fake_assistant_manager_; chromeos::FakePowerManagerClient* power_manager_client_; scoped_refptr<base::TestMockTimeTaskRunner> mock_task_runner_; std::unique_ptr<base::OneShotTimer> mock_timer_; - DISALLOW_COPY_AND_ASSIGN(ServiceTest); + DISALLOW_COPY_AND_ASSIGN(AssistantServiceTest); }; -TEST_F(ServiceTest, RefreshTokenAfterExpire) { +TEST_F(AssistantServiceTest, RefreshTokenAfterExpire) { auto current_count = identity_manager()->get_access_token_count(); mock_task_runner()->FastForwardBy(kDefaultTokenExpirationDelay / 2); base::RunLoop().RunUntilIdle(); @@ -305,7 +249,7 @@ EXPECT_EQ(identity_manager()->get_access_token_count(), ++current_count); } -TEST_F(ServiceTest, RetryRefreshTokenAfterFailure) { +TEST_F(AssistantServiceTest, RetryRefreshTokenAfterFailure) { auto current_count = identity_manager()->get_access_token_count(); identity_manager()->SetShouldFail(true); mock_task_runner()->FastForwardBy(kDefaultTokenExpirationDelay); @@ -325,7 +269,7 @@ EXPECT_EQ(identity_manager()->get_access_token_count(), ++current_count); } -TEST_F(ServiceTest, RetryRefreshTokenAfterDeviceWakeup) { +TEST_F(AssistantServiceTest, RetryRefreshTokenAfterDeviceWakeup) { auto current_count = identity_manager()->get_access_token_count(); power_manager_client()->SendSuspendDone(); base::RunLoop().RunUntilIdle();
diff --git a/chromeos/services/assistant/test_support/mock_assistant.h b/chromeos/services/assistant/test_support/mock_assistant.h index 673dddf..f27b4aee 100644 --- a/chromeos/services/assistant/test_support/mock_assistant.h +++ b/chromeos/services/assistant/test_support/mock_assistant.h
@@ -25,12 +25,12 @@ MOCK_METHOD1(StartMetalayerInteraction, void(const gfx::Rect&)); + MOCK_METHOD2(StartTextInteraction, void(const std::string&, bool)); + MOCK_METHOD0(StartVoiceInteraction, void()); MOCK_METHOD1(StopActiveInteraction, void(bool)); - MOCK_METHOD1(SendTextQuery, void(const std::string&)); - MOCK_METHOD1( AddAssistantInteractionSubscriber, void(chromeos::assistant::mojom::AssistantInteractionSubscriberPtr));
diff --git a/chromeos/services/assistant/unittest_manifest.json b/chromeos/services/assistant/unittest_manifest.json deleted file mode 100644 index d9b1e22..0000000 --- a/chromeos/services/assistant/unittest_manifest.json +++ /dev/null
@@ -1,18 +0,0 @@ -{ - "name": "assistant_unittests", - "display_name": "Assistant Unittests", - "interface_provider_specs": { - "service_manager:connector": { - "provides": { - "service_manager:service_factory": [ - "service_manager.mojom.ServiceFactory" - ] - }, - "requires": { - "assistant": [ - "assistant" - ] - } - } - } -}
diff --git a/chromeos/services/ime/BUILD.gn b/chromeos/services/ime/BUILD.gn index e170d6c..bb43f7d4 100644 --- a/chromeos/services/ime/BUILD.gn +++ b/chromeos/services/ime/BUILD.gn
@@ -3,8 +3,6 @@ # found in the LICENSE file. import("//chromeos/services/ime/public/features.gni") -import("//services/catalog/public/tools/catalog.gni") -import("//services/service_manager/public/cpp/service.gni") import("//services/service_manager/public/service_manifest.gni") assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos") @@ -51,24 +49,15 @@ deps = [ ":lib", "//base", + "//base/test:test_support", "//chromeos/services/ime/public/mojom", "//mojo/public/cpp/bindings", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp:service_test_support", + "//services/service_manager/public/cpp/test:test_support", "//testing/gmock", + "//testing/gtest", ] sources = [ "ime_service_unittest.cc", ] } - -service_manifest("unittest_manifest") { - name = "ime_unittests" - source = "test_manifest.json" - packaged_services = [ ":manifest" ] -} - -catalog("tests_catalog") { - testonly = true - embedded_services = [ ":unittest_manifest" ] -}
diff --git a/chromeos/services/ime/OWNERS b/chromeos/services/ime/OWNERS index 36d24774..404ff91 100644 --- a/chromeos/services/ime/OWNERS +++ b/chromeos/services/ime/OWNERS
@@ -3,6 +3,3 @@ per-file manifest.json=set noparent per-file manifest.json=file://ipc/SECURITY_OWNERS - -per-file test_manifest.json=set noparent -per-file test_manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/chromeos/services/ime/ime_service.cc b/chromeos/services/ime/ime_service.cc index ce08f4dc..6efbc675 100644 --- a/chromeos/services/ime/ime_service.cc +++ b/chromeos/services/ime/ime_service.cc
@@ -10,19 +10,15 @@ #if BUILDFLAG(ENABLE_CROS_IME_DECODER) #include "chromeos/services/ime/decoder/decoder_engine.h" -#include "services/service_manager/public/cpp/service_context.h" #endif namespace chromeos { namespace ime { -std::unique_ptr<service_manager::Service> CreateImeService() { - return std::make_unique<ImeService>(); -} +ImeService::ImeService(service_manager::mojom::ServiceRequest request) + : service_binding_(this, std::move(request)) {} -ImeService::ImeService() {} - -ImeService::~ImeService() {} +ImeService::~ImeService() = default; void ImeService::OnStart() { binder_registry_.AddInterface<mojom::InputEngineManager>(base::BindRepeating( @@ -33,7 +29,7 @@ #if BUILDFLAG(ENABLE_CROS_IME_DECODER) input_engine_ = std::make_unique<DecoderEngine>( - context()->connector(), base::SequencedTaskRunnerHandle::Get()); + service_binding_.GetConnector(), base::SequencedTaskRunnerHandle::Get()); #else input_engine_ = std::make_unique<InputEngine>(); #endif
diff --git a/chromeos/services/ime/ime_service.h b/chromeos/services/ime/ime_service.h index efdfbf9..c8a5a86 100644 --- a/chromeos/services/ime/ime_service.h +++ b/chromeos/services/ime/ime_service.h
@@ -10,16 +10,16 @@ #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/cpp/service_binding.h" +#include "services/service_manager/public/mojom/service.mojom.h" namespace chromeos { namespace ime { -std::unique_ptr<service_manager::Service> CreateImeService(); - class ImeService : public service_manager::Service, public mojom::InputEngineManager { public: - ImeService(); + explicit ImeService(service_manager::mojom::ServiceRequest request); ~ImeService() override; private: @@ -41,6 +41,8 @@ void OnConnectionLost(); + service_manager::ServiceBinding service_binding_; + // For the duration of this service lifetime, there should be only one // input engine instance. std::unique_ptr<InputEngine> input_engine_;
diff --git a/chromeos/services/ime/ime_service_unittest.cc b/chromeos/services/ime/ime_service_unittest.cc index 3f47e2d..ac775d0 100644 --- a/chromeos/services/ime/ime_service_unittest.cc +++ b/chromeos/services/ime/ime_service_unittest.cc
@@ -2,20 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chromeos/services/ime/ime_service.h" #include "base/bind.h" #include "base/strings/utf_string_conversions.h" - -#include "chromeos/services/ime/ime_service.h" +#include "base/test/scoped_task_environment.h" #include "chromeos/services/ime/public/mojom/constants.mojom.h" #include "chromeos/services/ime/public/mojom/input_engine.mojom.h" - #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/interface_request.h" -#include "services/service_manager/public/cpp/service_context.h" -#include "services/service_manager/public/cpp/service_test.h" +#include "services/service_manager/public/cpp/service_binding.h" +#include "services/service_manager/public/cpp/test/test_connector_factory.h" #include "services/service_manager/public/mojom/service_factory.mojom.h" #include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" using testing::_; @@ -23,7 +23,7 @@ namespace ime { namespace { -const char kTestServiceName[] = "ime_unittests"; + const char kInvalidImeSpec[] = "ime_spec_never_support"; const std::vector<uint8_t> extra{0x66, 0x77, 0x88}; @@ -58,78 +58,33 @@ DISALLOW_COPY_AND_ASSIGN(TestClientChannel); }; -class ImeServiceTestClient : public service_manager::test::ServiceTestClient, - public service_manager::mojom::ServiceFactory { +class ImeServiceTest : public testing::Test { public: - ImeServiceTestClient(service_manager::test::ServiceTest* test) - : service_manager::test::ServiceTestClient(test) { - registry_.AddInterface<service_manager::mojom::ServiceFactory>( - base::BindRepeating(&ImeServiceTestClient::Create, - base::Unretained(this))); - } - - protected: - void OnBindInterface(const service_manager::BindSourceInfo& source_info, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle interface_pipe) override { - registry_.BindInterface(interface_name, std::move(interface_pipe)); - } - - // service_manager::mojom::ServiceFactory - void CreateService( - service_manager::mojom::ServiceRequest request, - const std::string& name, - service_manager::mojom::PIDReceiverPtr pid_receiver) override { - if (name == mojom::kServiceName) { - service_context_.reset(new service_manager::ServiceContext( - CreateImeService(), std::move(request))); - } - } - - void Create(service_manager::mojom::ServiceFactoryRequest request) { - service_factory_bindings_.AddBinding(this, std::move(request)); - } - - private: - service_manager::BinderRegistry registry_; - mojo::BindingSet<service_manager::mojom::ServiceFactory> - service_factory_bindings_; - - std::unique_ptr<service_manager::ServiceContext> service_context_; - DISALLOW_COPY_AND_ASSIGN(ImeServiceTestClient); -}; - -class ImeServiceTest : public service_manager::test::ServiceTest { - public: - ImeServiceTest() : service_manager::test::ServiceTest(kTestServiceName) {} - ~ImeServiceTest() override {} + ImeServiceTest() + : service_(test_connector_factory_.RegisterInstance(mojom::kServiceName)), + connector_(test_connector_factory_.CreateConnector()) {} + ~ImeServiceTest() override = default; MOCK_METHOD1(SentTextCallback, void(const std::string&)); MOCK_METHOD1(SentMessageCallback, void(const std::vector<uint8_t>&)); protected: void SetUp() override { - ServiceTest::SetUp(); - connector()->BindInterface(mojom::kServiceName, - mojo::MakeRequest(&ime_manager_)); + connector_->BindInterface(mojom::kServiceName, + mojo::MakeRequest(&ime_manager_)); // TODO(https://crbug.com/837156): Start or bind other services used. // Eg. connector()->StartService(mojom::kSomeServiceName); } - // service_manager::test::ServiceTest - std::unique_ptr<service_manager::Service> CreateService() override { - return std::make_unique<ImeServiceTestClient>(this); - } - - void TearDown() override { - ime_manager_.reset(); - ServiceTest::TearDown(); - } - mojom::InputEngineManagerPtr ime_manager_; private: + base::test::ScopedTaskEnvironment task_environment_; + service_manager::TestConnectorFactory test_connector_factory_; + ImeService service_; + std::unique_ptr<service_manager::Connector> connector_; + DISALLOW_COPY_AND_ASSIGN(ImeServiceTest); };
diff --git a/chromeos/services/ime/input_engine.cc b/chromeos/services/ime/input_engine.cc index bbccd8c..008f412 100644 --- a/chromeos/services/ime/input_engine.cc +++ b/chromeos/services/ime/input_engine.cc
@@ -5,6 +5,7 @@ #include "chromeos/services/ime/input_engine.h" #include "base/json/json_reader.h" +#include "base/json/string_escape.h" #include "base/logging.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -152,8 +153,10 @@ response_str += (res.key_handled ? "true" : "false"); std::vector<std::string> ops; if (!res.commit_text.empty()) { - ops.push_back("{\"method\":\"commitText\",\"arguments\":[\"" + - res.commit_text + "\"]}"); + std::string commit_text; + base::EscapeJSONString(res.commit_text, false, &commit_text); + ops.push_back("{\"method\":\"commitText\",\"arguments\":[\"" + commit_text + + "\"]}"); } // Need to add the setComposition operation to the result when the key is // handled and commit_text and composition_text are both empty. @@ -161,8 +164,10 @@ // composition. if (!res.composition_text.empty() || (res.key_handled && res.commit_text.empty())) { + std::string composition_text; + base::EscapeJSONString(res.composition_text, false, &composition_text); ops.push_back("{\"method\":\"setComposition\",\"arguments\":[\"" + - res.composition_text + "\"]}"); + composition_text + "\"]}"); } if (ops.empty()) { response_str += "}";
diff --git a/chromeos/services/ime/public/cpp/rulebased/rules_data.cc b/chromeos/services/ime/public/cpp/rulebased/rules_data.cc index 74745208..6b21fe21 100644 --- a/chromeos/services/ime/public/cpp/rulebased/rules_data.cc +++ b/chromeos/services/ime/public/cpp/rulebased/rules_data.cc
@@ -162,7 +162,7 @@ static const char* k101Keys[] = { // Row #1 - "BackQuote", "Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6", + "Backquote", "Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6", "Digit7", "Digit8", "Digit9", "Digit0", "Minus", "Equal", // Row #2 "KeyQ", "KeyW", "KeyE", "KeyR", "KeyT", "KeyY", "KeyU", "KeyI", "KeyO", @@ -178,7 +178,7 @@ static const char* k102Keys[] = { // Row #1 - "BackQuote", "Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6", + "Backquote", "Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6", "Digit7", "Digit8", "Digit9", "Digit0", "Minus", "Equal", // Row #2 "KeyQ", "KeyW", "KeyE", "KeyR", "KeyT", "KeyY", "KeyU", "KeyI", "KeyO",
diff --git a/chromeos/services/ime/test_manifest.json b/chromeos/services/ime/test_manifest.json deleted file mode 100644 index b387433e..0000000 --- a/chromeos/services/ime/test_manifest.json +++ /dev/null
@@ -1,16 +0,0 @@ -{ - "name": "ime_unittests", - "display_name": "IME Unittests", - "interface_provider_specs": { - "service_manager:connector": { - "provides": { - "service_manager:service_factory": [ - "service_manager.mojom.ServiceFactory" - ] - }, - "requires": { - "ime": [ "input_engine" ] - } - } - } -}
diff --git a/chromeos/services/secure_channel/ble_connection_manager_impl.cc b/chromeos/services/secure_channel/ble_connection_manager_impl.cc index d55e1596..17e75fc 100644 --- a/chromeos/services/secure_channel/ble_connection_manager_impl.cc +++ b/chromeos/services/secure_channel/ble_connection_manager_impl.cc
@@ -4,6 +4,8 @@ #include "chromeos/services/secure_channel/ble_connection_manager_impl.h" +#include <utility> + #include "base/memory/ptr_util.h" #include "base/no_destructor.h" #include "base/stl_util.h" @@ -15,6 +17,7 @@ #include "chromeos/services/secure_channel/ble_listener_failure_type.h" #include "chromeos/services/secure_channel/ble_scanner_impl.h" #include "chromeos/services/secure_channel/ble_synchronizer.h" +#include "chromeos/services/secure_channel/latency_metrics_logger.h" #include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h" #include "chromeos/services/secure_channel/secure_channel_disconnector_impl.h" #include "components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h" @@ -73,17 +76,93 @@ BleConnectionManagerImpl::Factory::BuildInstance( scoped_refptr<device::BluetoothAdapter> bluetooth_adapter, BleServiceDataHelper* ble_service_data_helper, - TimerFactory* timer_factory) { + TimerFactory* timer_factory, + base::Clock* clock) { return base::WrapUnique(new BleConnectionManagerImpl( - bluetooth_adapter, ble_service_data_helper, timer_factory)); + bluetooth_adapter, ble_service_data_helper, timer_factory, clock)); +} + +BleConnectionManagerImpl::ConnectionAttemptTimestamps:: + ConnectionAttemptTimestamps(ConnectionRole connection_role, + base::Clock* clock) + : connection_role_(connection_role), + clock_(clock), + start_scan_timestamp_(clock_->Now()) {} + +BleConnectionManagerImpl::ConnectionAttemptTimestamps:: + ~ConnectionAttemptTimestamps() = default; + +void BleConnectionManagerImpl::ConnectionAttemptTimestamps:: + RecordAdvertisementReceived() { + DCHECK(!start_scan_timestamp_.is_null()); + + if (!advertisement_received_timestamp_.is_null()) + return; + advertisement_received_timestamp_ = clock_->Now(); + + if (connection_role_ == ConnectionRole::kListenerRole) { + LogLatencyMetric( + "MultiDevice.SecureChannel.BLE.Performance." + "StartScanToReceiveAdvertisementDuration.Background", + advertisement_received_timestamp_ - start_scan_timestamp_); + } +} + +void BleConnectionManagerImpl::ConnectionAttemptTimestamps:: + RecordGattConnectionEstablished() { + DCHECK(!start_scan_timestamp_.is_null()); + DCHECK(!advertisement_received_timestamp_.is_null()); + + if (!gatt_connection_timestamp_.is_null()) + return; + gatt_connection_timestamp_ = clock_->Now(); + + if (connection_role_ == ConnectionRole::kListenerRole) { + LogLatencyMetric( + "MultiDevice.SecureChannel.BLE.Performance." + "ReceiveAdvertisementToConnectionDuration.Background", + gatt_connection_timestamp_ - advertisement_received_timestamp_); + LogLatencyMetric( + "MultiDevice.SecureChannel.BLE.Performance." + "StartScanToConnectionDuration.Background", + gatt_connection_timestamp_ - start_scan_timestamp_); + } +} + +void BleConnectionManagerImpl::ConnectionAttemptTimestamps:: + RecordChannelAuthenticated() { + DCHECK(!start_scan_timestamp_.is_null()); + DCHECK(!advertisement_received_timestamp_.is_null()); + DCHECK(!gatt_connection_timestamp_.is_null()); + + if (!authentication_timestamp_.is_null()) + return; + authentication_timestamp_ = clock_->Now(); + + if (connection_role_ == ConnectionRole::kListenerRole) { + LogLatencyMetric( + "MultiDevice.SecureChannel.BLE.Performance." + "ConnectionToAuthenticationDuration.Background", + clock_->Now() - gatt_connection_timestamp_); + } +} + +void BleConnectionManagerImpl::ConnectionAttemptTimestamps::Reset() { + start_scan_timestamp_ = clock_->Now(); + + advertisement_received_timestamp_ = base::Time(); + gatt_connection_timestamp_ = base::Time(); + authentication_timestamp_ = base::Time(); } BleConnectionManagerImpl::BleConnectionManagerImpl( scoped_refptr<device::BluetoothAdapter> bluetooth_adapter, BleServiceDataHelper* ble_service_data_helper, - TimerFactory* timer_factory) + TimerFactory* timer_factory, + base::Clock* clock) : bluetooth_adapter_(bluetooth_adapter), ble_service_data_helper_(ble_service_data_helper), + clock_(clock), ble_synchronizer_( BleSynchronizer::Factory::Get()->BuildInstance(bluetooth_adapter)), ble_advertiser_(BleAdvertiserImpl::Factory::Get()->BuildInstance( @@ -107,6 +186,9 @@ if (DoesAuthenticatingChannelExist(device_id_pair.remote_device_id())) return; + StartConnectionAttemptTimerMetricsIfNecessary( + device_id_pair.remote_device_id(), ConnectionRole::kInitiatorRole); + ble_advertiser_->AddAdvertisementRequest(device_id_pair, connection_priority); ble_scanner_->AddScanFilter( BleScanner::ScanFilter(device_id_pair, ConnectionRole::kInitiatorRole)); @@ -124,6 +206,9 @@ void BleConnectionManagerImpl::PerformCancelBleInitiatorConnectionAttempt( const DeviceIdPair& device_id_pair) { + RemoveConnectionAttemptTimerMetricsIfNecessary( + device_id_pair.remote_device_id()); + if (DoesAuthenticatingChannelExist(device_id_pair.remote_device_id())) { // Check to see if we are removing the final request for an active channel; // if so, that channel needs to be disconnected. @@ -147,6 +232,9 @@ if (DoesAuthenticatingChannelExist(device_id_pair.remote_device_id())) return; + StartConnectionAttemptTimerMetricsIfNecessary( + device_id_pair.remote_device_id(), ConnectionRole::kListenerRole); + ble_scanner_->AddScanFilter( BleScanner::ScanFilter(device_id_pair, ConnectionRole::kListenerRole)); } @@ -159,6 +247,9 @@ void BleConnectionManagerImpl::PerformCancelBleListenerConnectionAttempt( const DeviceIdPair& device_id_pair) { + RemoveConnectionAttemptTimerMetricsIfNecessary( + device_id_pair.remote_device_id()); + if (DoesAuthenticatingChannelExist(device_id_pair.remote_device_id())) { // Check to see if we are removing the final request for an active channel; // if so, that channel needs to be disconnected. @@ -196,6 +287,9 @@ cryptauth::RemoteDeviceRef remote_device, device::BluetoothDevice* bluetooth_device, ConnectionRole connection_role) { + remote_device_id_to_timestamps_map_[remote_device.GetDeviceId()] + ->RecordAdvertisementReceived(); + // Create a connection to the device. std::unique_ptr<cryptauth::Connection> connection = cryptauth::weave::BluetoothLowEnergyWeaveClientConnection::Factory:: @@ -224,6 +318,11 @@ return; } + if (new_status == cryptauth::SecureChannel::Status::CONNECTED) { + remote_device_id_to_timestamps_map_[remote_device_id] + ->RecordGattConnectionEstablished(); + } + if (new_status == cryptauth::SecureChannel::Status::AUTHENTICATED) { HandleChannelAuthenticated(remote_device_id); return; @@ -246,8 +345,7 @@ // connections to the same device can interfere with each other. PauseConnectionAttemptsToDevice(remote_device_id); - if (base::ContainsKey(remote_device_id_to_secure_channel_map_, - remote_device_id)) { + if (DoesAuthenticatingChannelExist(remote_device_id)) { PA_LOG(ERROR) << "BleConnectionManager::OnReceivedAdvertisement(): A new " << "channel was created, one already exists for the same " << "remote device ID. ID: " @@ -310,10 +408,8 @@ const std::string& remote_device_id) { // If there was no authenticating SecureChannel associated with // |remote_device_id|, return early. - if (!base::ContainsKey(remote_device_id_to_secure_channel_map_, - remote_device_id)) { + if (!DoesAuthenticatingChannelExist(remote_device_id)) return; - } // If there is at least one active request, the channel should remain active. if (!GetDetailsForRemoteDevice(remote_device_id).empty()) @@ -352,6 +448,10 @@ void BleConnectionManagerImpl::HandleSecureChannelDisconnection( const std::string& remote_device_id, bool was_authenticating) { + // Since the channel has disconnected, the timestamps used to track the + // connection's latency should be reset and started anew. + remote_device_id_to_timestamps_map_[remote_device_id]->Reset(); + for (const auto& details : GetDetailsForRemoteDevice(remote_device_id)) { switch (details.connection_role()) { // Initiator role devices are notified of authentication errors as well as @@ -374,7 +474,7 @@ } } - // Stop observer the disconnected channel and remove it from the map. + // Stop observing the disconnected channel and remove it from the map. remote_device_id_to_secure_channel_map_[remote_device_id] .first->RemoveObserver(this); remote_device_id_to_secure_channel_map_.erase(remote_device_id); @@ -388,6 +488,10 @@ void BleConnectionManagerImpl::HandleChannelAuthenticated( const std::string& remote_device_id) { + remote_device_id_to_timestamps_map_[remote_device_id] + ->RecordChannelAuthenticated(); + remote_device_id_to_timestamps_map_.erase(remote_device_id); + // Extract the map value and remove the entry from the map. SecureChannelWithRole channel_with_role = std::move(remote_device_id_to_secure_channel_map_[remote_device_id]); @@ -445,6 +549,28 @@ ConnectionRole::kInitiatorRole); } +void BleConnectionManagerImpl::StartConnectionAttemptTimerMetricsIfNecessary( + const std::string& remote_device_id, + ConnectionRole connection_role) { + // If an entry already exists, there is nothing to do. This is expected if + // more than one client is attempting a connection to the same device. + if (base::ContainsKey(remote_device_id_to_timestamps_map_, remote_device_id)) + return; + + remote_device_id_to_timestamps_map_[remote_device_id] = + std::make_unique<ConnectionAttemptTimestamps>(connection_role, clock_); +} + +void BleConnectionManagerImpl::RemoveConnectionAttemptTimerMetricsIfNecessary( + const std::string& remote_device_id) { + // If there is at least one active request, latency metrics should continue + // tracking the connection attempt. + if (!GetDetailsForRemoteDevice(remote_device_id).empty()) + return; + + remote_device_id_to_timestamps_map_.erase(remote_device_id); +} + } // namespace secure_channel } // namespace chromeos
diff --git a/chromeos/services/secure_channel/ble_connection_manager_impl.h b/chromeos/services/secure_channel/ble_connection_manager_impl.h index 5fa3fa04..2d7a1df 100644 --- a/chromeos/services/secure_channel/ble_connection_manager_impl.h +++ b/chromeos/services/secure_channel/ble_connection_manager_impl.h
@@ -11,6 +11,7 @@ #include "base/containers/flat_map.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/time/default_clock.h" #include "chromeos/services/secure_channel/ble_advertiser.h" #include "chromeos/services/secure_channel/ble_connection_manager.h" #include "chromeos/services/secure_channel/ble_scanner.h" @@ -51,7 +52,8 @@ virtual std::unique_ptr<BleConnectionManager> BuildInstance( scoped_refptr<device::BluetoothAdapter> bluetooth_adapter, BleServiceDataHelper* ble_service_data_helper, - TimerFactory* timer_factory); + TimerFactory* timer_factory, + base::Clock* clock = base::DefaultClock::GetInstance()); private: static Factory* test_factory_; @@ -60,10 +62,35 @@ ~BleConnectionManagerImpl() override; private: + class ConnectionAttemptTimestamps { + public: + ConnectionAttemptTimestamps(ConnectionRole connection_role, + base::Clock* clock); + ~ConnectionAttemptTimestamps(); + + void RecordAdvertisementReceived(); + void RecordGattConnectionEstablished(); + void RecordChannelAuthenticated(); + + // Resets the connection attempt metrics by resetting the "start + // scan" timestamp and resetting the other timestamps. + void Reset(); + + private: + const ConnectionRole connection_role_; + base::Clock* clock_; + + base::Time start_scan_timestamp_; + base::Time advertisement_received_timestamp_; + base::Time gatt_connection_timestamp_; + base::Time authentication_timestamp_; + }; + BleConnectionManagerImpl( scoped_refptr<device::BluetoothAdapter> bluetooth_adapter, BleServiceDataHelper* ble_service_data_helper, - TimerFactory* timer_factory); + TimerFactory* timer_factory, + base::Clock* clock); // BleConnectionManager: void PerformAttemptBleInitiatorConnection( @@ -145,8 +172,20 @@ const std::string& remote_device_id, ConnectionRole connection_role); + // Starts tracking a connection attempt's duration. If a connection to + // |remote_device_id| is already in progress, this function is a no-op. + void StartConnectionAttemptTimerMetricsIfNecessary( + const std::string& remote_device_id, + ConnectionRole connection_role); + + // Removes tracking for a connection attempt's duration if there are no + // remaining requests for the connection. + void RemoveConnectionAttemptTimerMetricsIfNecessary( + const std::string& remote_device_id); + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_; BleServiceDataHelper* ble_service_data_helper_; + base::Clock* clock_; std::unique_ptr<BleSynchronizerBase> ble_synchronizer_; std::unique_ptr<BleAdvertiser> ble_advertiser_; @@ -157,6 +196,8 @@ std::pair<std::unique_ptr<cryptauth::SecureChannel>, ConnectionRole>; base::flat_map<std::string, SecureChannelWithRole> remote_device_id_to_secure_channel_map_; + base::flat_map<std::string, std::unique_ptr<ConnectionAttemptTimestamps>> + remote_device_id_to_timestamps_map_; base::Optional<std::string> notifying_remote_device_id_; DISALLOW_COPY_AND_ASSIGN(BleConnectionManagerImpl);
diff --git a/chromeos/services/secure_channel/ble_connection_manager_impl_unittest.cc b/chromeos/services/secure_channel/ble_connection_manager_impl_unittest.cc index 433bb49..9acbb71 100644 --- a/chromeos/services/secure_channel/ble_connection_manager_impl_unittest.cc +++ b/chromeos/services/secure_channel/ble_connection_manager_impl_unittest.cc
@@ -13,7 +13,9 @@ #include "base/containers/flat_set.h" #include "base/macros.h" #include "base/task/post_task.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_task_environment.h" +#include "base/test/simple_test_clock.h" #include "chromeos/services/secure_channel/authenticated_channel_impl.h" #include "chromeos/services/secure_channel/ble_advertiser_impl.h" #include "chromeos/services/secure_channel/ble_constants.h" @@ -47,6 +49,13 @@ const size_t kNumTestDevices = 5; +constexpr base::TimeDelta kScanToAdvertisementTime = + base::TimeDelta::FromSeconds(3); +constexpr base::TimeDelta kAdvertisementToConnectionTime = + base::TimeDelta::FromSeconds(2); +constexpr base::TimeDelta kConnectionToAuthenticationTime = + base::TimeDelta::FromSeconds(1); + class FakeBleSynchronizerFactory : public BleSynchronizer::Factory { public: FakeBleSynchronizerFactory( @@ -336,6 +345,9 @@ fake_timer_factory_ = std::make_unique<FakeTimerFactory>(); + test_clock_ = std::make_unique<base::SimpleTestClock>(); + test_clock_->SetNow(base::Time::UnixEpoch()); + fake_ble_synchronizer_factory_ = std::make_unique<FakeBleSynchronizerFactory>(mock_adapter_); BleSynchronizer::Factory::SetFactoryForTesting( @@ -375,7 +387,7 @@ manager_ = BleConnectionManagerImpl::Factory::Get()->BuildInstance( mock_adapter_, fake_ble_service_data_helper_.get(), - fake_timer_factory_.get()); + fake_timer_factory_.get(), test_clock_.get()); } void TearDown() override { @@ -647,10 +659,13 @@ size_t num_success_callbacks_before_call = successful_connections_.size(); + test_clock()->Advance(kAdvertisementToConnectionTime); fake_secure_channel->ChangeStatus( cryptauth::SecureChannel::Status::CONNECTED); fake_secure_channel->ChangeStatus( cryptauth::SecureChannel::Status::AUTHENTICATING); + + test_clock()->Advance(kConnectionToAuthenticationTime); fake_secure_channel->ChangeStatus( cryptauth::SecureChannel::Status::AUTHENTICATED); @@ -690,6 +705,10 @@ base::test::ScopedTaskEnvironment scoped_task_environment_; const cryptauth::RemoteDeviceRefList& test_devices() { return test_devices_; } + base::SimpleTestClock* test_clock() { return test_clock_.get(); } + + base::HistogramTester* histogram_tester() { return &histogram_tester_; } + private: void OnConnectionSuccess( const DeviceIdPair& device_id_pair, @@ -815,6 +834,8 @@ const cryptauth::RemoteDeviceRefList test_devices_; + base::HistogramTester histogram_tester_; + base::flat_map< std::string, base::flat_set< @@ -842,6 +863,7 @@ scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>> mock_adapter_; std::unique_ptr<FakeBleServiceDataHelper> fake_ble_service_data_helper_; std::unique_ptr<FakeTimerFactory> fake_timer_factory_; + std::unique_ptr<base::SimpleTestClock> test_clock_; std::unique_ptr<BleConnectionManager> manager_; @@ -1277,6 +1299,41 @@ EXPECT_TRUE(WasChannelHandledByDisconnector(fake_secure_channel)); } +TEST_F(SecureChannelBleConnectionManagerImplTest, ConnectionTimestamps) { + DeviceIdPair pair(test_devices()[1].GetDeviceId(), + test_devices()[0].GetDeviceId()); + + AttemptBleListenerConnection(pair, ConnectionPriority::kLow, + true /* expected_to_add_request */); + + test_clock()->Advance(kScanToAdvertisementTime); + + cryptauth::FakeSecureChannel* fake_secure_channel = + SimulateConnectionEstablished(test_devices()[1], + ConnectionRole::kListenerRole); + + SimulateSecureChannelAuthentication( + pair.remote_device_id(), fake_secure_channel, + true /* created_via_background_advertisement */); + + histogram_tester()->ExpectTimeBucketCount( + "MultiDevice.SecureChannel.BLE.Performance." + "StartScanToReceiveAdvertisementDuration.Background", + kScanToAdvertisementTime, 1); + histogram_tester()->ExpectTimeBucketCount( + "MultiDevice.SecureChannel.BLE.Performance." + "ReceiveAdvertisementToConnectionDuration.Background", + kAdvertisementToConnectionTime, 1); + histogram_tester()->ExpectTimeBucketCount( + "MultiDevice.SecureChannel.BLE.Performance." + "StartScanToConnectionDuration.Background", + kScanToAdvertisementTime + kAdvertisementToConnectionTime, 1); + histogram_tester()->ExpectTimeBucketCount( + "MultiDevice.SecureChannel.BLE.Performance." + "ConnectionToAuthenticationDuration.Background", + kConnectionToAuthenticationTime, 1); +} + } // namespace secure_channel } // namespace chromeos
diff --git a/chromeos/services/secure_channel/secure_channel_service_unittest.cc b/chromeos/services/secure_channel/secure_channel_service_unittest.cc index e39e52b..1cdd9e3c 100644 --- a/chromeos/services/secure_channel/secure_channel_service_unittest.cc +++ b/chromeos/services/secure_channel/secure_channel_service_unittest.cc
@@ -141,7 +141,8 @@ std::unique_ptr<BleConnectionManager> BuildInstance( scoped_refptr<device::BluetoothAdapter> bluetooth_adapter, BleServiceDataHelper* ble_service_data_helper, - TimerFactory* timer_factory) override { + TimerFactory* timer_factory, + base::Clock* clock) override { EXPECT_FALSE(instance_); EXPECT_EQ(expected_bluetooth_adapter_, bluetooth_adapter.get()); EXPECT_EQ(fake_ble_service_data_helper_factory_->instance(),
diff --git a/chromeos/settings/cros_settings_names.cc b/chromeos/settings/cros_settings_names.cc index 654e5935..b7fb4f31 100644 --- a/chromeos/settings/cros_settings_names.cc +++ b/chromeos/settings/cros_settings_names.cc
@@ -197,6 +197,27 @@ // size in bytes. const char kExtensionCacheSize[] = "cros.device.extension_cache_size"; +// A dictionary pref that sets the display resolution. +// Pref format: +// { +// "external_width": int, +// "external_height": int, +// "external_use_native": bool, +// "external_scale_percentage": int, +// "internal_scale_percentage": int, +// "recommended": bool +// } +const char kDeviceDisplayResolution[] = "cros.device_display_resolution"; +const char kDeviceDisplayResolutionKeyExternalWidth[] = "external_width"; +const char kDeviceDisplayResolutionKeyExternalHeight[] = "external_height"; +const char kDeviceDisplayResolutionKeyExternalScale[] = + "external_scale_percentage"; +const char kDeviceDisplayResolutionKeyExternalUseNative[] = + "external_use_native"; +const char kDeviceDisplayResolutionKeyInternalScale[] = + "internal_scale_percentage"; +const char kDeviceDisplayResolutionKeyRecommended[] = "recommended"; + // An integer pref that sets the display rotation at startup to a certain // value, overriding the user value: // 0 = 0 degrees rotation
diff --git a/chromeos/settings/cros_settings_names.h b/chromeos/settings/cros_settings_names.h index a8ad5e8..f4fe24e 100644 --- a/chromeos/settings/cros_settings_names.h +++ b/chromeos/settings/cros_settings_names.h
@@ -102,6 +102,15 @@ CHROMEOS_EXPORT extern const char kExtensionCacheSize[]; +CHROMEOS_EXPORT extern const char kDeviceDisplayResolution[]; +CHROMEOS_EXPORT extern const char kDeviceDisplayResolutionKeyExternalWidth[]; +CHROMEOS_EXPORT extern const char kDeviceDisplayResolutionKeyExternalHeight[]; +CHROMEOS_EXPORT extern const char kDeviceDisplayResolutionKeyExternalScale[]; +CHROMEOS_EXPORT extern const char + kDeviceDisplayResolutionKeyExternalUseNative[]; +CHROMEOS_EXPORT extern const char kDeviceDisplayResolutionKeyInternalScale[]; +CHROMEOS_EXPORT extern const char kDeviceDisplayResolutionKeyRecommended[]; + CHROMEOS_EXPORT extern const char kDisplayRotationDefault[]; CHROMEOS_EXPORT extern const char kLoginAuthenticationBehavior[];
diff --git a/chromeos/strings/chromeos_strings_cs.xtb b/chromeos/strings/chromeos_strings_cs.xtb index 696cb3f..7067720 100644 --- a/chromeos/strings/chromeos_strings_cs.xtb +++ b/chromeos/strings/chromeos_strings_cs.xtb
@@ -16,6 +16,7 @@ <translation id="54609108002486618">Spravovaný</translation> <translation id="5832805196449965646">Přidat uživatele</translation> <translation id="5895138241574237353">Restartovat</translation> +<translation id="7014997087841912572">UKONČIT</translation> <translation id="7222902781030499995">Zastavit časovač</translation> <translation id="7658239707568436148">Zrušit</translation> <translation id="7837740436429729974">Čas vypršel</translation>
diff --git a/chromeos/strings/chromeos_strings_el.xtb b/chromeos/strings/chromeos_strings_el.xtb index eb97343..0199da32 100644 --- a/chromeos/strings/chromeos_strings_el.xtb +++ b/chromeos/strings/chromeos_strings_el.xtb
@@ -16,6 +16,7 @@ <translation id="54609108002486618">Διαχειριζόμενη</translation> <translation id="5832805196449965646">Προσθήκη ατόμου</translation> <translation id="5895138241574237353">Επανεκκίνηση</translation> +<translation id="7014997087841912572">ΔΙΑΚΟΠΗ</translation> <translation id="7222902781030499995">Διακοπή χρονομέτρου</translation> <translation id="7658239707568436148">Ακύρωση</translation> <translation id="7837740436429729974">Ο χρόνος τελείωσε</translation>
diff --git a/chromeos/strings/chromeos_strings_en-GB.xtb b/chromeos/strings/chromeos_strings_en-GB.xtb index d9bec1d..8bc67e3 100644 --- a/chromeos/strings/chromeos_strings_en-GB.xtb +++ b/chromeos/strings/chromeos_strings_en-GB.xtb
@@ -16,6 +16,7 @@ <translation id="54609108002486618">Managed</translation> <translation id="5832805196449965646">Add Person</translation> <translation id="5895138241574237353">Restart</translation> +<translation id="7014997087841912572">STOP</translation> <translation id="7222902781030499995">Stop timer</translation> <translation id="7658239707568436148">Cancel</translation> <translation id="7837740436429729974">Time's up</translation>
diff --git a/components/arc/common/accessibility_helper.mojom b/components/arc/common/accessibility_helper.mojom index 5642e4a..cd9ed05e 100644 --- a/components/arc/common/accessibility_helper.mojom +++ b/components/arc/common/accessibility_helper.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Next MinVersion: 13 +// Next MinVersion: 14 module arc.mojom; @@ -81,6 +81,7 @@ SET_PROGRESS, SHOW_ON_SCREEN, CUSTOM_ACTION, // Not a standard action. + GET_TEXT_LOCATION, // Not a standard action. }; // Possible boolean properties set on an AccessibilityNodeInfo. @@ -109,7 +110,8 @@ IMPORTANCE, SCREEN_READER_FOCUSABLE, SHOWING_HINT_TEXT, - HEADING + HEADING, + SUPPORTS_TEXT_LOCATION, }; // These fields are taken from string instance members of @@ -358,8 +360,14 @@ // window_id where the action is performed on. [MinVersion=6] int32 window_id; + + // Parameters specifying indicies to get text location of node + // in Android. + [MinVersion=13] int32 start_index; + [MinVersion=13] int32 end_index; }; +// Interface for Android communicating to Chrome. // Next method ID: 3 interface AccessibilityHelperHost { OnAccessibilityEventDeprecated@0(AccessibilityEventType event_type, @@ -375,7 +383,8 @@ string notification_key, AccessibilityNotificationStateType state); }; -// Next method ID: 9 +// Interface for communicating to Android. +// Next method ID: 10 interface AccessibilityHelperInstance { // DEPRECATED: Please use Init@7 instead. InitDeprecated@0(AccessibilityHelperHost host); @@ -406,4 +415,9 @@ // Requests the service to enable or disable Explore By Touch. [MinVersion=11] SetExploreByTouchEnabled@8(bool enabled); + + // Refresh the current node with extra data. + // Returns Rect specifying location, or null if textLocation is not available. + [MinVersion=13] RefreshWithExtraData@9(AccessibilityActionData refresh_data) + => (Rect? text_location); };
diff --git a/components/arc/common/bluetooth.mojom b/components/arc/common/bluetooth.mojom index 131b03c26..78bf674 100644 --- a/components/arc/common/bluetooth.mojom +++ b/components/arc/common/bluetooth.mojom
@@ -402,7 +402,7 @@ }; // Next Method ID: 22 -// Deprecated Method ID: 2 +// Deprecated Method ID: 2, 6 interface BluetoothInstance { // DEPRECATED: Please use Init@18 instead. InitDeprecated@0(BluetoothHost host_ptr); @@ -417,9 +417,6 @@ OnBondStateChanged@5(BluetoothStatus status, BluetoothAddress remote_addr, BluetoothBondState state); - OnAclStateChanged@6(BluetoothStatus status, - BluetoothAddress remote_addr, - BluetoothAclState state); // Bluetooth Gatt Client callbacks // TODO(b/111367421): Remove this when no active device running Android N.
diff --git a/components/arc/common/ime.mojom b/components/arc/common/ime.mojom index c06d96b..3e10330 100644 --- a/components/arc/common/ime.mojom +++ b/components/arc/common/ime.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Next MinVersion: 11 +// Next MinVersion: 12 module arc.mojom; @@ -24,6 +24,15 @@ DATETIME, }; +// Maps to ui::TextInputFlags in ui/base/ime/text_input_flags.h. +// Some flags are still missing here because they're not yet supported in ARC++ +// IME. +const int32 TEXT_INPUT_FLAG_NONE = 0; +const int32 TEXT_INPUT_FLAG_AUTOCAPITALIZE_NONE = 64; // 1 << 6 +const int32 TEXT_INPUT_FLAG_AUTOCAPITALIZE_CHARACTERS = 128; // 1 << 7 +const int32 TEXT_INPUT_FLAG_AUTOCAPITALIZE_WORDS = 256; // 1 << 8 +const int32 TEXT_INPUT_FLAG_AUTOCAPITALIZE_SENTENCES = 512; // 1 << 9 + // Represents a single segment of text currently composed by IME. struct CompositionSegment { // Start offset of the segment in UTF-16 index. @@ -37,9 +46,11 @@ // Next method ID: 6 interface ImeHost { // Notifies Chrome that the text input focus is changed. + // Each bit of the bitmask |flags| corresponds to TEXT_INPUT_FLAG_*. OnTextInputTypeChanged@0( TextInputType type, - [MinVersion=10] bool is_personalized_learning_allowed); + [MinVersion=10] bool is_personalized_learning_allowed, + [MinVersion=11] int32 flags); // Notifies Chrome that the cursor poisition has changed. //
diff --git a/components/arc/ime/arc_ime_bridge.h b/components/arc/ime/arc_ime_bridge.h index 4feceae..08bcc27b 100644 --- a/components/arc/ime/arc_ime_bridge.h +++ b/components/arc/ime/arc_ime_bridge.h
@@ -29,9 +29,9 @@ // Received IPCs are deserialized and passed to this delegate. class Delegate { public: - virtual void OnTextInputTypeChanged( - ui::TextInputType type, - bool is_personalized_learning_allowed) = 0; + virtual void OnTextInputTypeChanged(ui::TextInputType type, + bool is_personalized_learning_allowed, + int flags) = 0; virtual void OnCursorRectChanged(const gfx::Rect& rect, bool is_screen_cooridnates) = 0; virtual void OnCancelComposition() = 0;
diff --git a/components/arc/ime/arc_ime_bridge_impl.cc b/components/arc/ime/arc_ime_bridge_impl.cc index 212e341..755c599 100644 --- a/components/arc/ime/arc_ime_bridge_impl.cc +++ b/components/arc/ime/arc_ime_bridge_impl.cc
@@ -13,6 +13,7 @@ #include "components/arc/arc_bridge_service.h" #include "components/arc/arc_service_manager.h" #include "ui/base/ime/composition_text.h" +#include "ui/base/ime/text_input_flags.h" #include "ui/base/ime/text_input_type.h" #include "ui/gfx/geometry/rect.h" @@ -35,6 +36,17 @@ return segments; } +// Converts mojom::TEXT_INPUT_FLAG_* to ui::TextInputFlags. +int ConvertTextInputFlags(int32_t flags) { + if (flags & mojom::TEXT_INPUT_FLAG_AUTOCAPITALIZE_NONE) + return ui::TextInputFlags::TEXT_INPUT_FLAG_AUTOCAPITALIZE_NONE; + if (flags & mojom::TEXT_INPUT_FLAG_AUTOCAPITALIZE_CHARACTERS) + return ui::TextInputFlags::TEXT_INPUT_FLAG_AUTOCAPITALIZE_CHARACTERS; + if (flags & mojom::TEXT_INPUT_FLAG_AUTOCAPITALIZE_WORDS) + return ui::TextInputFlags::TEXT_INPUT_FLAG_AUTOCAPITALIZE_WORDS; + return ui::TextInputFlags::TEXT_INPUT_FLAG_NONE; +} + } // namespace ArcImeBridgeImpl::ArcImeBridgeImpl(Delegate* delegate, @@ -99,8 +111,10 @@ void ArcImeBridgeImpl::OnTextInputTypeChanged( ui::TextInputType type, - bool is_personalized_learning_allowed) { - delegate_->OnTextInputTypeChanged(type, is_personalized_learning_allowed); + bool is_personalized_learning_allowed, + int32_t flags) { + delegate_->OnTextInputTypeChanged(type, is_personalized_learning_allowed, + ConvertTextInputFlags(flags)); } void ArcImeBridgeImpl::OnCursorRectChanged(const gfx::Rect& rect,
diff --git a/components/arc/ime/arc_ime_bridge_impl.h b/components/arc/ime/arc_ime_bridge_impl.h index b2670fcf..eb68bd47 100644 --- a/components/arc/ime/arc_ime_bridge_impl.h +++ b/components/arc/ime/arc_ime_bridge_impl.h
@@ -39,7 +39,8 @@ // mojom::ImeHost overrides: void OnTextInputTypeChanged(ui::TextInputType type, - bool is_personalized_learning_allowed) override; + bool is_personalized_learning_allowed, + int32_t flags) override; void OnCursorRectChanged(const gfx::Rect& rect, bool screen_coordinates) override; void OnCancelComposition() override;
diff --git a/components/arc/ime/arc_ime_service.cc b/components/arc/ime/arc_ime_service.cc index e52fbf499..f409f6b 100644 --- a/components/arc/ime/arc_ime_service.cc +++ b/components/arc/ime/arc_ime_service.cc
@@ -19,6 +19,7 @@ #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" #include "ui/base/ime/input_method.h" +#include "ui/base/ime/text_input_flags.h" #include "ui/base/ui_base_features.h" #include "ui/events/base_event_utils.h" #include "ui/events/event.h" @@ -140,6 +141,7 @@ : ime_bridge_(new ArcImeBridgeImpl(this, bridge_service)), arc_window_delegate_(new ArcWindowDelegateImpl(this)), ime_type_(ui::TEXT_INPUT_TYPE_NONE), + ime_flags_(ui::TEXT_INPUT_FLAG_NONE), is_personalized_learning_allowed_(false), has_composition_text_(false) { if (aura::Env::HasInstance()) @@ -260,13 +262,16 @@ void ArcImeService::OnTextInputTypeChanged( ui::TextInputType type, - bool is_personalized_learning_allowed) { + bool is_personalized_learning_allowed, + int flags) { if (ime_type_ == type && - is_personalized_learning_allowed_ == is_personalized_learning_allowed) { + is_personalized_learning_allowed_ == is_personalized_learning_allowed && + ime_flags_ == flags) { return; } ime_type_ = type; is_personalized_learning_allowed_ = is_personalized_learning_allowed; + ime_flags_ = flags; ui::InputMethod* const input_method = GetInputMethod(); if (input_method) @@ -318,8 +323,7 @@ void ArcImeService::RequestHideIme() { // Ignore the request when the ARC app is not focused. - ui::InputMethod* const input_method = GetInputMethod(); - if (!input_method || input_method->GetTextInputClient() != nullptr) + if (!focused_arc_window_) return; // TODO(mash): Support virtual keyboard under MASH. There is no @@ -471,7 +475,7 @@ } int ArcImeService::GetTextInputFlags() const { - return ui::TEXT_INPUT_FLAG_NONE; + return ime_flags_; } bool ArcImeService::CanComposeInline() const {
diff --git a/components/arc/ime/arc_ime_service.h b/components/arc/ime/arc_ime_service.h index f5c50432..695df6e 100644 --- a/components/arc/ime/arc_ime_service.h +++ b/components/arc/ime/arc_ime_service.h
@@ -14,7 +14,6 @@ #include "ui/aura/env_observer.h" #include "ui/aura/window_observer.h" #include "ui/base/ime/text_input_client.h" -#include "ui/base/ime/text_input_flags.h" #include "ui/base/ime/text_input_type.h" #include "ui/gfx/geometry/rect.h" #include "ui/keyboard/keyboard_controller_observer.h" @@ -87,7 +86,8 @@ // Overridden from ArcImeBridge::Delegate: void OnTextInputTypeChanged(ui::TextInputType type, - bool is_personalized_learning_allowed) override; + bool is_personalized_learning_allowed, + int flags) override; void OnCursorRectChanged(const gfx::Rect& rect, bool is_screen_coordinates) override; void OnCancelComposition() override; @@ -165,6 +165,8 @@ std::unique_ptr<ArcImeBridge> ime_bridge_; std::unique_ptr<ArcWindowDelegate> arc_window_delegate_; ui::TextInputType ime_type_; + // The flag is the bit map of ui::TextInputFlags. + int ime_flags_; bool is_personalized_learning_allowed_; gfx::Rect cursor_rect_; bool has_composition_text_;
diff --git a/components/arc/ime/arc_ime_service_unittest.cc b/components/arc/ime/arc_ime_service_unittest.cc index 4c2f90fa..549b372 100644 --- a/components/arc/ime/arc_ime_service_unittest.cc +++ b/components/arc/ime/arc_ime_service_unittest.cc
@@ -11,12 +11,14 @@ #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "components/arc/arc_bridge_service.h" +#include "components/arc/common/ime.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/test/test_windows.h" #include "ui/aura/window.h" #include "ui/base/ime/composition_text.h" #include "ui/base/ime/dummy_input_method.h" +#include "ui/base/ime/text_input_flags.h" #include "ui/events/event.h" #include "ui/events/keycodes/dom/dom_code.h" #include "ui/events/keycodes/keyboard_codes.h" @@ -235,11 +237,13 @@ TEST_F(ArcImeServiceTest, ShowVirtualKeyboardIfEnabled) { instance_->OnWindowFocused(arc_win_.get(), nullptr); - instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_NONE, false); + instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_NONE, false, + mojom::TEXT_INPUT_FLAG_NONE); ASSERT_EQ(0, fake_input_method_->count_show_ime_if_needed()); // Text input type change does not imply the show ime request. - instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_TEXT, true); + instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_TEXT, true, + mojom::TEXT_INPUT_FLAG_NONE); EXPECT_EQ(0, fake_input_method_->count_show_ime_if_needed()); instance_->ShowVirtualKeyboardIfEnabled(); @@ -258,12 +262,14 @@ instance_->OnWindowFocused(arc_win_.get(), nullptr); // When text input type is NONE, the event is not forwarded. - instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_NONE, false); + instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_NONE, false, + mojom::TEXT_INPUT_FLAG_NONE); instance_->InsertChar(ui::KeyEvent('a', ui::VKEY_A, ui::DomCode::NONE, 0)); EXPECT_EQ(0, fake_arc_ime_bridge_->count_send_insert_text()); // When the bridge is accepting text inputs, forward the event. - instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_TEXT, true); + instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_TEXT, true, + mojom::TEXT_INPUT_FLAG_NONE); instance_->InsertChar(ui::KeyEvent('a', ui::VKEY_A, ui::DomCode::NONE, 0)); EXPECT_EQ(1, fake_arc_ime_bridge_->count_send_insert_text()); } @@ -402,15 +408,18 @@ instance_->OnWindowFocused(arc_win_.get(), nullptr); ASSERT_NE(ui::TEXT_INPUT_TYPE_TEXT, instance_->GetTextInputType()); - instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_TEXT, true); + instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_TEXT, true, + mojom::TEXT_INPUT_FLAG_NONE); EXPECT_TRUE(instance_->ShouldDoLearning()); EXPECT_EQ(1, fake_input_method_->count_on_text_input_type_changed()); - instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_TEXT, false); + instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_TEXT, false, + mojom::TEXT_INPUT_FLAG_NONE); EXPECT_FALSE(instance_->ShouldDoLearning()); EXPECT_EQ(2, fake_input_method_->count_on_text_input_type_changed()); - instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_URL, false); + instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_URL, false, + mojom::TEXT_INPUT_FLAG_NONE); EXPECT_FALSE(instance_->ShouldDoLearning()); EXPECT_EQ(3, fake_input_method_->count_on_text_input_type_changed()); }
diff --git a/components/arc/test/fake_accessibility_helper_instance.cc b/components/arc/test/fake_accessibility_helper_instance.cc index cabc6af..7c467bfb9 100644 --- a/components/arc/test/fake_accessibility_helper_instance.cc +++ b/components/arc/test/fake_accessibility_helper_instance.cc
@@ -55,4 +55,8 @@ explore_by_touch_enabled_ = enabled; } +void FakeAccessibilityHelperInstance::RefreshWithExtraData( + mojom::AccessibilityActionDataPtr action_data_ptr, + RefreshWithExtraDataCallback callback) {} + } // namespace arc
diff --git a/components/arc/test/fake_accessibility_helper_instance.h b/components/arc/test/fake_accessibility_helper_instance.h index e7c4cdc..51e573d 100644 --- a/components/arc/test/fake_accessibility_helper_instance.h +++ b/components/arc/test/fake_accessibility_helper_instance.h
@@ -38,6 +38,8 @@ mojom::AccessibilityFilterType filter_type() { return filter_type_; } bool explore_by_touch_enabled() { return explore_by_touch_enabled_; } + void RefreshWithExtraData(mojom::AccessibilityActionDataPtr action_data_ptr, + RefreshWithExtraDataCallback callback) override; private: mojom::AccessibilityFilterType filter_type_ =
diff --git a/components/arc/test/fake_bluetooth_instance.cc b/components/arc/test/fake_bluetooth_instance.cc index b21d2ec1..ceb0c13 100644 --- a/components/arc/test/fake_bluetooth_instance.cc +++ b/components/arc/test/fake_bluetooth_instance.cc
@@ -59,11 +59,6 @@ mojom::BluetoothAddressPtr remote_addr, mojom::BluetoothBondState state) {} -void FakeBluetoothInstance::OnAclStateChanged( - mojom::BluetoothStatus status, - mojom::BluetoothAddressPtr remote_addr, - mojom::BluetoothAclState state) {} - void FakeBluetoothInstance::OnLEDeviceFoundForN( mojom::BluetoothAddressPtr addr, int32_t rssi,
diff --git a/components/arc/test/fake_bluetooth_instance.h b/components/arc/test/fake_bluetooth_instance.h index f54ad47..f125168 100644 --- a/components/arc/test/fake_bluetooth_instance.h +++ b/components/arc/test/fake_bluetooth_instance.h
@@ -83,9 +83,6 @@ void OnBondStateChanged(mojom::BluetoothStatus status, mojom::BluetoothAddressPtr remote_addr, mojom::BluetoothBondState state) override; - void OnAclStateChanged(mojom::BluetoothStatus status, - mojom::BluetoothAddressPtr remote_addr, - mojom::BluetoothAclState state) override; void OnLEDeviceFoundForN( mojom::BluetoothAddressPtr addr, int32_t rssi,
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 1f369f0d..0331599f 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -165,6 +165,8 @@ "search_field.h", "state_names.cc", "state_names.h", + "strike_database.cc", + "strike_database.h", "subkey_requester.cc", "subkey_requester.h", "suggestion.cc", @@ -359,6 +361,8 @@ "test_personal_data_manager.h", "test_region_data_loader.cc", "test_region_data_loader.h", + "test_strike_database.cc", + "test_strike_database.h", "webdata/autofill_sync_bridge_test_util.cc", "webdata/autofill_sync_bridge_test_util.h", "webdata/mock_autofill_webdata_backend.cc", @@ -498,10 +502,12 @@ "phone_field_unittest.cc", "phone_number_i18n_unittest.cc", "phone_number_unittest.cc", + "proto/legacy_proto_bridge_unittest.cc", "randomized_encoder_unittest.cc", "rationalization_util_unittest.cc", "region_combobox_model_unittest.cc", "search_field_unittest.cc", + "strike_database_unittest.cc", "subkey_requester_unittest.cc", "ui/card_unmask_prompt_controller_impl_unittest.cc", "validation_unittest.cc", @@ -536,6 +542,7 @@ ":password_generator_fips181", ":test_support", ":unit_tests_bundle_data", + "proto:legacy_proto_bridge", "//base", "//base/test:test_support", "//components/autofill/core/common",
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index 46ed034..3126dc7 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -2474,6 +2474,12 @@ std::vector<AutofillProfile>* local_profiles, std::unordered_map<std::string, AutofillProfile*>* server_id_profiles_map, std::unordered_map<std::string, std::string>* guids_merge_map) { + // If the full Sync feature isn't enabled, then do NOT convert any Wallet + // addresses to local ones. + if (!IsSyncFeatureEnabled()) { + return false; + } + bool has_converted_addresses = false; for (std::unique_ptr<AutofillProfile>& wallet_address : server_profiles_) { // Add the profile to the map.
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h index c66488d..736f34a8 100644 --- a/components/autofill/core/browser/personal_data_manager.h +++ b/components/autofill/core/browser/personal_data_manager.h
@@ -416,6 +416,8 @@ PersonalDataManagerTest, ConvertWalletAddressesAndUpdateWalletCards_MultipleSimilarWalletAddresses); // NOLINT FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest, + DoNotConvertWalletAddressesInEphemeralStorage); + FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest, DeleteDisusedCreditCards_OncePerVersion); FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest, DeleteDisusedCreditCards_DoNothingWhenDisabled);
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc index 88d8f59..acffc55c 100644 --- a/components/autofill/core/browser/personal_data_manager_unittest.cc +++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -33,6 +33,7 @@ #include "components/autofill/core/browser/autofill_experiments.h" #include "components/autofill/core/browser/autofill_metrics.h" #include "components/autofill/core/browser/autofill_profile.h" +#include "components/autofill/core/browser/autofill_profile_comparator.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/form_structure.h" @@ -223,6 +224,14 @@ personal_data_->SetProfiles(&empty_profiles); } + bool TurnOnSyncFeature() WARN_UNUSED_RESULT { + sync_service_.SetIsAuthenticatedAccountPrimary(true); + if (!sync_service_.IsSyncFeatureEnabled()) + return false; + personal_data_->OnStateChanged(&sync_service_); + return personal_data_->IsSyncFeatureEnabled(); + } + void EnableWalletCardImport() { identity_test_env_.MakePrimaryAccountAvailable("syncuser@example.com"); base::CommandLine::ForCurrentProcess()->AppendSwitch( @@ -2116,6 +2125,8 @@ /////////////////////////////////////////////////////////////////////// const std::string kServerAddressId("server_address1"); + ASSERT_TRUE(TurnOnSyncFeature()); + // Add two different profiles, a local and a server one. AutofillProfile local_profile(base::GenerateGUID(), test::kEmptyOrigin); test::SetProfileInfo(&local_profile, "Josephine", "Alicia", "Saenz", @@ -2160,6 +2171,8 @@ /////////////////////////////////////////////////////////////////////// const std::string kServerAddressId("server_address1"); + ASSERT_TRUE(TurnOnSyncFeature()); + // Add two different profiles, a local and a server one. AutofillProfile local_profile(base::GenerateGUID(), test::kEmptyOrigin); test::SetProfileInfo(&local_profile, "Josephine", "Alicia", "Saenz", @@ -5013,6 +5026,8 @@ // Setup. /////////////////////////////////////////////////////////////////////// EnableWalletCardImport(); + ASSERT_TRUE(TurnOnSyncFeature()); + base::HistogramTester histogram_tester; const std::string kServerAddressId("server_address1"); @@ -5116,6 +5131,8 @@ // Setup. /////////////////////////////////////////////////////////////////////// EnableWalletCardImport(); + ASSERT_TRUE(TurnOnSyncFeature()); + base::HistogramTester histogram_tester; const std::string kServerAddressId("server_address1"); @@ -5218,6 +5235,8 @@ // Setup. /////////////////////////////////////////////////////////////////////// EnableWalletCardImport(); + ASSERT_TRUE(TurnOnSyncFeature()); + base::HistogramTester histogram_tester; const std::string kServerAddressId("server_address1"); @@ -5269,6 +5288,8 @@ // Setup. /////////////////////////////////////////////////////////////////////// EnableWalletCardImport(); + ASSERT_TRUE(TurnOnSyncFeature()); + base::HistogramTester histogram_tester; const std::string kServerAddressId("server_address1"); const std::string kServerAddressId2("server_address2"); @@ -5393,6 +5414,8 @@ // a new server card that refers to the already converted server address as // its billing address. EnableWalletCardImport(); + ASSERT_TRUE(TurnOnSyncFeature()); + base::HistogramTester histogram_tester; const std::string kServerAddressId("server_address1"); @@ -5487,6 +5510,75 @@ personal_data_->GetCreditCards()[1]->billing_address_id()); } +// Tests that Wallet addresses do NOT get converted if they're stored in +// ephemeral storage. +TEST_F(PersonalDataManagerTest, DoNotConvertWalletAddressesInEphemeralStorage) { + /////////////////////////////////////////////////////////////////////// + // Setup. + /////////////////////////////////////////////////////////////////////// + EnableWalletCardImport(); + ResetPersonalDataManager(USER_MODE_NORMAL, + /*use_account_server_storage=*/true); + ASSERT_FALSE(personal_data_->IsSyncFeatureEnabled()); + + // Add a local profile. + AutofillProfile local_profile(base::GenerateGUID(), test::kEmptyOrigin); + test::SetProfileInfo(&local_profile, "Josephine", "Alicia", "Saenz", "", + "Fox", "1212 Center.", "Bld. 5", "", "", "", "", ""); + personal_data_->AddProfile(local_profile); + + // Add two server profiles: The first is unique, the second is similar to the + // local one but has some additional info. + std::vector<AutofillProfile> server_profiles; + server_profiles.push_back( + AutofillProfile(AutofillProfile::SERVER_PROFILE, "server_address1")); + test::SetProfileInfo(&server_profiles.back(), "John", "", "Doe", "", "", + "1212 Center", "Bld. 5", "Orlando", "FL", "32801", "US", + ""); + server_profiles.back().SetRawInfo(NAME_FULL, base::ASCIIToUTF16("John Doe")); + + server_profiles.push_back( + AutofillProfile(AutofillProfile::SERVER_PROFILE, "server_address2")); + test::SetProfileInfo(&server_profiles.back(), "Josephine", "Alicia", "Saenz", + "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", + "Orlando", "FL", "32801", "US", "19482937549"); + server_profiles.back().SetRawInfo( + NAME_FULL, base::ASCIIToUTF16("Josephine Alicia Saenz")); + SetServerProfiles(server_profiles); + + ASSERT_TRUE(AutofillProfileComparator(personal_data_->app_locale()) + .AreMergeable(local_profile, server_profiles.back())); + + // Make sure everything is set up correctly. + personal_data_->Refresh(); + WaitForOnPersonalDataChanged(); + ASSERT_EQ(1U, personal_data_->GetProfiles().size()); + ASSERT_EQ(2U, personal_data_->GetServerProfiles().size()); + + /////////////////////////////////////////////////////////////////////// + // Tested method. + /////////////////////////////////////////////////////////////////////// + // Since the wallet addresses are in ephemeral storage, they should *not* get + // converted to local addresses. + personal_data_->ConvertWalletAddressesAndUpdateWalletCards(); + + /////////////////////////////////////////////////////////////////////// + // Validation. + /////////////////////////////////////////////////////////////////////// + // Since there should be no change in data, OnPersonalDataChanged should not + // get called. + EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(0); + + personal_data_->Refresh(); + WaitForOnPersonalDataChanged(); + + // There should be no changes to the local profiles: No new one added, and no + // changes to the existing one (even though the second server profile contains + // additional information and is mergeable in principle). + EXPECT_EQ(1U, personal_data_->GetProfiles().size()); + EXPECT_EQ(local_profile, *personal_data_->GetProfiles()[0]); +} + TEST_F(PersonalDataManagerTest, RemoveByGUID_ResetsBillingAddress) { /////////////////////////////////////////////////////////////////////// // Setup.
diff --git a/components/autofill/core/browser/popup_item_ids.h b/components/autofill/core/browser/popup_item_ids.h index 31438f3b..7f333c6 100644 --- a/components/autofill/core/browser/popup_item_ids.h +++ b/components/autofill/core/browser/popup_item_ids.h
@@ -27,6 +27,7 @@ POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY = -13, POPUP_ITEM_ID_GOOGLE_PAY_BRANDING = -14, POPUP_ITEM_ID_GENERATE_PASSWORD_ENTRY = -15, + POPUP_ITEM_ID_SHOW_ACCOUNT_CARDS = -16, }; } // namespace autofill
diff --git a/components/autofill/core/browser/proto/BUILD.gn b/components/autofill/core/browser/proto/BUILD.gn index 6289d29..9f83614 100644 --- a/components/autofill/core/browser/proto/BUILD.gn +++ b/components/autofill/core/browser/proto/BUILD.gn
@@ -14,3 +14,13 @@ "strike_data.proto", ] } + +static_library("legacy_proto_bridge") { + sources = [ + "legacy_proto_bridge.cc", + "legacy_proto_bridge.h", + ] + deps = [ + ":proto", + ] +}
diff --git a/components/autofill/core/browser/proto/api_v1.proto b/components/autofill/core/browser/proto/api_v1.proto index 09c311b0..205bd21 100644 --- a/components/autofill/core/browser/proto/api_v1.proto +++ b/components/autofill/core/browser/proto/api_v1.proto
@@ -68,7 +68,7 @@ // Signature identifying the field that is the same as in the request. optional fixed32 field_signature = 1; // The predicted field type. - optional int32 primary_type_prediction = 2; + optional fixed32 primary_type_prediction = 2; // Detailed list of all possible predictions (including // |primary_type_prediction| as the first item). repeated FieldPrediction predictions = 3;
diff --git a/components/autofill/core/browser/proto/legacy_proto_bridge.cc b/components/autofill/core/browser/proto/legacy_proto_bridge.cc new file mode 100644 index 0000000..0380c255 --- /dev/null +++ b/components/autofill/core/browser/proto/legacy_proto_bridge.cc
@@ -0,0 +1,74 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/core/browser/proto/legacy_proto_bridge.h" + +namespace autofill { + +namespace { + +AutofillPageQueryRequest::Form::Field CreateLegacyFieldFromApiField( + const AutofillQueryContents::Form::Field& legacy_field) { + AutofillPageQueryRequest::Form::Field api_field; + api_field.set_signature(legacy_field.signature()); + api_field.set_name(legacy_field.name()); + api_field.set_control_type(legacy_field.type()); + return api_field; +} + +AutofillPageQueryRequest::Form CreateApiFormFromLegacyForm( + const AutofillQueryContents::Form& legacy_form) { + AutofillPageQueryRequest::Form api_form; + for (const auto& legacy_field : legacy_form.field()) { + *api_form.add_fields() = CreateLegacyFieldFromApiField(legacy_field); + } + return api_form; +} + +AutofillQueryResponseContents::Field::FieldPrediction +CreateLegacyFieldPredictionFromApiPrediction( + const AutofillQueryResponse::FormSuggestion::FieldSuggestion:: + FieldPrediction& api_field_prediction) { + AutofillQueryResponseContents::Field::FieldPrediction legacy_prediction; + legacy_prediction.set_type(api_field_prediction.type()); + return legacy_prediction; +} + +AutofillQueryResponseContents::Field CreateLegacyFieldFromApiField( + const AutofillQueryResponse::FormSuggestion::FieldSuggestion& api_field) { + AutofillQueryResponseContents::Field legacy_field; + legacy_field.set_overall_type_prediction(api_field.primary_type_prediction()); + for (const auto& api_prediction : api_field.predictions()) { + *legacy_field.add_predictions() = + CreateLegacyFieldPredictionFromApiPrediction(api_prediction); + } + *legacy_field.mutable_password_requirements() = + api_field.password_requirements(); + return legacy_field; +} + +} // namespace + +AutofillPageQueryRequest CreateApiRequestFromLegacyRequest( + const AutofillQueryContents& legacy_request) { + AutofillPageQueryRequest api_request; + api_request.set_client_version(legacy_request.client_version()); + for (const auto& legacy_form : legacy_request.form()) { + *api_request.add_forms() = CreateApiFormFromLegacyForm(legacy_form); + } + return api_request; +} + +AutofillQueryResponseContents CreateLegacyResponseFromApiResponse( + const AutofillQueryResponse& api_response) { + AutofillQueryResponseContents legacy_response; + for (const auto& api_form : api_response.form_suggestions()) { + for (const auto& api_field : api_form.field_suggestions()) { + *legacy_response.add_field() = CreateLegacyFieldFromApiField(api_field); + } + } + return legacy_response; +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/proto/legacy_proto_bridge.h b/components/autofill/core/browser/proto/legacy_proto_bridge.h new file mode 100644 index 0000000..9f0710676 --- /dev/null +++ b/components/autofill/core/browser/proto/legacy_proto_bridge.h
@@ -0,0 +1,23 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PROTO_LEGACY_PROTO_BRIDGE_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_PROTO_LEGACY_PROTO_BRIDGE_H_ + +#include "components/autofill/core/browser/proto/api_v1.pb.h" +#include "components/autofill/core/browser/proto/server.pb.h" + +namespace autofill { + +// Creates a new API request from a legacy request. +autofill::AutofillPageQueryRequest CreateApiRequestFromLegacyRequest( + const AutofillQueryContents& legacy_request); + +// Creates a new API response from a legacy response. +AutofillQueryResponseContents CreateLegacyResponseFromApiResponse( + const autofill::AutofillQueryResponse& api_response); + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PROTO_LEGACY_PROTO_BRIDGE_H_
diff --git a/components/autofill/core/browser/proto/legacy_proto_bridge_unittest.cc b/components/autofill/core/browser/proto/legacy_proto_bridge_unittest.cc new file mode 100644 index 0000000..19e1d10 --- /dev/null +++ b/components/autofill/core/browser/proto/legacy_proto_bridge_unittest.cc
@@ -0,0 +1,140 @@ +// 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/autofill/core/browser/proto/legacy_proto_bridge.h" + +#include "components/autofill/core/browser/proto/api_v1.pb.h" +#include "components/autofill/core/browser/proto/password_requirements.pb.h" +#include "components/autofill/core/browser/proto/server.pb.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace autofill { +namespace { + +using ::testing::ElementsAre; +using ::testing::Eq; +using ::testing::Property; + +AutofillQueryContents::Form::Field MakeLegacyField(uint32_t signature, + const std::string& name, + const std::string& type) { + AutofillQueryContents::Form::Field field; + field.set_signature(signature); + field.set_name(name); + field.set_type(type); + return field; +} + +AutofillQueryResponse::FormSuggestion::FieldSuggestion MakeFieldSuggestion( + uint32_t field_signature, + uint32_t primary_type_prediction, + std::vector<uint32_t> predictions, + bool may_use_prefilled_placeholder, + PasswordRequirementsSpec password_requirements) { + AutofillQueryResponse::FormSuggestion::FieldSuggestion field_suggestion; + field_suggestion.set_field_signature(field_signature); + field_suggestion.set_primary_type_prediction(primary_type_prediction); + for (auto prediction : predictions) { + field_suggestion.add_predictions()->set_type(prediction); + } + field_suggestion.set_may_use_prefilled_placeholder( + may_use_prefilled_placeholder); + *field_suggestion.mutable_password_requirements() = + std::move(password_requirements); + return field_suggestion; +} + +TEST(ProtoBridgeTest, TestCreateApiRequestFromLegacyRequest) { + AutofillQueryContents legacy_request; + legacy_request.set_client_version("dummy client v1"); + AutofillQueryContents::Form* new_form = legacy_request.add_form(); + new_form->set_signature(1234U); + *new_form->add_field() = MakeLegacyField(1234U, "First Name", "text"); + *new_form->add_field() = MakeLegacyField(5678U, "Last Name", "text"); + + new_form = legacy_request.add_form(); + new_form->set_signature(5678U); + *new_form->add_field() = MakeLegacyField(1234U, "Street Address", "text"); + *new_form->add_field() = MakeLegacyField(5678U, "Zip Code", "text"); + + AutofillPageQueryRequest api_request = + CreateApiRequestFromLegacyRequest(legacy_request); + + EXPECT_EQ(api_request.client_version(), "dummy client v1"); + // Assert fields of form 0. + EXPECT_EQ(api_request.forms(0).fields(0).signature(), 1234U); + EXPECT_EQ(api_request.forms(0).fields(0).name(), "First Name"); + EXPECT_EQ(api_request.forms(0).fields(0).control_type(), "text"); + EXPECT_EQ(api_request.forms(0).fields(1).signature(), 5678U); + EXPECT_EQ(api_request.forms(0).fields(1).name(), "Last Name"); + EXPECT_EQ(api_request.forms(0).fields(1).control_type(), "text"); + // Assert field of form 1. + EXPECT_EQ(api_request.forms(1).fields(0).signature(), 1234U); + EXPECT_EQ(api_request.forms(1).fields(0).name(), "Street Address"); + EXPECT_EQ(api_request.forms(1).fields(0).control_type(), "text"); + EXPECT_EQ(api_request.forms(1).fields(1).signature(), 5678U); + EXPECT_EQ(api_request.forms(1).fields(1).name(), "Zip Code"); + EXPECT_EQ(api_request.forms(1).fields(1).control_type(), "text"); +} + +TEST(ProtoBridgeTest, CreateLegacyResponseFromApiResponse) { + constexpr uint32_t dummy_password_type = 1U; + constexpr uint32_t dummy_address_type = 2U; + constexpr uint32_t dummy_password_priority = 3U; + + PasswordRequirementsSpec dummy_password_requirement_specs; + dummy_password_requirement_specs.set_priority(dummy_password_priority); + + AutofillQueryResponse api_response; + // Add suggestions for form 0. + auto* form_suggestion = api_response.add_form_suggestions(); + *form_suggestion->add_field_suggestions() = MakeFieldSuggestion( + /*field_signature=*/1234U, + /*primary_type_prediction=*/dummy_password_type, + /*predictions=*/{dummy_password_type, dummy_address_type}, + /*may_use_prefilled_placeholder=*/true, + /*password_requirements=*/dummy_password_requirement_specs); + // Add suggestions for form 1. + form_suggestion = api_response.add_form_suggestions(); + *form_suggestion->add_field_suggestions() = MakeFieldSuggestion( + /*field_signature=*/5678U, /*primary_type_prediction=*/dummy_address_type, + /*predictions=*/{dummy_address_type, dummy_password_type}, + /*may_use_prefilled_placeholder=*/false, + /*password_requirements=*/dummy_password_requirement_specs); + + AutofillQueryResponseContents legacy_response = + CreateLegacyResponseFromApiResponse(api_response); + + // Assert fields of form 0 in legacy response. + EXPECT_EQ(legacy_response.field(0).overall_type_prediction(), + dummy_password_type); + EXPECT_THAT( + legacy_response.field(0).predictions(), + ElementsAre( + Property(&AutofillQueryResponseContents::Field::FieldPrediction::type, + Eq(dummy_password_type)), + Property(&AutofillQueryResponseContents::Field::FieldPrediction::type, + Eq(dummy_address_type)))); + EXPECT_THAT(legacy_response.field(0).password_requirements(), + Property(&PasswordRequirementsSpec::priority, + Eq(dummy_password_priority))); + + // Assert fields of form 1 in legacy response. + EXPECT_EQ(legacy_response.field(1).overall_type_prediction(), + dummy_address_type); + EXPECT_THAT( + legacy_response.field(1).predictions(), + ElementsAre( + Property(&AutofillQueryResponseContents::Field::FieldPrediction::type, + Eq(dummy_address_type)), + Property(&AutofillQueryResponseContents::Field::FieldPrediction::type, + Eq(dummy_password_type)))); + EXPECT_THAT(legacy_response.field(1).password_requirements(), + Property(&PasswordRequirementsSpec::priority, + Eq(dummy_password_priority))); +} + +} // namespace +} // namespace autofill
diff --git a/components/autofill/core/browser/strike_database.cc b/components/autofill/core/browser/strike_database.cc new file mode 100644 index 0000000..451af485 --- /dev/null +++ b/components/autofill/core/browser/strike_database.cc
@@ -0,0 +1,192 @@ +// 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/autofill/core/browser/strike_database.h" + +#include <string> +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/metrics/histogram_functions.h" +#include "base/task/post_task.h" +#include "base/time/time.h" +#include "components/autofill/core/browser/proto/strike_data.pb.h" +#include "components/leveldb_proto/proto_database_impl.h" + +namespace autofill { + +namespace { +const char kDatabaseClientName[] = "StrikeService"; +const char kKeyDeliminator[] = "__"; +const int kMaxInitAttempts = 3; +} // namespace + +StrikeDatabase::StrikeDatabase(const base::FilePath& database_dir) + : db_(std::make_unique<leveldb_proto::ProtoDatabaseImpl<StrikeData>>( + base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}))), + database_dir_(database_dir), + weak_ptr_factory_(this) { + db_->Init(kDatabaseClientName, database_dir, + leveldb_proto::CreateSimpleOptions(), + base::BindRepeating(&StrikeDatabase::OnDatabaseInit, + weak_ptr_factory_.GetWeakPtr())); +} + +StrikeDatabase::~StrikeDatabase() {} + +int StrikeDatabase::AddStrike(const std::string id) { + std::string key = GetKey(id); + int num_strikes = strike_map_cache_.count(key) // Cache has entry for |key|. + ? strike_map_cache_[key].num_strikes() + 1 + : 1; + StrikeData data; + data.set_num_strikes(num_strikes); + data.set_last_update_timestamp( + base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds()); + UpdateCache(key, data); + SetProtoStrikeData(key, data, base::DoNothing()); + return num_strikes; +} + +int StrikeDatabase::GetStrikes(const std::string id) { + std::string key = GetKey(id); + return strike_map_cache_.count(key) // Cache contains entry for |key|. + ? strike_map_cache_[key].num_strikes() + : 0; +} + +void StrikeDatabase::ClearStrikes(const std::string id) { + std::string key = GetKey(id); + strike_map_cache_.erase(key); + ClearAllProtoStrikesForKey(key, base::DoNothing()); +} + +StrikeDatabase::StrikeDatabase() + : db_(nullptr), + database_dir_(base::FilePath(nullptr)), + weak_ptr_factory_(this) {} + +void StrikeDatabase::OnDatabaseInit(bool success) { + database_initialized_ = success; + if (!success) { + base::UmaHistogramCounts100( + "Autofill.StrikeDatabase.StrikeDatabaseInitFailed", num_init_attempts_); + if (num_init_attempts_ < kMaxInitAttempts) { + num_init_attempts_++; + db_->Init(kDatabaseClientName, database_dir_, + leveldb_proto::CreateSimpleOptions(), + base::BindRepeating(&StrikeDatabase::OnDatabaseInit, + weak_ptr_factory_.GetWeakPtr())); + } + return; + } + db_->LoadKeysAndEntries( + base::BindRepeating(&StrikeDatabase::OnDatabaseLoadKeysAndEntries, + weak_ptr_factory_.GetWeakPtr())); +} + +void StrikeDatabase::OnDatabaseLoadKeysAndEntries( + bool success, + std::unique_ptr<std::map<std::string, StrikeData>> entries) { + if (!success) { + database_initialized_ = false; + return; + } + strike_map_cache_.insert(entries->begin(), entries->end()); +} + +std::string StrikeDatabase::GetKey(const std::string id) { + return GetProjectPrefix() + kKeyDeliminator + id; +} + +void StrikeDatabase::GetProtoStrikes(const std::string key, + const StrikesCallback& outer_callback) { + if (!database_initialized_) { + outer_callback.Run(false); + return; + } + GetProtoStrikeData( + key, + base::BindRepeating(&StrikeDatabase::OnGetProtoStrikes, + base::Unretained(this), std::move(outer_callback))); +} + +void StrikeDatabase::ClearAllProtoStrikes( + const ClearStrikesCallback& outer_callback) { + if (!database_initialized_) { + outer_callback.Run(false); + return; + } + // For deleting all, filter method always returns true. + db_->UpdateEntriesWithRemoveFilter( + std::make_unique<StrikeDataProto::KeyEntryVector>(), + base::BindRepeating([](const std::string& key) { return true; }), + outer_callback); +} + +void StrikeDatabase::ClearAllProtoStrikesForKey( + const std::string& key, + const ClearStrikesCallback& outer_callback) { + if (!database_initialized_) { + outer_callback.Run(false); + return; + } + std::unique_ptr<std::vector<std::string>> keys_to_remove( + new std::vector<std::string>()); + keys_to_remove->push_back(key); + db_->UpdateEntries( + /*entries_to_save=*/std::make_unique< + leveldb_proto::ProtoDatabase<StrikeData>::KeyEntryVector>(), + /*keys_to_remove=*/std::move(keys_to_remove), outer_callback); +} + +void StrikeDatabase::GetProtoStrikeData(const std::string key, + const GetValueCallback& callback) { + if (!database_initialized_) { + callback.Run(false, nullptr); + return; + } + db_->GetEntry(key, callback); +} + +void StrikeDatabase::SetProtoStrikeData(const std::string& key, + const StrikeData& data, + const SetValueCallback& callback) { + if (!database_initialized_) { + callback.Run(false); + return; + } + std::unique_ptr<StrikeDataProto::KeyEntryVector> entries( + new StrikeDataProto::KeyEntryVector()); + entries->push_back(std::make_pair(key, data)); + db_->UpdateEntries( + /*entries_to_save=*/std::move(entries), + /*keys_to_remove=*/std::make_unique<std::vector<std::string>>(), + callback); +} + +void StrikeDatabase::OnGetProtoStrikes( + StrikesCallback callback, + bool success, + std::unique_ptr<StrikeData> strike_data) { + if (success && strike_data) + callback.Run(strike_data->num_strikes()); + else + callback.Run(0); +} + +void StrikeDatabase::LoadKeys(const LoadKeysCallback& callback) { + db_->LoadKeys(callback); +} + +void StrikeDatabase::UpdateCache(const std::string& key, + const StrikeData& data) { + strike_map_cache_[key] = data; +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/strike_database.h b/components/autofill/core/browser/strike_database.h new file mode 100644 index 0000000..6b79c564 --- /dev/null +++ b/components/autofill/core/browser/strike_database.h
@@ -0,0 +1,144 @@ +// 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_AUTOFILL_CORE_BROWSER_STRIKE_DATABASE_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASE_H_ + +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include "base/callback_forward.h" +#include "base/memory/weak_ptr.h" +#include "components/keyed_service/core/keyed_service.h" +#include "components/leveldb_proto/proto_database.h" + +namespace autofill { +class StrikeData; + +// Manages data on whether different Autofill opportunities should be offered to +// the user. Projects can earn strikes in a number of ways; for instance, if a +// user ignores or declines a prompt, or if a user accepts a prompt but the task +// fails. +class StrikeDatabase : public KeyedService { + public: + using ClearStrikesCallback = base::RepeatingCallback<void(bool success)>; + + using GetValueCallback = + base::RepeatingCallback<void(bool success, + std::unique_ptr<StrikeData> data)>; + + using LoadKeysCallback = + base::RepeatingCallback<void(bool success, + std::unique_ptr<std::vector<std::string>>)>; + + using SetValueCallback = base::RepeatingCallback<void(bool success)>; + + using StrikesCallback = base::RepeatingCallback<void(int num_strikes)>; + + using StrikeDataProto = leveldb_proto::ProtoDatabase<StrikeData>; + + explicit StrikeDatabase(const base::FilePath& database_dir); + ~StrikeDatabase() override; + + bool IsMaxStrikesLimitReached(); + + // Increments in-memory cache and updates underlying ProtoDatabase. + int AddStrike(const std::string id); + + // Returns strike count from in-memory cache. + int GetStrikes(const std::string id); + + // Removes all database entries from in-memory cache and underlying + // ProtoDatabase. + void ClearStrikes(const std::string id); + + protected: + // Constructor for testing that does not initialize a ProtoDatabase. + StrikeDatabase(); + + // The persistent ProtoDatabase for storing strike information. + std::unique_ptr<leveldb_proto::ProtoDatabase<StrikeData>> db_; + + // Cached StrikeDatabase entries. + std::map<std::string, StrikeData> strike_map_cache_; + + // Directory where the ProtoDatabase is intialized at. + const base::FilePath database_dir_; + + // Whether or not the ProtoDatabase database has been initialized and entries + // have been loaded. + bool database_initialized_ = false; + + // Number of attempts at initializing the ProtoDatabase. + int num_init_attempts_ = 0; + + private: + FRIEND_TEST_ALL_PREFIXES(ChromeBrowsingDataRemoverDelegateTest, + StrikeDatabaseEmptyOnAutofillRemoveEverything); + friend class StrikeDatabaseTest; + friend class StrikeDatabaseTester; + + void OnDatabaseInit(bool success); + + void OnDatabaseLoadKeysAndEntries( + bool success, + std::unique_ptr<std::map<std::string, StrikeData>> entries); + + // Returns a prefix unique to each project, which will be used to create + // database key. + virtual std::string GetProjectPrefix() = 0; + + // Returns the maximum number of strikes after which the project's Autofill + // opportunity stops being offered. + virtual int GetMaxStrikesLimit() = 0; + + // Generates key based on project-specific string identifier. + std::string GetKey(const std::string id); + + // Passes the number of strikes for |key| to |outer_callback|. In the case + // that the database fails to retrieve the strike update or if no entry is + // found for |key|, 0 is passed. + virtual void GetProtoStrikes(const std::string key, + const StrikesCallback& outer_callback); + + // Removes all database entries, which ensures there will be no saved strikes + // the next time the cache is recreated from the underlying ProtoDatabase. + virtual void ClearAllProtoStrikes(const ClearStrikesCallback& outer_callback); + + // Removes database entry for |key|, which ensures there will be no saved + // strikes the next time the cache is recreated from the underlying + // ProtoDatabase. + virtual void ClearAllProtoStrikesForKey( + const std::string& key, + const ClearStrikesCallback& outer_callback); + + // Passes success status and StrikeData entry for |key| to |inner_callback|. + void GetProtoStrikeData(const std::string key, + const GetValueCallback& inner_callback); + + // Sets the entry for |key| to |strike_data|. Success status is passed to the + // callback. + void SetProtoStrikeData(const std::string& key, + const StrikeData& strike_data, + const SetValueCallback& inner_callback); + + // Passes number of strikes to |outer_callback|. + void OnGetProtoStrikes(StrikesCallback outer_callback, + bool success, + std::unique_ptr<StrikeData> strike_data); + + // Exposed for testing purposes. + void LoadKeys(const LoadKeysCallback& callback); + + // Sets the entry for |key| in |strike_map_cache_| to |data|. + void UpdateCache(const std::string& key, const StrikeData& data); + + base::WeakPtrFactory<StrikeDatabase> weak_ptr_factory_; +}; + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASE_H_
diff --git a/components/autofill/core/browser/strike_database_unittest.cc b/components/autofill/core/browser/strike_database_unittest.cc new file mode 100644 index 0000000..07ea6bbe --- /dev/null +++ b/components/autofill/core/browser/strike_database_unittest.cc
@@ -0,0 +1,237 @@ +// 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/autofill/core/browser/strike_database.h" + +#include <utility> +#include <vector> + +#include "base/files/scoped_temp_dir.h" +#include "base/run_loop.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/autofill/core/browser/proto/strike_data.pb.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace autofill { +namespace { + +// Note: This class is NOT the same as test_strike_database.h. This is an +// actual implementation of StrikeDatabase, but with helper functions +// added for easier test setup. If you want a TestStrikeDatabase, please use the +// one in test_strike_database.h. This one is purely for this unit test class. +class TestStrikeDatabase : public StrikeDatabase { + public: + TestStrikeDatabase(const base::FilePath& database_dir) + : StrikeDatabase(database_dir) { + database_initialized_ = true; + } + + void AddProtoEntries( + std::vector<std::pair<std::string, StrikeData>> entries_to_add, + const SetValueCallback& callback) { + std::unique_ptr<leveldb_proto::ProtoDatabase<StrikeData>::KeyEntryVector> + entries(new leveldb_proto::ProtoDatabase<StrikeData>::KeyEntryVector()); + for (std::pair<std::string, StrikeData> entry : entries_to_add) { + entries->push_back(entry); + } + db_->UpdateEntries( + /*entries_to_save=*/std::move(entries), + /*keys_to_remove=*/std::make_unique<std::vector<std::string>>(), + callback); + } + + private: + DISALLOW_COPY_AND_ASSIGN(TestStrikeDatabase); + + // Do not use. This virtual function needed to be implemented but + // TestStrikeDatabase is not a project class. + std::string GetProjectPrefix() override { + NOTIMPLEMENTED(); + return " "; + } + + // Do not use. This virtual function needed to be implemented but + // TestStrikeDatabase is not a project class. + int GetMaxStrikesLimit() override { + NOTIMPLEMENTED(); + return 0; + } +}; + +} // anonymous namespace + +// Runs tests against the actual StrikeDatabase class, complete with +// ProtoDatabase. +class StrikeDatabaseTest : public ::testing::Test { + public: + StrikeDatabaseTest() : strike_database_(InitFilePath()) {} + + void AddProtoEntries( + std::vector<std::pair<std::string, StrikeData>> entries_to_add) { + base::RunLoop run_loop; + strike_database_.AddProtoEntries( + entries_to_add, + base::BindRepeating(&StrikeDatabaseTest::OnAddProtoEntries, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + } + + void OnAddProtoEntries(base::RepeatingClosure run_loop_closure, + bool success) { + run_loop_closure.Run(); + } + + void OnGetProtoStrikes(base::RepeatingClosure run_loop_closure, + int num_strikes) { + num_strikes_ = num_strikes; + run_loop_closure.Run(); + } + + int GetProtoStrikes(std::string key) { + base::RunLoop run_loop; + strike_database_.GetProtoStrikes( + key, + base::BindRepeating(&StrikeDatabaseTest::OnGetProtoStrikes, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + return num_strikes_; + } + + void OnClearAllProtoStrikesForKey(base::RepeatingClosure run_loop_closure, + bool success) { + run_loop_closure.Run(); + } + + void ClearAllProtoStrikesForKey(const std::string key) { + base::RunLoop run_loop; + strike_database_.ClearAllProtoStrikesForKey( + key, + base::BindRepeating(&StrikeDatabaseTest::OnClearAllProtoStrikesForKey, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + } + + void OnClearAllProtoStrikes(base::RepeatingClosure run_loop_closure, + bool success) { + run_loop_closure.Run(); + } + + void ClearAllProtoStrikes() { + base::RunLoop run_loop; + strike_database_.ClearAllProtoStrikes( + base::BindRepeating(&StrikeDatabaseTest::OnClearAllProtoStrikesForKey, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + } + + protected: + base::HistogramTester* GetHistogramTester() { return &histogram_tester_; } + base::test::ScopedTaskEnvironment scoped_task_environment_; + TestStrikeDatabase strike_database_; + + private: + static const base::FilePath InitFilePath() { + base::ScopedTempDir temp_dir_; + EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); + const base::FilePath file_path = + temp_dir_.GetPath().AppendASCII("StrikeDatabaseTest"); + return file_path; + } + + base::HistogramTester histogram_tester_; + int num_strikes_; + std::unique_ptr<StrikeData> strike_data_; +}; + +TEST_F(StrikeDatabaseTest, GetStrikesForMissingKeyTest) { + const std::string key = "12345"; + int strikes = GetProtoStrikes(key); + EXPECT_EQ(0, strikes); +} + +TEST_F(StrikeDatabaseTest, GetStrikeForNonZeroStrikesTest) { + // Set up database with 3 pre-existing strikes at |key|. + const std::string key = "12345"; + std::vector<std::pair<std::string, StrikeData>> entries; + StrikeData data; + data.set_num_strikes(3); + entries.push_back(std::make_pair(key, data)); + AddProtoEntries(entries); + + int strikes = GetProtoStrikes(key); + EXPECT_EQ(3, strikes); +} + +TEST_F(StrikeDatabaseTest, ClearStrikesForMissingKeyTest) { + const std::string key = "12345"; + ClearAllProtoStrikesForKey(key); + int strikes = GetProtoStrikes(key); + EXPECT_EQ(0, strikes); +} + +TEST_F(StrikeDatabaseTest, ClearStrikesForNonZeroStrikesTest) { + // Set up database with 3 pre-existing strikes at |key|. + const std::string key = "12345"; + std::vector<std::pair<std::string, StrikeData>> entries; + StrikeData data; + data.set_num_strikes(3); + entries.push_back(std::make_pair(key, data)); + AddProtoEntries(entries); + + int strikes = GetProtoStrikes(key); + EXPECT_EQ(3, strikes); + ClearAllProtoStrikesForKey(key); + strikes = GetProtoStrikes(key); + EXPECT_EQ(0, strikes); +} + +TEST_F(StrikeDatabaseTest, ClearStrikesForMultipleNonZeroStrikesEntriesTest) { + // Set up database with 3 pre-existing strikes at |key1|, and 5 pre-existing + // strikes at |key2|. + const std::string key1 = "12345"; + const std::string key2 = "13579"; + std::vector<std::pair<std::string, StrikeData>> entries; + StrikeData data1; + data1.set_num_strikes(3); + entries.push_back(std::make_pair(key1, data1)); + StrikeData data2; + data2.set_num_strikes(5); + entries.push_back(std::make_pair(key2, data2)); + AddProtoEntries(entries); + + int strikes = GetProtoStrikes(key1); + EXPECT_EQ(3, strikes); + strikes = GetProtoStrikes(key2); + EXPECT_EQ(5, strikes); + ClearAllProtoStrikesForKey(key1); + strikes = GetProtoStrikes(key1); + EXPECT_EQ(0, strikes); + strikes = GetProtoStrikes(key2); + EXPECT_EQ(5, strikes); +} + +TEST_F(StrikeDatabaseTest, ClearAllProtoStrikesTest) { + // Set up database with 3 pre-existing strikes at |key1|, and 5 pre-existing + // strikes at |key2|. + const std::string key1 = "12345"; + const std::string key2 = "13579"; + std::vector<std::pair<std::string, StrikeData>> entries; + StrikeData data1; + data1.set_num_strikes(3); + entries.push_back(std::make_pair(key1, data1)); + StrikeData data2; + data2.set_num_strikes(5); + entries.push_back(std::make_pair(key2, data2)); + AddProtoEntries(entries); + + EXPECT_EQ(3, GetProtoStrikes(key1)); + EXPECT_EQ(5, GetProtoStrikes(key2)); + ClearAllProtoStrikes(); + EXPECT_EQ(0, GetProtoStrikes(key1)); + EXPECT_EQ(0, GetProtoStrikes(key2)); +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/test_strike_database.cc b/components/autofill/core/browser/test_strike_database.cc new file mode 100644 index 0000000..bb242f4 --- /dev/null +++ b/components/autofill/core/browser/test_strike_database.cc
@@ -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. + +#include "components/autofill/core/browser/test_strike_database.h" + +#include "components/autofill/core/browser/proto/strike_data.pb.h" + +namespace autofill { + +TestStrikeDatabase::TestStrikeDatabase() {} + +TestStrikeDatabase::~TestStrikeDatabase() {} + +void TestStrikeDatabase::GetProtoStrikes( + const std::string key, + const StrikesCallback& outer_callback) { + outer_callback.Run(GetStrikesForTesting(key)); +} + +void TestStrikeDatabase::ClearAllProtoStrikes( + const ClearStrikesCallback& outer_callback) { + db_.clear(); + outer_callback.Run(/*success=*/true); +} + +void TestStrikeDatabase::ClearAllProtoStrikesForKey( + const std::string& key, + const ClearStrikesCallback& outer_callback) { + db_.erase(key); + outer_callback.Run(/*success=*/true); +} + +void TestStrikeDatabase::AddEntryWithNumStrikes(const std::string& key, + int num_strikes) { + StrikeData strike_data; + strike_data.set_num_strikes(num_strikes); + strike_data.set_last_update_timestamp( + base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds()); + db_[key] = strike_data; +} + +int TestStrikeDatabase::GetStrikesForTesting(const std::string& key) { + std::unordered_map<std::string, StrikeData>::iterator it = db_.find(key); + if (it != db_.end()) + return it->second.num_strikes(); + return 0; +} + +} // namespace autofill
diff --git a/components/autofill/core/browser/test_strike_database.h b/components/autofill/core/browser/test_strike_database.h new file mode 100644 index 0000000..ebe7731 --- /dev/null +++ b/components/autofill/core/browser/test_strike_database.h
@@ -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. + +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_STRIKE_DATABASE_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_STRIKE_DATABASE_H_ + +#include <memory> +#include <string> +#include <unordered_map> +#include <utility> +#include <vector> + +#include "components/autofill/core/browser/strike_database.h" + +namespace autofill { + +// An in-memory-only test version of StrikeDatabase. +class TestStrikeDatabase : public StrikeDatabase { + public: + TestStrikeDatabase(); + ~TestStrikeDatabase() override; + + // StrikeDatabase: + void GetProtoStrikes(const std::string key, + const StrikesCallback& outer_callback) override; + void ClearAllProtoStrikes( + const ClearStrikesCallback& outer_callback) override; + void ClearAllProtoStrikesForKey( + const std::string& key, + const ClearStrikesCallback& outer_callback) override; + + // TestStrikeDatabase: + void AddEntryWithNumStrikes(const std::string& key, int num_strikes); + int GetStrikesForTesting(const std::string& key); + + private: + // In-memory database of StrikeData. + std::unordered_map<std::string, StrikeData> db_; +}; + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_STRIKE_DATABASE_H_
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc index 51c0465..9699f36 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc +++ b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
@@ -64,7 +64,6 @@ void AutofillWalletSyncBridge::CreateForWebDataServiceAndBackend( const std::string& app_locale, const base::RepeatingCallback<void(bool)>& active_callback, - bool has_persistent_storage, AutofillWebDataBackend* web_data_backend, AutofillWebDataService* web_data_service) { web_data_service->GetDBUserData()->SetUserData( @@ -74,7 +73,7 @@ std::make_unique<syncer::ClientTagBasedModelTypeProcessor>( syncer::AUTOFILL_WALLET_DATA, /*dump_stack=*/base::RepeatingClosure()), - has_persistent_storage, web_data_backend)); + web_data_backend)); } // static @@ -88,10 +87,8 @@ AutofillWalletSyncBridge::AutofillWalletSyncBridge( const base::RepeatingCallback<void(bool)>& active_callback, std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor, - bool has_persistent_storage, AutofillWebDataBackend* web_data_backend) : ModelTypeSyncBridge(std::move(change_processor)), - has_persistent_storage_(has_persistent_storage), active_callback_(active_callback), initial_sync_done_(false), web_data_backend_(web_data_backend) { @@ -267,21 +264,13 @@ // Extract the Autofill types from the sync |entity_data|. std::vector<CreditCard> wallet_cards; + std::vector<AutofillProfile> wallet_addresses; std::vector<PaymentsCustomerData> customer_data; - if (has_persistent_storage_) { - // When in persistent storage mode, we update wallet addresses. - std::vector<AutofillProfile> wallet_addresses; - PopulateWalletTypesFromSyncData(entity_data, &wallet_cards, - &wallet_addresses, &customer_data); - wallet_data_changed |= SetWalletAddresses(std::move(wallet_addresses)); - } else { - // When in ephemeral storage mode, we ignore wallet addresses. - PopulateWalletTypesFromSyncData(entity_data, &wallet_cards, nullptr, - &customer_data); - } + PopulateWalletTypesFromSyncData(entity_data, &wallet_cards, &wallet_addresses, + &customer_data); - // In both cases, we need to update wallet cards and payments customer data. wallet_data_changed |= SetWalletCards(std::move(wallet_cards)); + wallet_data_changed |= SetWalletAddresses(std::move(wallet_addresses)); wallet_data_changed |= SetPaymentsCustomerData(std::move(customer_data)); if (web_data_backend_ && wallet_data_changed)
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h index d5d37a1b..07c99809 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h +++ b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h
@@ -40,7 +40,6 @@ static void CreateForWebDataServiceAndBackend( const std::string& app_locale, const base::RepeatingCallback<void(bool)>& active_callback, - bool has_persistent_storage_, AutofillWebDataBackend* webdata_backend, AutofillWebDataService* web_data_service); @@ -50,7 +49,6 @@ explicit AutofillWalletSyncBridge( const base::RepeatingCallback<void(bool)>& active_callback, std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor, - bool has_persistent_storage_, AutofillWebDataBackend* web_data_backend); ~AutofillWalletSyncBridge() override; @@ -123,11 +121,6 @@ // processor so that it can start tracking changes. void LoadMetadata(); - // Stores whether this bridge is connected to the persistent storage (as part - // of the complete sync feature) or to an ephemeral storage (as part of the - // content-area-account-based lightweight sync). - const bool has_persistent_storage_; - // Callback to let the metadata bridge know that whether the card data // is actively syncing. const base::RepeatingCallback<void(bool)> active_callback_;
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc index 7d7a12229..df87843c 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc
@@ -221,9 +221,9 @@ model_type_state.set_initial_sync_done(initial_sync_done); EXPECT_TRUE(table()->UpdateModelTypeState(syncer::AUTOFILL_WALLET_DATA, model_type_state)); - bridge_.reset(new AutofillWalletSyncBridge( + bridge_ = std::make_unique<AutofillWalletSyncBridge>( active_callback_.Get(), mock_processor_.CreateForwardingProcessor(), - UseFullSync(), &backend_)); + &backend_); } void StartSyncing( @@ -332,8 +332,6 @@ return &active_callback_; }; - virtual bool UseFullSync() { return true; } - private: autofill::TestAutofillClock test_clock_; ScopedTempDir temp_dir_; @@ -795,113 +793,4 @@ bridge()->ApplyStopSyncChanges(/*delete_metadata_change_list=*/nullptr); } -class AutofillWalletEphemeralSyncBridgeTest - : public AutofillWalletSyncBridgeTest { - public: - AutofillWalletEphemeralSyncBridgeTest() {} - ~AutofillWalletEphemeralSyncBridgeTest() override {} - - bool UseFullSync() override { return false; } -}; - -// Tests that when the server sends no cards, the client should delete all it's -// existing data. -TEST_F(AutofillWalletEphemeralSyncBridgeTest, MergeSyncData_NoWalletCard) { - // Create one card on the client. - CreditCard local_card = test::GetMaskedServerCard(); - table()->SetServerCreditCards({local_card}); - - EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()); - EXPECT_CALL(*backend(), - NotifyOfCreditCardChanged(RemoveChange(local_card.guid()))); - StartSyncing({}); - - EXPECT_TRUE(GetAllLocalData().empty()); - ExpectCardsDiffInHistograms(/*added=*/0, /*removed=*/1); -} - -// Test that when the server sends the same card as the client has, nothing -// changes on the client. -TEST_F(AutofillWalletEphemeralSyncBridgeTest, MergeSyncData_SameWalletCard) { - // Create one card on the client. - CreditCard card = test::GetMaskedServerCard(); - table()->SetServerCreditCards({card}); - - // Create the same card on the server. - AutofillWalletSpecifics card_specifics; - SetAutofillWalletSpecificsFromServerCard(card, &card_specifics); - - EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0); - EXPECT_CALL(*backend(), NotifyOfCreditCardChanged(_)).Times(0); - StartSyncing({card_specifics}); - - EXPECT_THAT(GetAllLocalData(), - UnorderedElementsAre(EqualsSpecifics(card_specifics))); - ExpectCardsDiffInHistograms(/*added=*/0, /*removed=*/0); -} - -// Tests that when a new wallet card is sent by the server, the client only -// keeps the new card. -TEST_F(AutofillWalletEphemeralSyncBridgeTest, MergeSyncData_NewWalletCard) { - // Create one card on the client. - CreditCard card1 = test::GetMaskedServerCard(); - table()->SetServerCreditCards({card1}); - PaymentsCustomerData customer_data{/*customer_id=*/kCustomerDataId}; - table()->SetPaymentsCustomerData(&customer_data); - - // Create a different card on the server. - CreditCard card2 = test::GetMaskedServerCardAmex(); - AutofillWalletSpecifics card_specifics2; - SetAutofillWalletSpecificsFromServerCard(card2, &card_specifics2); - AutofillWalletSpecifics customer_data_specifics; - SetAutofillWalletSpecificsFromPaymentsCustomerData(customer_data, - &customer_data_specifics); - - EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()); - EXPECT_CALL(*backend(), - NotifyOfCreditCardChanged(RemoveChange(card1.guid()))); - EXPECT_CALL(*backend(), - NotifyOfCreditCardChanged(AddChange(card2.guid(), card2))); - StartSyncing({card_specifics2, customer_data_specifics}); - - // Only the server card should be present on the client. - EXPECT_THAT(GetAllLocalData(), - UnorderedElementsAre(EqualsSpecifics(card_specifics2), - EqualsSpecifics(customer_data_specifics))); - ExpectCardsDiffInHistograms(/*added=*/1, /*removed=*/1); -} - -// Tests that when a new wallet card and new wallet address are sent by the -// server, the client only keeps the new card and disregards the address. -TEST_F(AutofillWalletEphemeralSyncBridgeTest, - MergeSyncData_AddressesAreDropped) { - // Create one card on the client. - CreditCard card1 = test::GetMaskedServerCard(); - table()->SetServerCreditCards({card1}); - PaymentsCustomerData customer_data{/*customer_id=*/kCustomerDataId}; - table()->SetPaymentsCustomerData(&customer_data); - - // Create a new profile and a different card on the server. - AutofillProfile address = test::GetServerProfile(); - AutofillWalletSpecifics profile_specifics; - SetAutofillWalletSpecificsFromServerProfile(address, &profile_specifics); - CreditCard card2 = test::GetMaskedServerCardAmex(); - AutofillWalletSpecifics card_specifics2; - SetAutofillWalletSpecificsFromServerCard(card2, &card_specifics2); - AutofillWalletSpecifics customer_data_specifics; - SetAutofillWalletSpecificsFromPaymentsCustomerData(customer_data, - &customer_data_specifics); - - EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(_)).Times(0); - StartSyncing({profile_specifics, card_specifics2, customer_data_specifics}); - - // Only the server card should be present on the client; the server profile is - // ignored. - EXPECT_THAT(GetAllLocalData(), - UnorderedElementsAre(EqualsSpecifics(card_specifics2), - EqualsSpecifics(customer_data_specifics))); - // Nothing gets recorded for addresses - they are completely disregarded. - ExpectNoHistogramsForAddressesDiff(); -} - } // namespace autofill
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index d7004b7..5e4ab82 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -67,7 +67,7 @@ // Controls whether Autofill attemps to fill dynamically changing forms. const base::Feature kAutofillDynamicForms{"AutofillDynamicForms", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Controls whether the server credit cards are saved only in the ephemeral // account-based storage, instead of the persistent local storage.
diff --git a/components/autofill_assistant/browser/web_controller.cc b/components/autofill_assistant/browser/web_controller.cc index 2ecd03a..9591cf3 100644 --- a/components/autofill_assistant/browser/web_controller.cc +++ b/components/autofill_assistant/browser/web_controller.cc
@@ -57,6 +57,11 @@ node.scrollIntoViewIfNeeded(); })"; +const char* const kScrollIntoViewIfNeededScript = + R"(function(node) { + node.scrollIntoViewIfNeeded(); + })"; + const char* const kScrollByScript = R"(window.scrollBy(%f * window.visualViewport.width, %f * window.visualViewport.height))"; @@ -208,15 +213,17 @@ // Return the center of the element. const std::vector<double>* content_box = result->GetModel()->GetContent(); DCHECK_EQ(content_box->size(), 8u); - int x = round((round((*content_box)[0]) + round((*content_box)[2])) * 0.5); - int y = round((round((*content_box)[3]) + round((*content_box)[5])) * 0.5); + int new_point_x = + round((round((*content_box)[0]) + round((*content_box)[2])) * 0.5); + int new_point_y = + round((round((*content_box)[3]) + round((*content_box)[5])) * 0.5); // Wait for at least three rounds (~600ms = // 3*kPeriodicBoxModelCheckInterval) for visual state update callback since // it might take longer time to return or never return if no updates. DCHECK(kPeriodicBoxModelCheckRounds > 2 && kPeriodicBoxModelCheckRounds >= remaining_rounds); - if (x == point_x && y == point_y && + if (new_point_x == point_x && new_point_y == point_y && (visual_state_updated_ || remaining_rounds + 2 < kPeriodicBoxModelCheckRounds)) { // Note that there is still a chance that the element's position has been @@ -225,7 +232,7 @@ // click or tap event after stable for kPeriodicBoxModelCheckInterval. In // addition, checking again after issuing click or tap event doesn't help // since the change may be expected. - OnResult(x, y); + OnResult(new_point_x, new_point_y); return; } @@ -234,12 +241,54 @@ return; } + // Scroll the element into view again if it was moved out of view. + // Check 'point_x' amd 'point_y' are greater or equal than zero to escape the + // first round. + if (point_x >= 0 && point_y >= 0) { + std::vector<std::unique_ptr<runtime::CallArgument>> argument; + argument.emplace_back( + runtime::CallArgument::Builder().SetObjectId(object_id).Build()); + devtools_client->GetRuntime()->CallFunctionOn( + runtime::CallFunctionOnParams::Builder() + .SetObjectId(object_id) + .SetArguments(std::move(argument)) + .SetFunctionDeclaration(std::string(kScrollIntoViewIfNeededScript)) + .SetReturnByValue(true) + .Build(), + base::BindOnce(&WebController::ElementPositionGetter::OnScrollIntoView, + weak_ptr_factory_.GetWeakPtr(), devtools_client, + object_id, new_point_x, new_point_y, remaining_rounds)); + return; + } + base::PostDelayedTaskWithTraits( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce( &WebController::ElementPositionGetter::GetAndWaitBoxModelStable, - weak_ptr_factory_.GetWeakPtr(), devtools_client, object_id, x, y, - --remaining_rounds), + weak_ptr_factory_.GetWeakPtr(), devtools_client, object_id, + new_point_x, new_point_y, --remaining_rounds), + kPeriodicBoxModelCheckInterval); +} + +void WebController::ElementPositionGetter::OnScrollIntoView( + DevtoolsClient* devtools_client, + std::string object_id, + int point_x, + int point_y, + int remaining_rounds, + std::unique_ptr<runtime::CallFunctionOnResult> result) { + if (!result || result->HasExceptionDetails()) { + DLOG(ERROR) << "Failed to scroll the element."; + OnResult(-1, -1); + return; + } + + base::PostDelayedTaskWithTraits( + FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce( + &WebController::ElementPositionGetter::GetAndWaitBoxModelStable, + weak_ptr_factory_.GetWeakPtr(), devtools_client, object_id, point_x, + point_y, --remaining_rounds), kPeriodicBoxModelCheckInterval); }
diff --git a/components/autofill_assistant/browser/web_controller.h b/components/autofill_assistant/browser/web_controller.h index 52a9591..bb2b7267 100644 --- a/components/autofill_assistant/browser/web_controller.h +++ b/components/autofill_assistant/browser/web_controller.h
@@ -193,6 +193,13 @@ int point_y, int remaining_rounds, std::unique_ptr<dom::GetBoxModelResult> result); + void OnScrollIntoView( + DevtoolsClient* devtools_client, + std::string object_id, + int point_x, + int point_y, + int remaining_rounds, + std::unique_ptr<runtime::CallFunctionOnResult> result); void OnResult(int x, int y); base::OnceCallback<void(int, int)> callback_;
diff --git a/components/autofill_assistant/browser/web_controller_browsertest.cc b/components/autofill_assistant/browser/web_controller_browsertest.cc index bd084cb..65a2b1f 100644 --- a/components/autofill_assistant/browser/web_controller_browsertest.cc +++ b/components/autofill_assistant/browser/web_controller_browsertest.cc
@@ -446,6 +446,13 @@ WaitForElementRemove(selectors); } +IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, TapElementMovingOutOfView) { + std::vector<std::string> selectors; + selectors.emplace_back("#touch_area_three"); + TapElement(selectors); + WaitForElementRemove(selectors); +} + IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, TapElementAfterPageIsIdle) { // Set a very long timeout to make sure either the page is idle or the test // timeout.
diff --git a/components/autofill_strings.grdp b/components/autofill_strings.grdp index d9a9729..e15dc25 100644 --- a/components/autofill_strings.grdp +++ b/components/autofill_strings.grdp
@@ -348,7 +348,7 @@ Enter the expiration date and CVC for <ph name="CREDIT_CARD">$1<ex>Visa - 5679</ex></ph> </message> <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS" desc="Text explaining what the user should do in the card unmasking dialog."> - After you confirm, card details from your Google Payments account will be shared with this site. + After you confirm, card details from your Google Account will be shared with this site. </message> <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS_LOCAL_CARD" desc="Text explaining what the user should do in the card unmasking dialog. Appears specifically for local cards already stored on the device."> Once you confirm, your card details will be shared with this site. @@ -362,13 +362,13 @@ Confirm Card </message> <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS" desc="Text explaining what the user should do in the card unmasking dialog."> - Enter the CVC for <ph name="CREDIT_CARD">$1<ex>Visa - 5679</ex></ph>. After you confirm, card details from your Google Payments account will be shared with this site. + Enter the CVC for <ph name="CREDIT_CARD">$1<ex>Visa - 5679</ex></ph>. After you confirm, card details from your Google Account will be shared with this site. </message> <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS_LOCAL_CARD" desc="Text explaining what the user should do in the card unmasking dialog. Appears specifically for local cards already stored on the device."> Enter the CVC for <ph name="CREDIT_CARD">$1<ex>Visa - 5679</ex></ph>. Once you confirm, your card details will be shared with this site. </message> <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS_EXPIRED" desc="Text explaining what the user should do in the card unmasking dialog to update an expired card."> - Enter the expiration date and CVC for <ph name="CREDIT_CARD">$1<ex>Visa - 5679</ex></ph> to update your card details. After you confirm, card details from your Google Payments account will be shared with this site. + Enter the expiration date and CVC for <ph name="CREDIT_CARD">$1<ex>Visa - 5679</ex></ph> to update your card details. After you confirm, card details from your Google Account will be shared with this site. </message> <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS_EXPIRED_LOCAL_CARD" desc="Text explaining what the user should do in the card unmasking dialog to update an expired card. Appears specifically for local cards already stored on the device."> Enter the expiration date and CVC for <ph name="CREDIT_CARD">$1<ex>Visa - 5679</ex></ph> to update your card details. Once you confirm, your card details will be shared with this site.
diff --git a/components/components_strings.grd b/components/components_strings.grd index d539c1a..045961b 100644 --- a/components/components_strings.grd +++ b/components/components_strings.grd
@@ -242,6 +242,14 @@ <message name="IDS_SAVE" desc="Used on a button to save information you are editing."> Save </message> + <if expr="is_android"> + <message name="IDS_SHOW" desc="Generic label to show content for a feature. [CHAR-LIMIT=20]" formatter_data="android_java"> + Show + </message> + <message name="IDS_HIDE" desc="Generic label to hide content for a feature. [CHAR-LIMIT=20]" formatter_data="android_java"> + Hide + </message> + </if> <if expr="not use_titlecase"> <message name="IDS_NO_THANKS" desc="Used to dismiss various prompts."> No thanks
diff --git a/components/components_strings_grd/IDS_HIDE.png.sha1 b/components/components_strings_grd/IDS_HIDE.png.sha1 new file mode 100644 index 0000000..34d9d7f --- /dev/null +++ b/components/components_strings_grd/IDS_HIDE.png.sha1
@@ -0,0 +1 @@ +38ecae590d6814c16186782d4136f2a709e491dc \ No newline at end of file
diff --git a/components/components_strings_grd/IDS_SHOW.png.sha1 b/components/components_strings_grd/IDS_SHOW.png.sha1 new file mode 100644 index 0000000..966deb02 --- /dev/null +++ b/components/components_strings_grd/IDS_SHOW.png.sha1
@@ -0,0 +1 @@ +5729c98023bb700bb346fe357623c8444a8bfafb \ No newline at end of file
diff --git a/components/country_codes/BUILD.gn b/components/country_codes/BUILD.gn new file mode 100644 index 0000000..2259c46b --- /dev/null +++ b/components/country_codes/BUILD.gn
@@ -0,0 +1,18 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/features.gni") +static_library("country_codes") { + sources = [ + "country_codes.cc", + "country_codes.h", + ] + + deps = [ + "//base", + "//components/pref_registry", + "//components/prefs", + "//components/sync", + ] +}
diff --git a/components/country_codes/DEPS b/components/country_codes/DEPS new file mode 100644 index 0000000..4876dc70 --- /dev/null +++ b/components/country_codes/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+components/pref_registry", + "+components/prefs", +]
diff --git a/components/country_codes/OWNERS b/components/country_codes/OWNERS new file mode 100644 index 0000000..76dd81a --- /dev/null +++ b/components/country_codes/OWNERS
@@ -0,0 +1,5 @@ +jdonnelly@chromium.org +scottchen@chromium.org +pkasting@chromium.org + +# COMPONENT: Internals>Core
diff --git a/components/country_codes/country_codes.cc b/components/country_codes/country_codes.cc new file mode 100644 index 0000000..5d1081a --- /dev/null +++ b/components/country_codes/country_codes.cc
@@ -0,0 +1,203 @@ +// 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/country_codes/country_codes.h" + +#if defined(OS_POSIX) && !defined(OS_MACOSX) +#include <locale.h> +#endif + +#include "base/strings/string_util.h" +#include "build/build_config.h" +#include "components/pref_registry/pref_registry_syncable.h" +#include "components/prefs/pref_service.h" + +#if defined(OS_WIN) +#include <windows.h> +#undef IN // On Windows, windef.h defines this, which screws up "India" cases. +#elif defined(OS_MACOSX) +#include "base/mac/scoped_cftyperef.h" +#endif + +#if defined(OS_ANDROID) +#include "base/android/locale_utils.h" +#endif + +namespace country_codes { + +namespace { + +int CountryCharsToCountryID(char c1, char c2) { + return c1 << 8 | c2; +} + +// TODO(scottchen): remove this function after confirming if it only pertains +// to obsolete OSes. +int CountryCharsToCountryIDWithUpdate(char c1, char c2) { + // SPECIAL CASE: In 2003, Yugoslavia renamed itself to Serbia and Montenegro. + // Serbia and Montenegro dissolved their union in June 2006. Yugoslavia was + // ISO 'YU' and Serbia and Montenegro were ISO 'CS'. Serbia was subsequently + // issued 'RS' and Montenegro 'ME'. Windows XP and Mac OS X Leopard still use + // the value 'YU'. If we get a value of 'YU' or 'CS' we will map it to 'RS'. + if ((c1 == 'Y' && c2 == 'U') || (c1 == 'C' && c2 == 'S')) { + c1 = 'R'; + c2 = 'S'; + } + + // SPECIAL CASE: Timor-Leste changed from 'TP' to 'TL' in 2002. Windows XP + // predates this; we therefore map this value. + if (c1 == 'T' && c2 == 'P') + c2 = 'L'; + + return CountryCharsToCountryID(c1, c2); +} + +#if defined(OS_WIN) + +// For reference, a list of GeoIDs can be found at +// http://msdn.microsoft.com/en-us/library/dd374073.aspx . +int GeoIDToCountryID(GEOID geo_id) { + const int kISOBufferSize = 3; // Two plus one for the terminator. + wchar_t isobuf[kISOBufferSize] = {}; + int retval = GetGeoInfo(geo_id, GEO_ISO2, isobuf, kISOBufferSize, 0); + + if (retval == kISOBufferSize && !(isobuf[0] == L'X' && isobuf[1] == L'X')) { + return CountryCharsToCountryIDWithUpdate(static_cast<char>(isobuf[0]), + static_cast<char>(isobuf[1])); + } + + // Various locations have ISO codes that Windows does not return. + switch (geo_id) { + case 0x144: // Guernsey + return CountryCharsToCountryID('G', 'G'); + case 0x148: // Jersey + return CountryCharsToCountryID('J', 'E'); + case 0x3B16: // Isle of Man + return CountryCharsToCountryID('I', 'M'); + + // 'UM' (U.S. Minor Outlying Islands) + case 0x7F: // Johnston Atoll + case 0x102: // Wake Island + case 0x131: // Baker Island + case 0x146: // Howland Island + case 0x147: // Jarvis Island + case 0x149: // Kingman Reef + case 0x152: // Palmyra Atoll + case 0x52FA: // Midway Islands + return CountryCharsToCountryID('U', 'M'); + + // 'SH' (Saint Helena) + case 0x12F: // Ascension Island + case 0x15C: // Tristan da Cunha + return CountryCharsToCountryID('S', 'H'); + + // 'IO' (British Indian Ocean Territory) + case 0x13A: // Diego Garcia + return CountryCharsToCountryID('I', 'O'); + + // Other cases where there is no ISO country code; we assign countries that + // can serve as reasonable defaults. + case 0x154: // Rota Island + case 0x155: // Saipan + case 0x15A: // Tinian Island + return CountryCharsToCountryID('U', 'S'); + case 0x134: // Channel Islands + return CountryCharsToCountryID('G', 'B'); + case 0x143: // Guantanamo Bay + default: + return kCountryIDUnknown; + } +} + +#endif // defined(OS_WIN) + +} // namespace + +const char kCountryIDAtInstall[] = "countryid_at_install"; + +#if !defined(OS_WIN) && !defined(OS_MACOSX) + +int CountryStringToCountryID(const std::string& country) { + return (country.length() == 2) + ? CountryCharsToCountryIDWithUpdate(country[0], country[1]) + : kCountryIDUnknown; +} + +#endif + +int GetCountryIDFromPrefs(PrefService* prefs) { + if (!prefs) + return GetCurrentCountryID(); + + // Cache first run Country ID value in prefs, and use it afterwards. This + // ensures that just because the user moves around, we won't automatically + // make major changes to their available search providers, which would feel + // surprising. + if (!prefs->HasPrefPath(country_codes::kCountryIDAtInstall)) { + prefs->SetInteger(country_codes::kCountryIDAtInstall, + GetCurrentCountryID()); + } + return prefs->GetInteger(country_codes::kCountryIDAtInstall); +} + +void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { + registry->RegisterIntegerPref(country_codes::kCountryIDAtInstall, + kCountryIDUnknown); +} + +#if defined(OS_WIN) + +int GetCurrentCountryID() { + return GeoIDToCountryID(GetUserGeoID(GEOCLASS_NATION)); +} + +#elif defined(OS_MACOSX) + +int GetCurrentCountryID() { + base::ScopedCFTypeRef<CFLocaleRef> locale(CFLocaleCopyCurrent()); + CFStringRef country = + (CFStringRef)CFLocaleGetValue(locale.get(), kCFLocaleCountryCode); + if (!country) + return kCountryIDUnknown; + + UniChar isobuf[2]; + CFRange char_range = CFRangeMake(0, 2); + CFStringGetCharacters(country, char_range, isobuf); + + return CountryCharsToCountryIDWithUpdate(static_cast<char>(isobuf[0]), + static_cast<char>(isobuf[1])); +} + +#elif defined(OS_ANDROID) + +int GetCurrentCountryID() { + return CountryStringToCountryID(base::android::GetDefaultCountryCode()); +} + +#elif defined(OS_POSIX) || defined(OS_FUCHSIA) + +int GetCurrentCountryID() { + const char* locale = setlocale(LC_MESSAGES, nullptr); + if (!locale) + return kCountryIDUnknown; + + // The format of a locale name is: + // language[_territory][.codeset][@modifier], where territory is an ISO 3166 + // country code, which is what we want. + + // First remove the language portion. + std::string locale_str(locale); + size_t territory_delim = locale_str.find('_'); + if (territory_delim == std::string::npos) + return kCountryIDUnknown; + locale_str.erase(0, territory_delim + 1); + + // Next remove any codeset/modifier portion and uppercase. + return CountryStringToCountryID( + base::ToUpperASCII(locale_str.substr(0, locale_str.find_first_of(".@")))); +} + +#endif // OS_* + +} // namespace country_codes
diff --git a/components/country_codes/country_codes.h b/components/country_codes/country_codes.h new file mode 100644 index 0000000..93cf88e --- /dev/null +++ b/components/country_codes/country_codes.h
@@ -0,0 +1,51 @@ +// 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. + +// Please refer to ISO 3166-1 for information about the two-character country +// codes; http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 is useful. In the +// following (C++) code, we pack the two letters of the country code into an int +// value we call the CountryID. + +#ifndef COMPONENTS_COUNTRY_CODES_COUNTRY_CODES_H_ +#define COMPONENTS_COUNTRY_CODES_COUNTRY_CODES_H_ + +#include <string> + +class PrefService; + +namespace user_prefs { +class PrefRegistrySyncable; +} + +namespace country_codes { + +// Integer containing the system Country ID the first time we checked the +// template URL prepopulate data. This is used to avoid adding a whole bunch of +// new search engine choices if prepopulation runs when the user's Country ID +// differs from their previous Country ID. This pref does not exist until +// prepopulation has been run at least once. +extern const char kCountryIDAtInstall[]; + +const int kCountryIDUnknown = -1; + +void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); + +// Returns the identifier for the user current country. Used to update the list +// of search engines when user switches device region settings. For use on iOS +// only. +// TODO(ios): Once user can customize search engines ( http://crbug.com/153047 ) +// this declaration should be removed and the definition in the .cc file be +// moved back to the anonymous namespace. +int GetCurrentCountryID(); + +// Converts a two-letter country code to an integer-based country identifier. +int CountryStringToCountryID(const std::string& country); + +// Returns the country identifier that was stored at install. If no such pref +// is available, it will return identifier of the current country instead. +int GetCountryIDFromPrefs(PrefService* prefs); + +} // namespace country_codes + +#endif // COMPONENTS_COUNTRY_CODES_COUNTRY_CODES_H_
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc index ecbf8ff..a0dd02d 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
@@ -252,8 +252,10 @@ // If Data Saver is disabled, reset data reduction proxy state. if (!enabled) { - // TODO(crbug.com/721403): Make DRP work with network service. - if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) { + if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { + if (proxy_config_client_) + proxy_config_client_->ClearBadProxiesCache(); + } else { net::ProxyResolutionService* proxy_resolution_service = url_request_context_getter_->GetURLRequestContext() ->proxy_resolution_service();
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc index 9a9e8ee..020c266 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
@@ -239,6 +239,8 @@ const net::ProxyList& bad_proxies, MarkProxiesAsBadCallback callback) override {} + void ClearBadProxiesCache() override {} + network::mojom::CustomProxyConfigPtr config; private:
diff --git a/components/dom_distiller/core/dom_distiller_store_unittest.cc b/components/dom_distiller/core/dom_distiller_store_unittest.cc index 762a8f5..ce188a3 100644 --- a/components/dom_distiller/core/dom_distiller_store_unittest.cc +++ b/components/dom_distiller/core/dom_distiller_store_unittest.cc
@@ -148,8 +148,7 @@ protected: SyncData CreateSyncData(const ArticleEntry& entry) { EntitySpecifics specifics = SpecificsFromEntry(entry); - return SyncData::CreateRemoteData(next_sync_id_++, specifics, - Time::UnixEpoch()); + return SyncData::CreateRemoteData(next_sync_id_++, specifics); } SyncDataList SyncDataFromEntryMap(const EntryMap& model) {
diff --git a/components/error_page/common/localized_error.cc b/components/error_page/common/localized_error.cc index 8c60334..fcaaed49 100644 --- a/components/error_page/common/localized_error.cc +++ b/components/error_page/common/localized_error.cc
@@ -1107,6 +1107,12 @@ {"offlineContentList", "actionText"}, base::Value(l10n_util::GetStringUTF16( IDS_ERRORPAGES_OFFLINE_CONTENT_LIST_OPEN_ALL_BUTTON))); + error_strings->SetPath( + {"offlineContentList", "showText"}, + base::Value(l10n_util::GetStringUTF16(IDS_SHOW))); + error_strings->SetPath( + {"offlineContentList", "hideText"}, + base::Value(l10n_util::GetStringUTF16(IDS_HIDE))); break; case OfflineContentOnNetErrorFeatureState::kEnabledSummary: error_strings->SetString("suggestedOfflineContentPresentationMode",
diff --git a/components/error_page/common/net_error_info.h b/components/error_page/common/net_error_info.h index 4208007d..e0f25b9 100644 --- a/components/error_page/common/net_error_info.h +++ b/components/error_page/common/net_error_info.h
@@ -57,14 +57,18 @@ // Values for suggested content on the net-error page: - // At least one offline content suggestion was shown. + // A list containing at least one item of offline content suggestions was + // shown in the expanded/shown state. NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN = 24, - // An offline content suggestion was clicked. + // An item from the offline content suggestions list was clicked. NETWORK_ERROR_PAGE_OFFLINE_SUGGESTION_CLICKED = 25, // A link that opens the downloads page was clicked. NETWORK_ERROR_PAGE_OFFLINE_DOWNLOADS_PAGE_CLICKED = 26, // A summary of available offline content was shown. NETWORK_ERROR_PAGE_OFFLINE_CONTENT_SUMMARY_SHOWN = 27, + // A list containing at least one item of offline content suggestions was + // shown in the collapsed/hidden state. + NETWORK_ERROR_PAGE_OFFLINE_SUGGESTIONS_SHOWN_COLLAPSED = 28, NETWORK_ERROR_PAGE_EVENT_MAX, };
diff --git a/components/history/core/browser/history_service_unittest.cc b/components/history/core/browser/history_service_unittest.cc index 835a025..631a6a5 100644 --- a/components/history/core/browser/history_service_unittest.cc +++ b/components/history/core/browser/history_service_unittest.cc
@@ -749,8 +749,7 @@ .ToInternalValue()); global_id_directive->set_start_time_usec(3); global_id_directive->set_end_time_usec(10); - directives.push_back( - syncer::SyncData::CreateRemoteData(1, entity_specs, base::Time())); + directives.push_back(syncer::SyncData::CreateRemoteData(1, entity_specs)); // 2nd directive. global_id_directive->Clear(); @@ -759,8 +758,7 @@ .ToInternalValue()); global_id_directive->set_start_time_usec(13); global_id_directive->set_end_time_usec(19); - directives.push_back( - syncer::SyncData::CreateRemoteData(2, entity_specs, base::Time())); + directives.push_back(syncer::SyncData::CreateRemoteData(2, entity_specs)); syncer::FakeSyncChangeProcessor change_processor; EXPECT_FALSE(history_service_ @@ -827,15 +825,13 @@ ->mutable_time_range_directive(); time_range_directive->set_start_time_usec(2); time_range_directive->set_end_time_usec(5); - directives.push_back( - syncer::SyncData::CreateRemoteData(1, entity_specs, base::Time())); + directives.push_back(syncer::SyncData::CreateRemoteData(1, entity_specs)); // 2nd directive. time_range_directive->Clear(); time_range_directive->set_start_time_usec(8); time_range_directive->set_end_time_usec(10); - directives.push_back( - syncer::SyncData::CreateRemoteData(2, entity_specs, base::Time())); + directives.push_back(syncer::SyncData::CreateRemoteData(2, entity_specs)); syncer::FakeSyncChangeProcessor change_processor; EXPECT_FALSE(history_service_
diff --git a/components/metrics/data_use_tracker.cc b/components/metrics/data_use_tracker.cc index 1588b89..0cb37b0 100644 --- a/components/metrics/data_use_tracker.cc +++ b/components/metrics/data_use_tracker.cc
@@ -8,7 +8,6 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" -#include "build/build_config.h" #include "components/metrics/metrics_pref_names.h" #include "components/prefs/scoped_user_pref_update.h" #include "components/variations/variations_associated_data.h" @@ -34,8 +33,6 @@ std::unique_ptr<DataUseTracker> DataUseTracker::Create( PrefService* local_state) { std::unique_ptr<DataUseTracker> data_use_tracker; -// Instantiate DataUseTracker only on Android. UpdateMetricsUsagePrefs() honors -// this rule too. #if defined(OS_ANDROID) data_use_tracker.reset(new DataUseTracker(local_state)); #endif @@ -48,23 +45,9 @@ registry->RegisterDictionaryPref(metrics::prefs::kUmaCellDataUse); } -// static void DataUseTracker::UpdateMetricsUsagePrefs(int message_size, bool is_cellular, - bool is_metrics_service_usage, - PrefService* local_state) { -// Instantiate DataUseTracker only on Android. Create() honors this rule too. -#if defined(OS_ANDROID) - metrics::DataUseTracker tracker(local_state); - tracker.UpdateMetricsUsagePrefsInternal(message_size, is_cellular, - is_metrics_service_usage); -#endif // defined(OS_ANDROID) -} - -void DataUseTracker::UpdateMetricsUsagePrefsInternal( - int message_size, - bool is_cellular, - bool is_metrics_service_usage) { + bool is_metrics_service_usage) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!is_cellular)
diff --git a/components/metrics/data_use_tracker.h b/components/metrics/data_use_tracker.h index e6ad4b3..457193e 100644 --- a/components/metrics/data_use_tracker.h +++ b/components/metrics/data_use_tracker.h
@@ -17,6 +17,9 @@ namespace metrics { +typedef base::Callback<void(const std::string&, int, bool)> + UpdateUsagePrefCallbackType; + // Records the data use of user traffic and UMA traffic in user prefs. Taking // into account those prefs it can verify whether certain UMA log upload is // allowed. @@ -33,10 +36,9 @@ static void RegisterPrefs(PrefRegistrySimple* registry); // Updates data usage tracking prefs with the specified values. - static void UpdateMetricsUsagePrefs(int message_size, - bool is_cellular, - bool is_metrics_service_usage, - PrefService* local_state); + void UpdateMetricsUsagePrefs(int message_size, + bool is_cellular, + bool is_metrics_service_usage); // Returns whether a log with provided |log_bytes| can be uploaded according // to data use ratio and UMA quota provided by variations. @@ -48,11 +50,6 @@ FRIEND_TEST_ALL_PREFIXES(DataUseTrackerTest, CheckComputeTotalDataUse); FRIEND_TEST_ALL_PREFIXES(DataUseTrackerTest, CheckCanUploadUMALog); - // Updates data usage tracking prefs with the specified values. - void UpdateMetricsUsagePrefsInternal(int message_size, - bool is_cellular, - bool is_metrics_service_usage); - // Updates provided |pref_name| for a current date with the given message // size. void UpdateUsagePref(const std::string& pref_name, int message_size);
diff --git a/components/metrics/data_use_tracker_unittest.cc b/components/metrics/data_use_tracker_unittest.cc index 7174823..b571dc4f2 100644 --- a/components/metrics/data_use_tracker_unittest.cc +++ b/components/metrics/data_use_tracker_unittest.cc
@@ -106,7 +106,7 @@ int user_pref_value = 0; int uma_pref_value = 0; - data_use_tracker.UpdateMetricsUsagePrefsInternal(2 * 100, true, false); + data_use_tracker.UpdateMetricsUsagePrefs(2 * 100, true, false); local_state.GetDictionary(prefs::kUserCellDataUse) ->GetInteger(kTodayStr, &user_pref_value); EXPECT_EQ(2 * 100, user_pref_value); @@ -114,7 +114,7 @@ ->GetInteger(kTodayStr, &uma_pref_value); EXPECT_EQ(0, uma_pref_value); - data_use_tracker.UpdateMetricsUsagePrefsInternal(100, true, true); + data_use_tracker.UpdateMetricsUsagePrefs(100, true, true); local_state.GetDictionary(prefs::kUserCellDataUse) ->GetInteger(kTodayStr, &user_pref_value); EXPECT_EQ(3 * 100, user_pref_value);
diff --git a/components/metrics/metrics_service.cc b/components/metrics/metrics_service.cc index 0416024..fb8f5419 100644 --- a/components/metrics/metrics_service.cc +++ b/components/metrics/metrics_service.cc
@@ -452,6 +452,14 @@ log_store()->StoreLog(log, MetricsLog::ONGOING_LOG); } +void MetricsService::UpdateMetricsUsagePrefs(int message_size, + bool is_cellular, + bool is_metrics_service_usage) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + reporting_service_.UpdateMetricsUsagePrefs(message_size, is_cellular, + is_metrics_service_usage); +} + //------------------------------------------------------------------------------ // private methods //------------------------------------------------------------------------------
diff --git a/components/metrics/metrics_service.h b/components/metrics/metrics_service.h index 34d4903..aa94eab 100644 --- a/components/metrics/metrics_service.h +++ b/components/metrics/metrics_service.h
@@ -169,6 +169,11 @@ // Pushes a log that has been generated by an external component. void PushExternalLog(const std::string& log); + // Updates data usage tracking prefs with the specified values. + void UpdateMetricsUsagePrefs(int message_size, + bool is_cellular, + bool is_metrics_service_usage); + variations::SyntheticTrialRegistry* synthetic_trial_registry() { return &synthetic_trial_registry_; }
diff --git a/components/metrics/reporting_service.cc b/components/metrics/reporting_service.cc index 251c095..7e3d789 100644 --- a/components/metrics/reporting_service.cc +++ b/components/metrics/reporting_service.cc
@@ -81,6 +81,16 @@ return reporting_active_; } +void ReportingService::UpdateMetricsUsagePrefs(int message_size, + bool is_cellular, + bool is_metrics_service_usage) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (data_use_tracker_) { + data_use_tracker_->UpdateMetricsUsagePrefs(message_size, is_cellular, + is_metrics_service_usage); + } +} + //------------------------------------------------------------------------------ // private methods //------------------------------------------------------------------------------
diff --git a/components/metrics/reporting_service.h b/components/metrics/reporting_service.h index 6094fc3..a913d4e5 100644 --- a/components/metrics/reporting_service.h +++ b/components/metrics/reporting_service.h
@@ -66,6 +66,11 @@ // True iff reporting is currently enabled. bool reporting_active() const; + // Updates data usage tracking prefs with the specified values. + void UpdateMetricsUsagePrefs(int message_size, + bool is_cellular, + bool is_metrics_service_usage); + // Registers local state prefs used by this class. This should only be called // once. static void RegisterPrefs(PrefRegistrySimple* registry);
diff --git a/components/neterror/resources/neterror.css b/components/neterror/resources/neterror.css index c325a21..dd8798d 100644 --- a/components/neterror/resources/neterror.css +++ b/components/neterror/resources/neterror.css
@@ -343,14 +343,46 @@ opacity: 0; } -.offline-content-list-title { - color: rgb(95, 99, 104); +#offline-content-list-visibility-card { + border: 1px solid white; + border-radius: 8px; + display: flex; font-size: .8em; + justify-content: space-between; line-height: 1; - margin-bottom: .8em; } -#offline-content-suggestions { +#offline-content-list.list-hidden #offline-content-list-visibility-card { + border-color: rgb(218, 220, 224); +} + +#offline-content-list-visibility-card > div { + padding: 1em; +} + +#offline-content-list-title { + color: var(--google-gray-700); +} + +#offline-content-list-show-text, #offline-content-list-hide-text { + color: rgb(66, 133, 244); +} + +/* Hides "hide" text div, the offline content list itself and the action button + * to show the downloads home when the offline content list is collapsed/hidden. + */ +#offline-content-list.list-hidden #offline-content-suggestions, +#offline-content-list.list-hidden #offline-content-list-action, +#offline-content-list.list-hidden #offline-content-list-hide-text { + display: none; +} + +/* Hides the "show" div when the offline content list is expanded/shown. */ +#offline-content-list:not(.list-hidden) #offline-content-list-show-text { + display: none; +} + +#offline-content-list { margin-inline-start: -5%; width: 110%; } @@ -358,21 +390,15 @@ /* The selectors below adjust the "overflow" of the suggestion cards contents * based on the same screen size based strategy used for the main frame, which * is applied by the `interstitial-wrapper` class. */ -@media (max-width: 700px) { - #offline-content-suggestions { - margin-inline-start: -5%; - width: 110%; - } -} @media (max-width: 420px) { - #offline-content-suggestions { + #offline-content-list { margin-inline-start: -2.5%; width: 105%; } } @media (max-width: 420px) and (orientation: portrait), (max-height: 560px) { - #offline-content-suggestions { + #offline-content-list { margin-inline-start: -12px; width: calc(100% + 24px); } @@ -390,14 +416,14 @@ #offline-content-list:not(.is-rtl) .suggestion-with-image .offline-content-suggestion-visual > img { - border-bottom-right-radius: 8px; - border-top-right-radius: 8px; + border-bottom-right-radius: 7px; + border-top-right-radius: 7px; } #offline-content-list.is-rtl .suggestion-with-image .offline-content-suggestion-visual > img { - border-bottom-left-radius: 8px; - border-top-left-radius: 8px; + border-bottom-left-radius: 7px; + border-top-left-radius: 7px; } .suggestion-with-icon .offline-content-suggestion-visual { @@ -460,10 +486,8 @@ div.offline-content-suggestion { align-items: stretch; - border-color: rgb(218, 220, 224); + border: 1px solid rgb(218, 220, 224); border-radius: 8px; - border-style: solid; - border-width: 1px; display: flex; justify-content: space-between; margin-bottom: .8em; @@ -540,15 +564,13 @@ width: 1.4em; } -.offline-content-list-action { +#offline-content-list-action { text-align: center; } #offline-content-summary { - border-color: rgb(241, 243, 244); + border: 1px solid rgb(241, 243, 244); border-radius: 12px; - border-style: solid; - border-width: 1px; padding: 12px; text-align: center; }
diff --git a/components/neterror/resources/neterror.html b/components/neterror/resources/neterror.html index 019a2892..c989aac37 100644 --- a/components/neterror/resources/neterror.html +++ b/components/neterror/resources/neterror.html
@@ -63,10 +63,22 @@ </div> </div> <div id="offline-content-list" hidden> - <div class="offline-content-list-title" jsselect="offlineContentList" - jscontent="title"></div> + <div id="offline-content-list-visibility-card" + onclick="toggleOfflineContentListVisibility(true)"> + <div id="offline-content-list-title" + jsselect="offlineContentList" jscontent="title"> + </div> + <div> + <div id="offline-content-list-show-text" + jsselect="offlineContentList" jscontent="showText"> + </div> + <div id="offline-content-list-hide-text" + jsselect="offlineContentList" jscontent="hideText"> + </div> + </div> + </div> <div id="offline-content-suggestions"></div> - <div class="offline-content-list-action"> + <div id="offline-content-list-action"> <a class="link-button" onclick="launchDownloadsPage()" jsselect="offlineContentList" jscontent="actionText"> </a>
diff --git a/components/neterror/resources/neterror.js b/components/neterror/resources/neterror.js index e495d10..a80db62 100644 --- a/components/neterror/resources/neterror.js +++ b/components/neterror/resources/neterror.js
@@ -271,7 +271,7 @@ // unsafe and must be securely handled to be presented on the dino page. Images // have already been safely re-encoded but textual content -- like title and // attribution -- must be properly handled here. -function offlineContentAvailable(suggestions) { +function offlineContentAvailable(isShown, suggestions) { if (!suggestions || !loadTimeData.valueExists('offlineContentList')) return; @@ -294,9 +294,24 @@ var contentListElement = document.getElementById('offline-content-list'); if (document.dir == 'rtl') contentListElement.classList.add('is-rtl'); + // The list is configured as shown by default. Hide if needed. + if (!isShown) + toggleOfflineContentListVisibility(false); contentListElement.hidden = false; } +function toggleOfflineContentListVisibility(updatePref) { + if (!loadTimeData.valueExists('offlineContentList')) + return; + + var contentListElement = document.getElementById('offline-content-list'); + var isVisible = !contentListElement.classList.toggle('list-hidden'); + + if (updatePref && window.errorPageController) { + errorPageController.listVisibilityChanged(isVisible); + } +} + function onDocumentLoad() { var controlButtonDiv = document.getElementById('control-buttons'); var reloadButton = document.getElementById('reload-button');
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index a01a49e..f425b75f 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn
@@ -235,19 +235,39 @@ if ((!is_android || enable_vr) && !is_ios) { deps += [ ":vector_icons" ] } + + if (is_android) { + deps += [ ":jni_headers" ] + } } if (is_android) { - java_cpp_enum("autocomplete_match_javagen") { + android_library("browser_java") { + java_files = [ + "android/java/src/org/chromium/components/omnibox/SuggestionAnswer.java", + ] + + deps = [ + "//base:base_java", + "//third_party/android_deps:android_support_compat_java", + ] + + srcjar_deps = [ ":browser_java_enums_srcjar" ] + } + + java_cpp_enum("browser_java_enums_srcjar") { sources = [ "autocomplete_match.h", + "autocomplete_match_type.h", + "suggestion_answer.h", ] } - java_cpp_enum("autocomplete_match_type_javagen") { + generate_jni("jni_headers") { sources = [ - "autocomplete_match_type.h", + "android/java/src/org/chromium/components/omnibox/SuggestionAnswer.java", ] + jni_package = "components/omnibox/browser" } }
diff --git a/components/omnibox/browser/DEPS b/components/omnibox/browser/DEPS index c4374110..86a2bde 100644 --- a/components/omnibox/browser/DEPS +++ b/components/omnibox/browser/DEPS
@@ -24,6 +24,7 @@ "+components/variations", "+components/vector_icons", "+extensions/common/constants.h", + "+jni", "+net", "+services/network/public/cpp", "+services/network/test",
diff --git a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/SuggestionAnswer.java b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/SuggestionAnswer.java new file mode 100644 index 0000000..ba6acfb --- /dev/null +++ b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/SuggestionAnswer.java
@@ -0,0 +1,234 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.components.omnibox; + +import android.support.v4.util.ObjectsCompat; +import android.text.TextUtils; + +import org.chromium.base.annotations.CalledByNative; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Contains the data needed to renderer a answer in the Omnibox suggestions. + */ +public class SuggestionAnswer { + @AnswerType + private final int mType; + private final ImageLine mFirstLine; + private final ImageLine mSecondLine; + + private SuggestionAnswer(@AnswerType int type, ImageLine firstLine, ImageLine secondLine) { + mType = type; + mFirstLine = firstLine; + mSecondLine = secondLine; + } + + /** Return the type of Answer being shown. */ + @AnswerType + public int getType() { + return mType; + } + + /** Returns the first of the two required image lines. */ + public ImageLine getFirstLine() { + return mFirstLine; + } + + /** Returns the second of the two required image lines. */ + public ImageLine getSecondLine() { + return mSecondLine; + } + + @Override + public int hashCode() { + // TODO(tedchoc): Replace usage of Arrays.hashCode with ObjectsCompat.hash once the support + // library is rolled past 27.1. + return Arrays.hashCode(new Object[] {mType, mFirstLine, mSecondLine}); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof SuggestionAnswer)) return false; + SuggestionAnswer other = (SuggestionAnswer) obj; + return mType == other.mType && ObjectsCompat.equals(mFirstLine, other.mFirstLine) + && ObjectsCompat.equals(mSecondLine, other.mSecondLine); + } + + /** + * Represents a single line of an answer, containing any number of typed text fields and an + * optional image. + */ + public static class ImageLine { + private final List<TextField> mTextFields; + private final TextField mAdditionalText; + private final TextField mStatusText; + private final String mImage; + + private ImageLine(List<TextField> textFields, TextField additionalText, + TextField statusText, String imageUrl) { + mTextFields = textFields; + mAdditionalText = additionalText; + mStatusText = statusText; + mImage = imageUrl; + } + + /** + * Return an unnamed list of text fields. These represent the main content of the line. + */ + public List<TextField> getTextFields() { + return mTextFields; + } + + /** + * Returns true if the line contains an "additional text" field. + */ + public boolean hasAdditionalText() { + return mAdditionalText != null; + } + + /** + * Return the "additional text" field. + */ + public TextField getAdditionalText() { + return mAdditionalText; + } + + /** + * Returns true if the line contains an "status text" field. + */ + public boolean hasStatusText() { + return mStatusText != null; + } + + /** + * Return the "status text" field. + */ + public TextField getStatusText() { + return mStatusText; + } + + /** + * Returns true if the line contains an image. + */ + public boolean hasImage() { + return mImage != null; + } + + /** + * Return the optional image (URL or base64-encoded image data). + */ + public String getImage() { + return mImage; + } + + @Override + public int hashCode() { + return Arrays.deepHashCode( + new Object[] {mTextFields.toArray(), mAdditionalText, mStatusText, mImage}); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ImageLine)) return false; + ImageLine other = (ImageLine) obj; + + if (mTextFields.size() != other.mTextFields.size()) return false; + for (int i = 0; i < mTextFields.size(); i++) { + if (!ObjectsCompat.equals(mTextFields.get(i), other.mTextFields.get(i))) { + return false; + } + } + return TextUtils.equals(mImage, other.mImage) + && ObjectsCompat.equals(mAdditionalText, other.mAdditionalText) + && ObjectsCompat.equals(mStatusText, other.mStatusText); + } + } + + /** + * Represents one text field of an answer, containing a integer type and a string. + */ + public static class TextField { + @AnswerTextType + private final int mType; + private final String mText; + @AnswerTextStyle + private final int mStyle; + private final int mNumLines; + + private TextField( + @AnswerTextType int type, String text, @AnswerTextStyle int style, int numLines) { + mType = type; + mText = text; + mStyle = style; + mNumLines = numLines; + } + + @AnswerTextType + public int getType() { + return mType; + } + + public String getText() { + return mText; + } + + @AnswerTextStyle + public int getStyle() { + return mStyle; + } + + public boolean hasNumLines() { + return mNumLines != -1; + } + + public int getNumLines() { + return mNumLines; + } + + @Override + public int hashCode() { + return Arrays.hashCode(new Object[] {mType, mText, mStyle, mNumLines}); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof TextField)) return false; + TextField other = (TextField) obj; + return mType == other.mType && TextUtils.equals(mText, other.mText) + && mStyle == other.mStyle && mNumLines == other.mNumLines; + } + } + + @CalledByNative + private static SuggestionAnswer createSuggestionAnswer( + @AnswerType int type, ImageLine firstLine, ImageLine secondLine) { + return new SuggestionAnswer(type, firstLine, secondLine); + } + + @CalledByNative + private static ImageLine createImageLine(List<TextField> fields, TextField additionalText, + TextField statusText, String imageUrl) { + return new ImageLine(fields, additionalText, statusText, imageUrl); + } + + @CalledByNative + private static List<TextField> createTextFieldList() { + return new ArrayList<>(); + } + + @CalledByNative + private static void addTextFieldToList(List<TextField> list, TextField field) { + list.add(field); + } + + @CalledByNative + private static TextField createTextField( + @AnswerTextType int type, String text, @AnswerTextStyle int style, int numLines) { + return new TextField(type, text, style, numLines); + } +}
diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc index cf11964..65185b7 100644 --- a/components/omnibox/browser/autocomplete_match.cc +++ b/components/omnibox/browser/autocomplete_match.cc
@@ -545,11 +545,9 @@ const GURL& url, const std::vector<MatchPosition>& match_positions, bool* match_in_scheme, - bool* match_in_subdomain, - bool* match_after_host) { + bool* match_in_subdomain) { DCHECK(match_in_scheme); DCHECK(match_in_subdomain); - DCHECK(match_after_host); size_t domain_length = net::registry_controlled_domains::GetDomainAndRegistry( @@ -560,11 +558,6 @@ size_t host_pos = parsed.CountCharactersBefore(url::Parsed::HOST, false); - // We must add an extra character to exclude the '/' delimiter that prefixes - // every path. We have to do this because the |include_delimiter| parameter - // passed to url::Parsed::CountCharactersBefore has no effect for the PATH. - size_t path_pos = parsed.CountCharactersBefore(url::Parsed::PATH, false) + 1; - bool has_subdomain = domain_length > 0 && domain_length < url.host_piece().length(); // Subtract an extra character from the domain start to exclude the '.' @@ -584,20 +577,13 @@ position.second > host_pos && parsed.host.is_nonempty()) { *match_in_subdomain = true; } - - if (position.second > path_pos && - (parsed.path.is_nonempty() || parsed.query.is_nonempty() || - parsed.ref.is_nonempty())) { - *match_after_host = true; - } } } // static url_formatter::FormatUrlTypes AutocompleteMatch::GetFormatTypes( bool preserve_scheme, - bool preserve_subdomain, - bool preserve_after_host) { + bool preserve_subdomain) { auto format_types = url_formatter::kFormatUrlOmitDefaults; if (preserve_scheme) { format_types &= ~url_formatter::kFormatUrlOmitHTTP; @@ -609,12 +595,6 @@ format_types |= url_formatter::kFormatUrlOmitTrivialSubdomains; } - if (!preserve_after_host && - base::FeatureList::IsEnabled( - omnibox::kUIExperimentElideSuggestionUrlAfterHost)) { - format_types |= url_formatter::kFormatUrlExperimentalElideAfterHost; - } - return format_types; }
diff --git a/components/omnibox/browser/autocomplete_match.h b/components/omnibox/browser/autocomplete_match.h index 7f98a7ef..79c14b33 100644 --- a/components/omnibox/browser/autocomplete_match.h +++ b/components/omnibox/browser/autocomplete_match.h
@@ -238,17 +238,15 @@ const TemplateURLService* template_url_service, const base::string16& keyword); - // Sets the |match_in_scheme|, |match_in_subdomain|, and |match_after_host| - // flags based on the provided |url| and list of substring |match_positions|. - // |match_positions| is the [begin, end) positions of a match within the - // unstripped URL spec. + // Sets the |match_in_scheme| and |match_in_subdomain| flags based on the + // provided |url| and list of substring |match_positions|. |match_positions| + // is the [begin, end) positions of a match within the unstripped URL spec. using MatchPosition = std::pair<size_t, size_t>; static void GetMatchComponents( const GURL& url, const std::vector<MatchPosition>& match_positions, bool* match_in_scheme, - bool* match_in_subdomain, - bool* match_after_host); + bool* match_in_subdomain); // Gets the formatting flags used for display of suggestions. This method // encapsulates the return of experimental flags too, so any URLs displayed @@ -257,12 +255,10 @@ // This function returns flags that may destructively format the URL, and // therefore should never be used for the |fill_into_edit| field. // - // |preserve_scheme|, |preserve_subdomain|, and |preserve_after_host| indicate - // that these URL components are important (part of the match), and should - // not be trimmed or elided. + // |preserve_scheme| and |preserve_subdomain| indicate that these URL + // components are important (part of the match), and should not be trimmed. static url_formatter::FormatUrlTypes GetFormatTypes(bool preserve_scheme, - bool preserve_subdomain, - bool preserve_after_host); + bool preserve_subdomain); // Computes the stripped destination URL (via GURLToStrippedGURL()) and // stores the result in |stripped_destination_url|. |input| is used for the
diff --git a/components/omnibox/browser/autocomplete_match_unittest.cc b/components/omnibox/browser/autocomplete_match_unittest.cc index f5df087..cd61f95 100644 --- a/components/omnibox/browser/autocomplete_match_unittest.cc +++ b/components/omnibox/browser/autocomplete_match_unittest.cc
@@ -10,8 +10,6 @@ #include "base/macros.h" #include "base/strings/utf_string_conversions.h" -#include "base/test/scoped_feature_list.h" -#include "components/omnibox/browser/omnibox_field_trial.h" #include "components/omnibox/browser/test_scheme_classifier.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -156,65 +154,48 @@ std::vector<std::string> input_terms; bool expected_match_in_scheme; bool expected_match_in_subdomain; - bool expected_match_after_host; }; MatchComponentsTestData test_cases[] = { // Match in scheme. - {"http://www.google.com", {"ht"}, true, false, false}, + {"http://www.google.com", {"ht"}, true, false}, // Match within the scheme, but not starting at the beginning, i.e. "ttp". - {"http://www.google.com", {"tp"}, false, false, false}, + {"http://www.google.com", {"tp"}, false, false}, // Sanity check that HTTPS still works. - {"https://www.google.com", {"http"}, true, false, false}, + {"https://www.google.com", {"http"}, true, false}, // Match within the subdomain. - {"http://www.google.com", {"www"}, false, true, false}, - {"http://www.google.com", {"www."}, false, true, false}, + {"http://www.google.com", {"www"}, false, true}, + {"http://www.google.com", {"www."}, false, true}, // Don't consider matches on the '.' delimiter as a match_in_subdomain. - {"http://www.google.com", {"."}, false, false, false}, - {"http://www.google.com", {".goo"}, false, false, false}, + {"http://www.google.com", {"."}, false, false}, + {"http://www.google.com", {".goo"}, false, false}, // Matches within the domain. - {"http://www.google.com", {"goo"}, false, false, false}, + {"http://www.google.com", {"goo"}, false, false}, // Verify that in private registries, we detect matches in subdomains. - {"http://www.appspot.com", {"www"}, false, true, false}, + {"http://www.appspot.com", {"www"}, false, true}, // Matches spanning the scheme, subdomain, and domain. - {"http://www.google.com", {"http://www.goo"}, true, true, false}, - {"http://www.google.com", {"ht", "www"}, true, true, false}, + {"http://www.google.com", {"http://www.goo"}, true, true}, + {"http://www.google.com", {"ht", "www"}, true, true}, // But we should not flag match_in_subdomain if there is no subdomain. - {"http://google.com", {"http://goo"}, true, false, false}, - - // Matches in the path, query, and ref. - {"http://google.com/abc?def=ghi#jkl", {"abc"}, false, false, true}, - {"http://google.com/abc?def=ghi#jkl", {"ghi"}, false, false, true}, - {"http://google.com/abc?def=ghi#jkl", {"jkl"}, false, false, true}, - // Match spanning an arbitrary portion of the URL after the host. - {"http://google.com/abc?def=ghi#jkl", {"bc?def=g"}, false, false, true}, - // Don't consider the '/' delimiter as a match_in_path. - {"http://google.com/abc?def=ghi#jkl", {"com/"}, false, false, false}, - // Match on the query and ref only - {"http://google.com?def", {"def"}, false, false, true}, - {"http://google.com#jkl", {"jkl"}, false, false, true}, + {"http://google.com", {"http://goo"}, true, false}, // Matches spanning the subdomain and path. - {"http://www.google.com/abc", {"www.google.com/ab"}, false, true, true}, - {"http://www.google.com/abc", {"www", "ab"}, false, true, true}, + {"http://www.google.com/abc", {"www.google.com/ab"}, false, true}, + {"http://www.google.com/abc", {"www", "ab"}, false, true}, // Matches spanning the scheme, subdomain, and path. - {"http://www.google.com/abc", - {"http://www.google.com/ab"}, - true, - true, - true}, - {"http://www.google.com/abc", {"ht", "ww", "ab"}, true, true, true}, + {"http://www.google.com/abc", {"http://www.google.com/ab"}, true, true}, + {"http://www.google.com/abc", {"ht", "ww", "ab"}, true, true}, // Intranet sites. - {"http://foobar/biz", {"foobar"}, false, false, false}, - {"http://foobar/biz", {"biz"}, false, false, true}, + {"http://foobar/biz", {"foobar"}, false, false}, + {"http://foobar/biz", {"biz"}, false, false}, // Ensure something sane happens when the URL input is invalid. - {"", {""}, false, false, false}, - {"foobar", {"bar"}, false, false, false}, + {"", {""}, false, false}, + {"foobar", {"bar"}, false, false}, }; for (auto& test_case : test_cases) { SCOPED_TRACE(testing::Message() @@ -222,12 +203,9 @@ << test_case.input_terms[0] << " expected_match_in_scheme=" << test_case.expected_match_in_scheme << " expected_match_in_subdomain=" - << test_case.expected_match_in_subdomain - << " expected_match_after_host=" - << test_case.expected_match_after_host); + << test_case.expected_match_in_subdomain); bool match_in_scheme = false; bool match_in_subdomain = false; - bool match_after_host = false; std::vector<AutocompleteMatch::MatchPosition> match_positions; for (auto& term : test_case.input_terms) { size_t start = test_case.url.find(term); @@ -236,11 +214,10 @@ match_positions.push_back(std::make_pair(start, end)); } AutocompleteMatch::GetMatchComponents(GURL(test_case.url), match_positions, - &match_in_scheme, &match_in_subdomain, - &match_after_host); + &match_in_scheme, + &match_in_subdomain); EXPECT_EQ(test_case.expected_match_in_scheme, match_in_scheme); EXPECT_EQ(test_case.expected_match_in_subdomain, match_in_subdomain); - EXPECT_EQ(test_case.expected_match_after_host, match_after_host); } } @@ -253,17 +230,15 @@ const std::string url; bool preserve_scheme; bool preserve_subdomain; - bool preserve_after_host; const wchar_t* expected_result; void Validate() { SCOPED_TRACE(testing::Message() << " url=" << url << " preserve_scheme=" << preserve_scheme << " preserve_subdomain=" << preserve_subdomain - << " preserve_after_host=" << preserve_after_host << " expected_result=" << expected_result); - auto format_types = AutocompleteMatch::GetFormatTypes( - preserve_scheme, preserve_subdomain, preserve_after_host); + auto format_types = AutocompleteMatch::GetFormatTypes(preserve_scheme, + preserve_subdomain); EXPECT_EQ(base::WideToUTF16(expected_result), url_formatter::FormatUrl(GURL(url), format_types, net::UnescapeRule::SPACES, nullptr, @@ -273,33 +248,20 @@ FormatUrlTestData normal_cases[] = { // Test the |preserve_scheme| parameter. - {"http://google.com", false, false, false, L"google.com"}, - {"https://google.com", false, false, false, L"google.com"}, - {"http://google.com", true, false, false, L"http://google.com"}, - {"https://google.com", true, false, false, L"https://google.com"}, + {"http://google.com", false, false, L"google.com"}, + {"https://google.com", false, false, L"google.com"}, + {"http://google.com", true, false, L"http://google.com"}, + {"https://google.com", true, false, L"https://google.com"}, // Test the |preserve_subdomain| parameter. - {"http://www.google.com", false, false, false, L"google.com"}, - {"http://www.google.com", false, true, false, L"www.google.com"}, + {"http://www.google.com", false, false, L"google.com"}, + {"http://www.google.com", false, true, L"www.google.com"}, // Test that paths are preserved in the default case. - {"http://google.com/foobar", false, false, false, L"google.com/foobar"}, + {"http://google.com/foobar", false, false, L"google.com/foobar"}, }; for (FormatUrlTestData& test_case : normal_cases) test_case.Validate(); - - // Test the elide-after-host feature flag. - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - omnibox::kUIExperimentElideSuggestionUrlAfterHost); - - FormatUrlTestData hide_path_cases[] = { - {"http://google.com/foobar", false, false, false, - L"google.com/\x2026\x0000"}, - {"http://google.com/foobar", false, false, true, L"google.com/foobar"}, - }; - for (FormatUrlTestData& test_case : hide_path_cases) - test_case.Validate(); } TEST(AutocompleteMatchTest, SupportsDeletion) {
diff --git a/components/omnibox/browser/clipboard_url_provider.cc b/components/omnibox/browser/clipboard_url_provider.cc index 8bddb9f..86d41a6 100644 --- a/components/omnibox/browser/clipboard_url_provider.cc +++ b/components/omnibox/browser/clipboard_url_provider.cc
@@ -88,8 +88,8 @@ AutocompleteMatch match(this, 800, false, AutocompleteMatchType::CLIPBOARD); match.destination_url = url; // Because the user did not type a related input to get this clipboard - // suggestion, preserve the path and subdomain so the user has extra context. - auto format_types = AutocompleteMatch::GetFormatTypes(false, true, true); + // suggestion, preserve the subdomain so the user has extra context. + auto format_types = AutocompleteMatch::GetFormatTypes(false, true); match.contents.assign(url_formatter::FormatUrl( url, format_types, net::UnescapeRule::SPACES, nullptr, nullptr, nullptr)); AutocompleteMatch::ClassifyLocationInString(
diff --git a/components/omnibox/browser/history_match.cc b/components/omnibox/browser/history_match.cc index d3c32e1..4498d22 100644 --- a/components/omnibox/browser/history_match.cc +++ b/components/omnibox/browser/history_match.cc
@@ -13,7 +13,6 @@ : input_location(base::string16::npos), match_in_scheme(false), match_in_subdomain(false), - match_after_host(false), innermost_match(true) {} bool HistoryMatch::EqualsGURL(const HistoryMatch& h, const GURL& url) {
diff --git a/components/omnibox/browser/history_match.h b/components/omnibox/browser/history_match.h index 714d03e3..a206aa3 100644 --- a/components/omnibox/browser/history_match.h +++ b/components/omnibox/browser/history_match.h
@@ -43,7 +43,6 @@ // selected.) bool match_in_scheme; bool match_in_subdomain; - bool match_after_host; // A match after any scheme/"www.", if the user input could match at both // locations. If the user types "w", an innermost match ("website.com") is
diff --git a/components/omnibox/browser/history_quick_provider.cc b/components/omnibox/browser/history_quick_provider.cc index c8662da..c7a5f2b 100644 --- a/components/omnibox/browser/history_quick_provider.cc +++ b/components/omnibox/browser/history_quick_provider.cc
@@ -246,7 +246,7 @@ AutocompleteMatch::GetFormatTypes( autocomplete_input_.parts().scheme.len > 0 || history_match.match_in_scheme, - history_match.match_in_subdomain, history_match.match_after_host), + history_match.match_in_subdomain), net::UnescapeRule::SPACES, nullptr, nullptr, &offsets); TermMatches new_matches =
diff --git a/components/omnibox/browser/history_url_provider.cc b/components/omnibox/browser/history_url_provider.cc index 37db85f..48e295dc 100644 --- a/components/omnibox/browser/history_url_provider.cc +++ b/components/omnibox/browser/history_url_provider.cc
@@ -780,8 +780,7 @@ AutocompleteMatch::GetMatchComponents( row_url, {{match.input_location, prefixed_input.length()}}, - &match.match_in_scheme, &match.match_in_subdomain, - &match.match_after_host); + &match.match_in_scheme, &match.match_in_subdomain); params->matches.push_back(std::move(match)); } @@ -1272,7 +1271,7 @@ const auto format_types = AutocompleteMatch::GetFormatTypes( params.input.parts().scheme.len > 0 || !params.trim_http || history_match.match_in_scheme, - history_match.match_in_subdomain, history_match.match_after_host); + history_match.match_in_subdomain); match.contents = url_formatter::FormatUrlWithOffsets( info.url(), format_types, net::UnescapeRule::SPACES, nullptr, nullptr, &offsets);
diff --git a/components/omnibox/browser/history_url_provider_unittest.cc b/components/omnibox/browser/history_url_provider_unittest.cc index 73710752..11cf2535 100644 --- a/components/omnibox/browser/history_url_provider_unittest.cc +++ b/components/omnibox/browser/history_url_provider_unittest.cc
@@ -14,7 +14,6 @@ #include "base/run_loop.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "base/time/time.h" #include "components/history/core/browser/history_service.h" @@ -1190,39 +1189,34 @@ ExpectFormattedFullMatch("abc", L"www.abc.def.com/path", 4, 3); ExpectFormattedFullMatch("hij", L"hij.com/path", 0, 3); - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - omnibox::kUIExperimentElideSuggestionUrlAfterHost); - // Sanity check that scheme, subdomain, and path can all be trimmed or elided. - ExpectFormattedFullMatch("hij", L"hij.com/\x2026\x0000", 0, 3); + ExpectFormattedFullMatch("hij", L"hij.com/path", 0, 3); // Verify that the scheme is preserved if part of match. - ExpectFormattedFullMatch("https://www.hi", - L"https://www.hij.com/\x2026\x0000", 0, 14); + ExpectFormattedFullMatch("https://www.hi", L"https://www.hij.com/path", 0, + 14); // Verify that the whole subdomain is preserved if part of match. - ExpectFormattedFullMatch("abc", L"www.abc.def.com/\x2026\x0000", 4, 3); - ExpectFormattedFullMatch("www.hij", L"www.hij.com/\x2026\x0000", 0, 7); + ExpectFormattedFullMatch("abc", L"www.abc.def.com/path", 4, 3); + ExpectFormattedFullMatch("www.hij", L"www.hij.com/path", 0, 7); // Verify that the path is preserved if part of the match. ExpectFormattedFullMatch("hij.com/path", L"hij.com/path", 0, 12); // Verify preserving both the scheme and subdomain. - ExpectFormattedFullMatch("https://www.hi", - L"https://www.hij.com/\x2026\x0000", 0, 14); + ExpectFormattedFullMatch("https://www.hi", L"https://www.hij.com/path", 0, + 14); // Verify preserving everything. ExpectFormattedFullMatch("https://www.hij.com/p", L"https://www.hij.com/path", 0, 21); // Verify that upper case input still works for subdomain matching. - ExpectFormattedFullMatch("WWW.hij", L"www.hij.com/\x2026\x0000", 0, 7); + ExpectFormattedFullMatch("WWW.hij", L"www.hij.com/path", 0, 7); // Verify that matching in the subdomain-only preserves the subdomain. - ExpectFormattedFullMatch("ww", L"www.hij.com/\x2026\x0000", 0, 2); - ExpectFormattedFullMatch("https://ww", L"https://www.hij.com/\x2026\x0000", 0, - 10); + ExpectFormattedFullMatch("ww", L"www.hij.com/path", 0, 2); + ExpectFormattedFullMatch("https://ww", L"https://www.hij.com/path", 0, 10); } std::unique_ptr<HistoryURLProviderParams> BuildHistoryURLProviderParams(
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc index a47217d..6cebbd3 100644 --- a/components/omnibox/browser/omnibox_field_trial.cc +++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -201,26 +201,6 @@ const base::Feature kQueryInOmnibox{"QueryInOmnibox", base::FEATURE_DISABLED_BY_DEFAULT}; -// Feature used for eliding the suggestion URL after the host as a UI -// experiment. -const base::Feature kUIExperimentElideSuggestionUrlAfterHost{ - "OmniboxUIExperimentElideSuggestionUrlAfterHost", - base::FEATURE_DISABLED_BY_DEFAULT}; - -// Feature used to jog the Omnibox textfield to align with the dropdown -// suggestions text when the popup is opened. When this feature is disabled, the -// textfield is always aligned with the suggestions text, and a separator fills -// the gap. -const base::Feature kUIExperimentJogTextfieldOnPopup{ - "OmniboxUIExperimentJogTextfieldOnPopup", - base::FEATURE_ENABLED_BY_DEFAULT}; - -// Feature used for showing the URL suggestion favicons as a UI experiment, -// currently only used on desktop platforms. -const base::Feature kUIExperimentShowSuggestionFavicons{ - "OmniboxUIExperimentShowSuggestionFavicons", - base::FEATURE_ENABLED_BY_DEFAULT}; - // Feature used to always swap the title and URL. const base::Feature kUIExperimentSwapTitleAndUrl{ "OmniboxUIExperimentSwapTitleAndUrl", @@ -812,11 +792,6 @@ return omnibox::pedal_suggestion_mode.Get(); } -bool OmniboxFieldTrial::IsJogTextfieldOnPopupEnabled() { - return base::FeatureList::IsEnabled( - omnibox::kUIExperimentJogTextfieldOnPopup); -} - bool OmniboxFieldTrial::IsHideSteadyStateUrlSchemeEnabled() { return base::FeatureList::IsEnabled(omnibox::kHideSteadyStateUrlScheme) || base::FeatureList::IsEnabled(features::kExperimentalUi); @@ -828,12 +803,6 @@ base::FeatureList::IsEnabled(features::kExperimentalUi); } -bool OmniboxFieldTrial::IsShowSuggestionFaviconsEnabled() { - return base::FeatureList::IsEnabled( - omnibox::kUIExperimentShowSuggestionFavicons) || - base::FeatureList::IsEnabled(features::kExperimentalUi); -} - bool OmniboxFieldTrial::IsExperimentalKeywordModeEnabled() { return base::FeatureList::IsEnabled(omnibox::kExperimentalKeywordMode); }
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h index 59cfd3dd9..99f79ed 100644 --- a/components/omnibox/browser/omnibox_field_trial.h +++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -44,10 +44,7 @@ extern const base::Feature kZeroSuggestSwapTitleAndUrl; extern const base::Feature kDisplayTitleForCurrentUrl; extern const base::Feature kQueryInOmnibox; -extern const base::Feature kUIExperimentElideSuggestionUrlAfterHost; -extern const base::Feature kUIExperimentJogTextfieldOnPopup; extern const base::Feature kUIExperimentMaxAutocompleteMatches; -extern const base::Feature kUIExperimentShowSuggestionFavicons; extern const base::Feature kUIExperimentSwapTitleAndUrl; extern const base::Feature kUIExperimentVerticalMargin; extern const base::Feature kSpeculativeServiceWorkerStartOnQueryInput; @@ -448,9 +445,6 @@ // Returns the #omnibox-pedal-suggestions feature's mode parameter as enum. static PedalSuggestionMode GetPedalSuggestionMode(); - // Returns true if the jog textfield flag is enabled. - static bool IsJogTextfieldOnPopupEnabled(); - // Returns true if either the steady-state elision flag for scheme or the // #upcoming-ui-features flag is enabled. static bool IsHideSteadyStateUrlSchemeEnabled(); @@ -459,10 +453,6 @@ // subdomains or the #upcoming-ui-features flag is enabled. static bool IsHideSteadyStateUrlTrivialSubdomainsEnabled(); - // Returns true if either the show suggestion favicons flag or the - // #upcoming-ui-features flag is enabled. - static bool IsShowSuggestionFaviconsEnabled(); - // Returns true if the experimental keyword mode is enabled. static bool IsExperimentalKeywordModeEnabled();
diff --git a/components/omnibox/browser/omnibox_popup_model.cc b/components/omnibox/browser/omnibox_popup_model.cc index f7321dc1..4ffe74e2 100644 --- a/components/omnibox/browser/omnibox_popup_model.cc +++ b/components/omnibox/browser/omnibox_popup_model.cc
@@ -305,8 +305,8 @@ if (!extension_icon.IsEmpty()) return edit_model_->client()->GetSizedIcon(extension_icon); - if (OmniboxFieldTrial::IsShowSuggestionFaviconsEnabled() && - !AutocompleteMatch::IsSearchType(match.type)) { + // Get the favicon for navigational suggestions. + if (!AutocompleteMatch::IsSearchType(match.type)) { // Because the Views UI code calls GetMatchIcon in both the layout and // painting code, we may generate multiple OnFaviconFetched callbacks, // all run one after another. This seems to be harmless as the callback
diff --git a/components/omnibox/browser/omnibox_view.cc b/components/omnibox/browser/omnibox_view.cc index 5ecebac..101c04d 100644 --- a/components/omnibox/browser/omnibox_view.cc +++ b/components/omnibox/browser/omnibox_view.cc
@@ -147,7 +147,7 @@ favicon = model_->client()->GetFaviconForDefaultSearchProvider( std::move(on_icon_fetched)); - } else if (OmniboxFieldTrial::IsShowSuggestionFaviconsEnabled()) { + } else { // For site suggestions, display site's favicon. favicon = model_->client()->GetFaviconForPageUrl( match.destination_url, std::move(on_icon_fetched));
diff --git a/components/omnibox/browser/omnibox_view_unittest.cc b/components/omnibox/browser/omnibox_view_unittest.cc index 53b79e3..30f20c4 100644 --- a/components/omnibox/browser/omnibox_view_unittest.cc +++ b/components/omnibox/browser/omnibox_view_unittest.cc
@@ -9,13 +9,11 @@ #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/test/test_bookmark_client.h" #include "components/omnibox/browser/autocomplete_match.h" -#include "components/omnibox/browser/omnibox_field_trial.h" #include "components/omnibox/browser/omnibox_view.h" #include "components/omnibox/browser/test_omnibox_client.h" #include "components/omnibox/browser/test_omnibox_edit_controller.h" @@ -176,10 +174,6 @@ TEST_F(OmniboxViewTest, GetIcon_Favicon) { const GURL kUrl("https://woahDude.com"); - base::test::ScopedFeatureList scoped_feature_list_; - scoped_feature_list_.InitAndEnableFeature( - omnibox::kUIExperimentShowSuggestionFavicons); - AutocompleteMatch match; match.type = AutocompleteMatchType::URL_WHAT_YOU_TYPED; match.destination_url = kUrl;
diff --git a/components/omnibox/browser/scored_history_match.cc b/components/omnibox/browser/scored_history_match.cc index 5e5874a..ff7997ca 100644 --- a/components/omnibox/browser/scored_history_match.cc +++ b/components/omnibox/browser/scored_history_match.cc
@@ -148,7 +148,6 @@ input_location = 0; match_in_scheme = false; match_in_subdomain = false; - match_after_host = false; innermost_match = false; // NOTE: Call Init() before doing any validity checking to ensure that the @@ -336,7 +335,7 @@ std::make_pair(url_match.offset, url_match.offset + url_match.length)); } AutocompleteMatch::GetMatchComponents(gurl, match_positions, &match_in_scheme, - &match_in_subdomain, &match_after_host); + &match_in_subdomain); } ScoredHistoryMatch::ScoredHistoryMatch(const ScoredHistoryMatch& other) =
diff --git a/components/omnibox/browser/scored_history_match_unittest.cc b/components/omnibox/browser/scored_history_match_unittest.cc index cb73dfe..4a4112d 100644 --- a/components/omnibox/browser/scored_history_match_unittest.cc +++ b/components/omnibox/browser/scored_history_match_unittest.cc
@@ -294,22 +294,18 @@ one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_a.match_in_scheme); EXPECT_FALSE(scored_a.match_in_subdomain); - EXPECT_FALSE(scored_a.match_after_host); ScoredHistoryMatch scored_b(row, visits, ASCIIToUTF16("w"), Make1Term("w"), one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_b.match_in_scheme); EXPECT_TRUE(scored_b.match_in_subdomain); - EXPECT_FALSE(scored_b.match_after_host); ScoredHistoryMatch scored_c(row, visits, ASCIIToUTF16("h"), Make1Term("h"), one_word_no_offset, word_starts, false, 1, now); EXPECT_TRUE(scored_c.match_in_scheme); EXPECT_FALSE(scored_c.match_in_subdomain); - EXPECT_FALSE(scored_c.match_after_host); ScoredHistoryMatch scored_d(row, visits, ASCIIToUTF16("o"), Make1Term("o"), one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_d.match_in_scheme); EXPECT_FALSE(scored_d.match_in_subdomain); - EXPECT_FALSE(scored_d.match_after_host); } { @@ -319,17 +315,14 @@ one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_a.match_in_scheme); EXPECT_TRUE(scored_a.match_in_subdomain); - EXPECT_FALSE(scored_a.match_after_host); ScoredHistoryMatch scored_b(row, visits, ASCIIToUTF16("f"), Make1Term("f"), one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_b.match_in_scheme); EXPECT_FALSE(scored_b.match_in_subdomain); - EXPECT_FALSE(scored_b.match_after_host); ScoredHistoryMatch scored_c(row, visits, ASCIIToUTF16("o"), Make1Term("o"), one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_c.match_in_scheme); EXPECT_FALSE(scored_c.match_in_subdomain); - EXPECT_FALSE(scored_c.match_after_host); } { @@ -339,17 +332,14 @@ one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_a.match_in_scheme); EXPECT_TRUE(scored_a.match_in_subdomain); - EXPECT_FALSE(scored_a.match_after_host); ScoredHistoryMatch scored_b(row, visits, ASCIIToUTF16("m"), Make1Term("m"), one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_b.match_in_scheme); EXPECT_TRUE(scored_b.match_in_subdomain); - EXPECT_FALSE(scored_b.match_after_host); ScoredHistoryMatch scored_c(row, visits, ASCIIToUTF16("f"), Make1Term("f"), one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_c.match_in_scheme); EXPECT_FALSE(scored_c.match_in_subdomain); - EXPECT_FALSE(scored_c.match_after_host); } { @@ -360,51 +350,42 @@ one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_a.match_in_scheme); EXPECT_FALSE(scored_a.match_in_subdomain); - EXPECT_FALSE(scored_a.match_after_host); ScoredHistoryMatch scored_b(row, visits, ASCIIToUTF16("h"), Make1Term("h"), one_word_no_offset, word_starts, false, 1, now); EXPECT_TRUE(scored_b.match_in_scheme); EXPECT_FALSE(scored_b.match_in_subdomain); - EXPECT_FALSE(scored_b.match_after_host); ScoredHistoryMatch scored_c(row, visits, ASCIIToUTF16("w"), Make1Term("w"), one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_c.match_in_scheme); EXPECT_TRUE(scored_c.match_in_subdomain); - EXPECT_FALSE(scored_c.match_after_host); ScoredHistoryMatch scored_d(row, visits, ASCIIToUTF16("x"), Make1Term("x"), one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_d.match_in_scheme); EXPECT_FALSE(scored_d.match_in_subdomain); - EXPECT_TRUE(scored_d.match_after_host); ScoredHistoryMatch scored_e(row, visits, ASCIIToUTF16("y"), Make1Term("y"), one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_e.match_in_scheme); EXPECT_FALSE(scored_e.match_in_subdomain); - EXPECT_TRUE(scored_e.match_after_host); ScoredHistoryMatch scored_f(row, visits, ASCIIToUTF16("z"), Make1Term("z"), one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_f.match_in_scheme); EXPECT_FALSE(scored_f.match_in_subdomain); - EXPECT_TRUE(scored_f.match_after_host); ScoredHistoryMatch scored_g(row, visits, ASCIIToUTF16("https://www"), Make1Term("https://www"), one_word_no_offset, word_starts, false, 1, now); EXPECT_TRUE(scored_g.match_in_scheme); EXPECT_TRUE(scored_g.match_in_subdomain); - EXPECT_FALSE(scored_g.match_after_host); ScoredHistoryMatch scored_h(row, visits, ASCIIToUTF16("testing.com/x"), Make1Term("testing.com/x"), one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_h.match_in_scheme); EXPECT_FALSE(scored_h.match_in_subdomain); - EXPECT_TRUE(scored_h.match_after_host); ScoredHistoryMatch scored_i(row, visits, ASCIIToUTF16("https://www.testing.com/x"), Make1Term("https://www.testing.com/x"), one_word_no_offset, word_starts, false, 1, now); EXPECT_TRUE(scored_i.match_in_scheme); EXPECT_TRUE(scored_i.match_in_subdomain); - EXPECT_TRUE(scored_i.match_after_host); } { @@ -415,18 +396,15 @@ one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_a.match_in_scheme); EXPECT_FALSE(scored_a.match_in_subdomain); - EXPECT_FALSE(scored_a.match_after_host); ScoredHistoryMatch scored_b(row, visits, ASCIIToUTF16("xn"), Make1Term("xn"), one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_b.match_in_scheme); EXPECT_FALSE(scored_b.match_in_subdomain); - EXPECT_FALSE(scored_b.match_after_host); ScoredHistoryMatch scored_c(row, visits, ASCIIToUTF16("w"), Make1Term("w"), one_word_no_offset, word_starts, false, 1, now); EXPECT_FALSE(scored_c.match_in_scheme); EXPECT_TRUE(scored_c.match_in_subdomain); - EXPECT_FALSE(scored_c.match_after_host); } }
diff --git a/components/omnibox/browser/search_suggestion_parser.cc b/components/omnibox/browser/search_suggestion_parser.cc index 28b0539..dd79ff84 100644 --- a/components/omnibox/browser/search_suggestion_parser.cc +++ b/components/omnibox/browser/search_suggestion_parser.cc
@@ -262,13 +262,11 @@ bool match_in_scheme = false; bool match_in_subdomain = false; - bool match_after_host = false; AutocompleteMatch::GetMatchComponents( GURL(formatted_url_), {{match_start, match_start + input_text.length()}}, - &match_in_scheme, &match_in_subdomain, &match_after_host); + &match_in_scheme, &match_in_subdomain); auto format_types = AutocompleteMatch::GetFormatTypes( - GURL(input_text).has_scheme() || match_in_scheme, match_in_subdomain, - match_after_host); + GURL(input_text).has_scheme() || match_in_scheme, match_in_subdomain); base::string16 match_contents = url_formatter::FormatUrl(url_, format_types, net::UnescapeRule::SPACES,
diff --git a/components/omnibox/browser/suggestion_answer.cc b/components/omnibox/browser/suggestion_answer.cc index d6897d3..0adf61d 100644 --- a/components/omnibox/browser/suggestion_answer.cc +++ b/components/omnibox/browser/suggestion_answer.cc
@@ -19,6 +19,13 @@ #include "net/base/escape.h" #include "url/url_constants.h" +#ifdef OS_ANDROID +#include "base/android/jni_string.h" +#include "jni/SuggestionAnswer_jni.h" + +using base::android::ScopedJavaLocalRef; +#endif + namespace { // All of these are defined here (even though most are only used once each) so @@ -341,3 +348,54 @@ first_line_.SetTextStyles(0, TextStyle::NORMAL_DIM); second_line_.SetTextStyles(0, TextStyle::NORMAL); } + +#ifdef OS_ANDROID +namespace { + +ScopedJavaLocalRef<jobject> CreateJavaTextField( + JNIEnv* env, + const SuggestionAnswer::TextField& text_field) { + return Java_SuggestionAnswer_createTextField( + env, text_field.type(), + base::android::ConvertUTF16ToJavaString(env, text_field.text()), + static_cast<int>(text_field.style()), text_field.num_lines()); +} + +ScopedJavaLocalRef<jobject> CreateJavaImageLine( + JNIEnv* env, + const SuggestionAnswer::ImageLine* image_line) { + ScopedJavaLocalRef<jobject> jtext_fields = + Java_SuggestionAnswer_createTextFieldList(env); + for (const SuggestionAnswer::TextField& text_field : + image_line->text_fields()) { + Java_SuggestionAnswer_addTextFieldToList( + env, jtext_fields, CreateJavaTextField(env, text_field)); + } + + ScopedJavaLocalRef<jobject> jadditional_text; + if (image_line->additional_text()) + jadditional_text = CreateJavaTextField(env, *image_line->additional_text()); + + ScopedJavaLocalRef<jobject> jstatus_text; + if (image_line->status_text()) + jstatus_text = CreateJavaTextField(env, *image_line->status_text()); + + ScopedJavaLocalRef<jstring> jimage_url; + if (image_line->image_url().is_valid()) { + jimage_url = base::android::ConvertUTF8ToJavaString( + env, image_line->image_url().spec()); + } + + return Java_SuggestionAnswer_createImageLine( + env, jtext_fields, jadditional_text, jstatus_text, jimage_url); +} + +} // namespace + +ScopedJavaLocalRef<jobject> SuggestionAnswer::CreateJavaObject() const { + JNIEnv* env = base::android::AttachCurrentThread(); + return Java_SuggestionAnswer_createSuggestionAnswer( + env, static_cast<int>(type_), CreateJavaImageLine(env, &first_line_), + CreateJavaImageLine(env, &second_line_)); +} +#endif // OS_ANDROID
diff --git a/components/omnibox/browser/suggestion_answer.h b/components/omnibox/browser/suggestion_answer.h index 4069fe7..d0ddffc 100644 --- a/components/omnibox/browser/suggestion_answer.h +++ b/components/omnibox/browser/suggestion_answer.h
@@ -15,6 +15,10 @@ #include "base/optional.h" #include "url/gurl.h" +#ifdef OS_ANDROID +#include "base/android/scoped_java_ref.h" +#endif + namespace base { class DictionaryValue; } @@ -37,8 +41,11 @@ // These values are based on the server-side type AnswerTriggererKey. Do not // remove values from this enum (or the client/server will become out of // sync). + // + // A Java counterpart will be generated for this enum. + // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.omnibox enum AnswerType { - ANSWER_TYPE_INVALID, + ANSWER_TYPE_INVALID = 0, ANSWER_TYPE_DICTIONARY, ANSWER_TYPE_FINANCE, ANSWER_TYPE_KNOWLEDGE_GRAPH, @@ -57,6 +64,10 @@ // These values are named and numbered to match a specification at go/ais_api. // The values are only used for answer results. + // + // A Java counterpart will be generated for this enum. + // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.omnibox + // GENERATED_JAVA_CLASS_NAME_OVERRIDE: AnswerTextType enum TextType { // Deprecated: ANSWER = 1, // Deprecated: HEADLINE = 2, @@ -89,8 +100,12 @@ // based on a finite set of text types instead of answer properties and rules. // Performance is also improved by doing this once at parse time instead of // every time render text is invalidated. + // + // A Java counterpart will be generated for this enum. + // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.omnibox + // GENERATED_JAVA_CLASS_NAME_OVERRIDE: AnswerTextStyle enum class TextStyle { - NONE, + NONE = 0, NORMAL, NORMAL_DIM, SECONDARY, @@ -223,6 +238,10 @@ // For new answers, replace old answer text types with appropriate new types. void InterpretTextTypes(); +#ifdef OS_ANDROID + base::android::ScopedJavaLocalRef<jobject> CreateJavaObject() const; +#endif + private: GURL image_url_; ImageLine first_line_;
diff --git a/components/omnibox/browser/titled_url_match_utils.cc b/components/omnibox/browser/titled_url_match_utils.cc index bcbd0a0..9cf69e1 100644 --- a/components/omnibox/browser/titled_url_match_utils.cc +++ b/components/omnibox/browser/titled_url_match_utils.cc
@@ -72,13 +72,11 @@ bool match_in_scheme = false; bool match_in_subdomain = false; - bool match_after_host = false; - AutocompleteMatch::GetMatchComponents( - url, titled_url_match.url_match_positions, &match_in_scheme, - &match_in_subdomain, &match_after_host); + AutocompleteMatch::GetMatchComponents(url, + titled_url_match.url_match_positions, + &match_in_scheme, &match_in_subdomain); auto format_types = AutocompleteMatch::GetFormatTypes( - input.parts().scheme.len > 0 || match_in_scheme, match_in_subdomain, - match_after_host); + input.parts().scheme.len > 0 || match_in_scheme, match_in_subdomain); std::vector<size_t> offsets = TitledUrlMatch::OffsetsFromMatchPositions( titled_url_match.url_match_positions);
diff --git a/components/omnibox/browser/zero_suggest_provider.cc b/components/omnibox/browser/zero_suggest_provider.cc index 2575891..0a63c48 100644 --- a/components/omnibox/browser/zero_suggest_provider.cc +++ b/components/omnibox/browser/zero_suggest_provider.cc
@@ -383,7 +383,7 @@ match.destination_url = navigation.url(); // Zero suggest results should always omit protocols and never appear bold. - auto format_types = AutocompleteMatch::GetFormatTypes(false, false, false); + auto format_types = AutocompleteMatch::GetFormatTypes(false, false); match.contents = url_formatter::FormatUrl(navigation.url(), format_types, net::UnescapeRule::SPACES, nullptr, nullptr, nullptr);
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc index ab00772..44dcecb 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -1358,7 +1358,7 @@ "Name of 'verification_type' matches the CVC pattern.", { {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.form_control_type = "text", .name = "verification_type"}, + {.form_control_type = "password", .name = "verification_type"}, {.role = ElementRole::CURRENT_PASSWORD, .form_control_type = "password"}, },
diff --git a/components/password_manager/core/browser/http_credentials_cleaner.cc b/components/password_manager/core/browser/http_credentials_cleaner.cc index 73fd3e16..ec326e5 100644 --- a/components/password_manager/core/browser/http_credentials_cleaner.cc +++ b/components/password_manager/core/browser/http_credentials_cleaner.cc
@@ -62,7 +62,7 @@ } // This is needed in case of empty |results|. - ReportMetrics(); + SetPrefIfDone(); } void HttpCredentialCleaner::OnHSTSQueryResult( @@ -71,7 +71,7 @@ HSTSResult hsts_result) { ++processed_results_; base::ScopedClosureRunner report(base::BindOnce( - &HttpCredentialCleaner::ReportMetrics, base::Unretained(this))); + &HttpCredentialCleaner::SetPrefIfDone, base::Unretained(this))); if (hsts_result == HSTSResult::kError) return; @@ -81,7 +81,10 @@ auto user_it = https_credentials_map_.find(key); if (user_it == https_credentials_map_.end()) { // Credentials are not migrated yet. - ++https_credential_not_found_[is_hsts]; + base::UmaHistogramEnumeration( + "PasswordManager.HttpCredentials", + is_hsts ? HttpCredentialType::kHasNoMatchingHttpsWithHsts + : HttpCredentialType::kHasNoMatchingHttpsWithoutHsts); if (is_hsts) { // Migrate credentials to HTTPS, by moving them. store_->AddLogin( @@ -94,44 +97,29 @@ if (base::ContainsKey(user_it->second, form->password_value)) { // The password store contains the same credentials (signon_realm, scheme, // username and password) on HTTPS version of the form. - ++same_password_[is_hsts]; + base::UmaHistogramEnumeration( + "PasswordManager.HttpCredentials", + is_hsts ? HttpCredentialType::kHasEquivalentHttpsWithHsts + : HttpCredentialType::kHasEquivalentHttpsWithoutHsts); if (is_hsts) { // This HTTP credential is no more used. store_->RemoveLogin(*form); } } else { - ++different_password_[is_hsts]; + base::UmaHistogramEnumeration( + "PasswordManager.HttpCredentials", + is_hsts ? HttpCredentialType::kHasConflictingHttpsWithHsts + : HttpCredentialType::kHasConflictingHttpsWithoutHsts); } } -void HttpCredentialCleaner::ReportMetrics() { - // The metrics have to be recorded after all requests are done. +void HttpCredentialCleaner::SetPrefIfDone() { if (processed_results_ != total_http_credentials_) return; - for (bool is_hsts_enabled : {false, true}) { - std::string suffix = (is_hsts_enabled ? std::string("WithHSTSEnabled") - : std::string("HSTSNotEnabled")); - - base::UmaHistogramCounts1000( - "PasswordManager.HttpCredentialsWithEquivalentHttpsCredential." + - suffix, - same_password_[is_hsts_enabled]); - - base::UmaHistogramCounts1000( - "PasswordManager.HttpCredentialsWithConflictingHttpsCredential." + - suffix, - different_password_[is_hsts_enabled]); - - base::UmaHistogramCounts1000( - "PasswordManager.HttpCredentialsWithoutMatchingHttpsCredential." + - suffix, - https_credential_not_found_[is_hsts_enabled]); - } - prefs_->SetDouble(prefs::kLastTimeObsoleteHttpCredentialsRemoved, base::Time::Now().ToDoubleT()); observer_->CleaningCompleted(); } -} // namespace password_manager \ No newline at end of file +} // namespace password_manager
diff --git a/components/password_manager/core/browser/http_credentials_cleaner.h b/components/password_manager/core/browser/http_credentials_cleaner.h index bd1bd97..3192d46e 100644 --- a/components/password_manager/core/browser/http_credentials_cleaner.h +++ b/components/password_manager/core/browser/http_credentials_cleaner.h
@@ -43,6 +43,16 @@ class HttpCredentialCleaner : public PasswordStoreConsumer, public CredentialsCleaner { public: + enum class HttpCredentialType { + kHasConflictingHttpsWithoutHsts = 0, + kHasConflictingHttpsWithHsts = 1, + kHasEquivalentHttpsWithoutHsts = 2, + kHasEquivalentHttpsWithHsts = 3, + kHasNoMatchingHttpsWithoutHsts = 4, + kHasNoMatchingHttpsWithHsts = 5, + kMaxValue = kHasNoMatchingHttpsWithHsts + }; + // The cleaning will be made for credentials from |store|. // |network_context_getter| should return nullptr if it can't get the network // context because whatever owns it is dead. @@ -86,9 +96,9 @@ FormKey key, HSTSResult hsts_result); - // After metrics are reported, this function will inform the |observer_| about - // completion. - void ReportMetrics(); + // After all HTTP credentials are processed, this function will inform the + // |observer_| about completion. + void SetPrefIfDone(); // Clean-up is performed on |store_|. scoped_refptr<PasswordStore> store_; @@ -113,24 +123,6 @@ // received. size_t processed_results_ = 0; - // The next three counters are in pairs where [0] component means that HSTS is - // not enabled and [1] component means that HSTS is enabled for that HTTP type - // of credentials. - - // Number of HTTP credentials for which no HTTPS credential for the same - // signon_realm excluding protocol, PasswordForm::scheme and username exists. - size_t https_credential_not_found_[2] = {0, 0}; - - // Number of HTTP credentials for which an equivalent (i.e. same signon_realm - // excluding protocol, PasswordForm::scheme (i.e. HTML, BASIC, etc.), username - // and password) HTTPS credential exists. - size_t same_password_[2] = {0, 0}; - - // Number of HTTP credentials for which a conflicting (i.e. same signon-realm - // excluding the protocol, PasswordForm::Scheme and username but different - // password) HTTPS credential exists. - size_t different_password_[2] = {0, 0}; - // Number of HTTP credentials from the password store. Used to know when all // credentials were processed. size_t total_http_credentials_ = 0; @@ -140,4 +132,4 @@ } // namespace password_manager -#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_HTTP_CREDENTIALS_CLEANER_H_ \ No newline at end of file +#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_HTTP_CREDENTIALS_CLEANER_H_
diff --git a/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc b/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc index 752a0942..d4d09df 100644 --- a/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc +++ b/components/password_manager/core/browser/http_credentials_cleaner_unittest.cc
@@ -27,7 +27,10 @@ namespace { -enum class HttpCredentialType { kNoMatching, kEquivalent, kConflicting }; +// The order of the enumerations needs to the reflect the order of the +// corresponding entries in the HttpCredentialCleaner::HttpCredentialType +// enumeration. +enum class HttpCredentialType { kConflicting, kEquivalent, kNoMatching }; struct TestCase { bool is_hsts_enabled; @@ -210,29 +213,11 @@ cleaner.StartCleaning(&observer); scoped_task_environment.RunUntilIdle(); - std::vector<Histogram> histograms_to_test; - for (bool test_hsts_enabled : {true, false}) { - std::string suffix = - (test_hsts_enabled ? "WithHSTSEnabled" : "HSTSNotEnabled"); - histograms_to_test.push_back( - {test_hsts_enabled, HttpCredentialType::kNoMatching, - "PasswordManager.HttpCredentialsWithoutMatchingHttpsCredential." + - suffix}); - histograms_to_test.push_back( - {test_hsts_enabled, HttpCredentialType::kEquivalent, - "PasswordManager.HttpCredentialsWithEquivalentHttpsCredential." + - suffix}); - histograms_to_test.push_back( - {test_hsts_enabled, HttpCredentialType::kConflicting, - "PasswordManager.HttpCredentialsWithConflictingHttpsCredential." + - suffix}); - } - for (const auto& histogram : histograms_to_test) { - int sample = - static_cast<int>(histogram.test_type == test.expected && - histogram.test_hsts_enabled == test.is_hsts_enabled); - histogram_tester.ExpectUniqueSample(histogram.histogram_name, sample, 1); - } + histogram_tester.ExpectUniqueSample( + "PasswordManager.HttpCredentials", + static_cast<HttpCredentialCleaner::HttpCredentialType>( + static_cast<int>(test.expected) * 2 + test.is_hsts_enabled), + 1); const TestPasswordStore::PasswordMap current_store = store_->stored_passwords();
diff --git a/components/policy/core/common/BUILD.gn b/components/policy/core/common/BUILD.gn index 44e34ae..f9005485 100644 --- a/components/policy/core/common/BUILD.gn +++ b/components/policy/core/common/BUILD.gn
@@ -246,6 +246,8 @@ "cloud/mock_cloud_external_data_manager.h", "cloud/mock_cloud_policy_client.cc", "cloud/mock_cloud_policy_client.h", + "cloud/mock_cloud_policy_service.cc", + "cloud/mock_cloud_policy_service.h", "cloud/mock_cloud_policy_store.cc", "cloud/mock_cloud_policy_store.h", "cloud/mock_device_management_service.cc",
diff --git a/components/policy/core/common/cloud/cloud_policy_core.cc b/components/policy/core/common/cloud/cloud_policy_core.cc index 8c5c9fca..1a9b5aa 100644 --- a/components/policy/core/common/cloud/cloud_policy_core.cc +++ b/components/policy/core/common/cloud/cloud_policy_core.cc
@@ -82,9 +82,9 @@ void CloudPolicyCore::StartRefreshScheduler() { if (!refresh_scheduler_) { - refresh_scheduler_.reset( - new CloudPolicyRefreshScheduler(client_.get(), store_, task_runner_, - network_connection_tracker_getter_)); + refresh_scheduler_ = std::make_unique<CloudPolicyRefreshScheduler>( + client_.get(), store_, service_.get(), task_runner_, + network_connection_tracker_getter_); UpdateRefreshDelayFromPref(); for (auto& observer : observers_) observer.OnRefreshSchedulerStarted(this);
diff --git a/components/policy/core/common/cloud/cloud_policy_refresh_scheduler.cc b/components/policy/core/common/cloud/cloud_policy_refresh_scheduler.cc index 49b3361..a7e0a94 100644 --- a/components/policy/core/common/cloud/cloud_policy_refresh_scheduler.cc +++ b/components/policy/core/common/cloud/cloud_policy_refresh_scheduler.cc
@@ -9,10 +9,12 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/sequenced_task_runner.h" #include "build/build_config.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" +#include "components/policy/core/common/cloud/cloud_policy_service.h" namespace policy { @@ -57,10 +59,12 @@ CloudPolicyRefreshScheduler::CloudPolicyRefreshScheduler( CloudPolicyClient* client, CloudPolicyStore* store, + CloudPolicyService* service, const scoped_refptr<base::SequencedTaskRunner>& task_runner, network::NetworkConnectionTrackerGetter network_connection_tracker_getter) : client_(client), store_(store), + service_(service), task_runner_(task_runner), network_connection_tracker_(network_connection_tracker_getter.Run()), error_retry_delay_ms_(kInitialErrorRetryDelayMs), @@ -333,9 +337,12 @@ // Update |last_refresh_| so another fetch isn't triggered inadvertently. UpdateLastRefresh(); - // The result of this operation will be reported through a callback, at - // which point the next refresh will be scheduled. - client_->FetchPolicy(); + // The result of this operation will be reported through OnPolicyFetched() + // and OnPolicyRefreshed() callbacks. Next refresh will be scheduled in + // OnPolicyFetched(). + service_->RefreshPolicy( + base::BindRepeating(&CloudPolicyRefreshScheduler::OnPolicyRefreshed, + base::Unretained(this))); return; } @@ -374,4 +381,10 @@ last_refresh_ticks_ = base::TimeTicks::Now(); } +void CloudPolicyRefreshScheduler::OnPolicyRefreshed(bool success) { + // Next policy fetch is scheduled in OnPolicyFetched() callback. + VLOG(1) << "Scheduled policy refresh " + << (success ? "successful" : "unsuccessful"); +} + } // namespace policy
diff --git a/components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h b/components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h index 3c8afda..6ac2703 100644 --- a/components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h +++ b/components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h
@@ -22,6 +22,8 @@ namespace policy { +class CloudPolicyService; + // Observes CloudPolicyClient and CloudPolicyStore to trigger periodic policy // fetches and issue retries on error conditions. class POLICY_EXPORT CloudPolicyRefreshScheduler @@ -39,11 +41,12 @@ static const int64_t kRefreshDelayMinMs; static const int64_t kRefreshDelayMaxMs; - // |client| and |store| pointers must stay valid throughout the + // |client|, |store| and |service| pointers must stay valid throughout the // lifetime of CloudPolicyRefreshScheduler. CloudPolicyRefreshScheduler( CloudPolicyClient* client, CloudPolicyStore* store, + CloudPolicyService* service, const scoped_refptr<base::SequencedTaskRunner>& task_runner, network::NetworkConnectionTrackerGetter network_connection_tracker_getter); @@ -115,8 +118,15 @@ // Sets the |last_refresh_| and |last_refresh_ticks_| to current time. void UpdateLastRefresh(); + // Called when policy was refreshed after refresh request. + // It is different than OnPolicyFetched(), which will be called every time + // policy was fetched by the |client_|, does not matter where it was + // requested. + void OnPolicyRefreshed(bool success); + CloudPolicyClient* client_; CloudPolicyStore* store_; + CloudPolicyService* service_; // For scheduling delayed tasks. const scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/components/policy/core/common/cloud/cloud_policy_refresh_scheduler_unittest.cc b/components/policy/core/common/cloud/cloud_policy_refresh_scheduler_unittest.cc index 3959872..ce6b741 100644 --- a/components/policy/core/common/cloud/cloud_policy_refresh_scheduler_unittest.cc +++ b/components/policy/core/common/cloud/cloud_policy_refresh_scheduler_unittest.cc
@@ -17,6 +17,7 @@ #include "build/build_config.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "components/policy/core/common/cloud/mock_cloud_policy_client.h" +#include "components/policy/core/common/cloud/mock_cloud_policy_service.h" #include "components/policy/core/common/cloud/mock_cloud_policy_store.h" #include "services/network/test/test_network_connection_tracker.h" #include "testing/gmock/include/gmock/gmock.h" @@ -25,6 +26,7 @@ namespace em = enterprise_management; using testing::Mock; +using testing::_; namespace policy { @@ -39,7 +41,8 @@ class CloudPolicyRefreshSchedulerTest : public testing::Test { protected: CloudPolicyRefreshSchedulerTest() - : task_runner_(new base::TestSimpleTaskRunner()) {} + : service_(std::make_unique<MockCloudPolicyService>(&client_, &store_)), + task_runner_(new base::TestSimpleTaskRunner()) {} void SetUp() override { client_.SetDMToken("token"); @@ -60,7 +63,7 @@ CloudPolicyRefreshScheduler* CreateRefreshScheduler() { EXPECT_EQ(0u, task_runner_->NumPendingTasks()); CloudPolicyRefreshScheduler* scheduler = new CloudPolicyRefreshScheduler( - &client_, &store_, task_runner_, + &client_, &store_, service_.get(), task_runner_, network::TestNetworkConnectionTracker::CreateGetter()); // Make sure the NetworkConnectionTracker has been set up. base::RunLoop().RunUntilIdle(); @@ -168,6 +171,7 @@ base::MessageLoop loop_; MockCloudPolicyClient client_; MockCloudPolicyStore store_; + std::unique_ptr<MockCloudPolicyService> service_; scoped_refptr<base::TestSimpleTaskRunner> task_runner_; // Base time for the refresh that the scheduler should be using. @@ -181,6 +185,7 @@ CreateRefreshScheduler()); EXPECT_TRUE(task_runner_->HasPendingTask()); EXPECT_EQ(GetLastDelay(), base::TimeDelta()); + EXPECT_CALL(*service_.get(), RefreshPolicy(_)).Times(1); EXPECT_CALL(client_, FetchPolicy()).Times(1); task_runner_->RunUntilIdle(); } @@ -190,6 +195,7 @@ std::unique_ptr<CloudPolicyRefreshScheduler> scheduler( CreateRefreshScheduler()); CheckTiming(CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs); + EXPECT_CALL(*service_.get(), RefreshPolicy(_)).Times(1); EXPECT_CALL(client_, FetchPolicy()).Times(1); task_runner_->RunUntilIdle(); } @@ -199,6 +205,7 @@ CreateRefreshScheduler()); EXPECT_TRUE(task_runner_->HasPendingTask()); CheckInitialRefresh(false); + EXPECT_CALL(*service_.get(), RefreshPolicy(_)).Times(1); EXPECT_CALL(client_, FetchPolicy()).Times(1); task_runner_->RunUntilIdle(); } @@ -210,6 +217,7 @@ std::unique_ptr<CloudPolicyRefreshScheduler> scheduler( CreateRefreshScheduler()); CheckTiming(kPolicyRefreshRate); + EXPECT_CALL(*service_.get(), RefreshPolicy(_)).Times(1); EXPECT_CALL(client_, FetchPolicy()).Times(1); task_runner_->RunUntilIdle(); } @@ -230,6 +238,7 @@ TEST_F(CloudPolicyRefreshSchedulerTest, RefreshSoon) { std::unique_ptr<CloudPolicyRefreshScheduler> scheduler( CreateRefreshScheduler()); + EXPECT_CALL(*service_.get(), RefreshPolicy(_)).Times(1); EXPECT_CALL(client_, FetchPolicy()).Times(1); scheduler->RefreshSoon(); task_runner_->RunUntilIdle(); @@ -257,6 +266,7 @@ store_.NotifyStoreLoaded(); CheckTiming(0); + EXPECT_CALL(*service_.get(), RefreshPolicy(_)).Times(1); EXPECT_CALL(client_, FetchPolicy()).Times(1); task_runner_->RunUntilIdle(); Mock::VerifyAndClearExpectations(&client_); @@ -269,7 +279,7 @@ TEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsAvailable) { std::unique_ptr<CloudPolicyRefreshScheduler> scheduler( new CloudPolicyRefreshScheduler( - &client_, &store_, task_runner_, + &client_, &store_, service_.get(), task_runner_, network::TestNetworkConnectionTracker::CreateGetter())); scheduler->SetDesiredRefreshDelay(kPolicyRefreshRate); @@ -284,6 +294,7 @@ CheckInitialRefresh(true); + EXPECT_CALL(*service_.get(), RefreshPolicy(_)).Times(1); EXPECT_CALL(client_, FetchPolicy()).Times(1); task_runner_->RunPendingTasks(); Mock::VerifyAndClearExpectations(&client_); @@ -300,7 +311,7 @@ TEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsNotAvailable) { std::unique_ptr<CloudPolicyRefreshScheduler> scheduler( new CloudPolicyRefreshScheduler( - &client_, &store_, task_runner_, + &client_, &store_, service_.get(), task_runner_, network::TestNetworkConnectionTracker::CreateGetter())); scheduler->SetDesiredRefreshDelay(kPolicyRefreshRate); @@ -316,6 +327,7 @@ EXPECT_EQ(kPolicyRefreshRate, scheduler->GetActualRefreshDelay()); // Perform that fetch now. + EXPECT_CALL(*service_.get(), RefreshPolicy(_)).Times(1); EXPECT_CALL(client_, FetchPolicy()).Times(1); task_runner_->RunPendingTasks(); Mock::VerifyAndClearExpectations(&client_); @@ -332,11 +344,12 @@ TEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsOffAndOn) { std::unique_ptr<CloudPolicyRefreshScheduler> scheduler( new CloudPolicyRefreshScheduler( - &client_, &store_, task_runner_, + &client_, &store_, service_.get(), task_runner_, network::TestNetworkConnectionTracker::CreateGetter())); scheduler->SetDesiredRefreshDelay(kPolicyRefreshRate); scheduler->SetInvalidationServiceAvailability(true); // Initial fetch. + EXPECT_CALL(*service_.get(), RefreshPolicy(_)).Times(1); EXPECT_CALL(client_, FetchPolicy()).Times(1); task_runner_->RunUntilIdle(); Mock::VerifyAndClearExpectations(&client_); @@ -352,6 +365,7 @@ scheduler->SetInvalidationServiceAvailability(false); scheduler->SetInvalidationServiceAvailability(true); // The next refresh has been scheduled using a lower refresh rate. + EXPECT_CALL(*service_.get(), RefreshPolicy(_)).Times(1); EXPECT_CALL(client_, FetchPolicy()).Times(1); CheckTiming(CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs); task_runner_->RunPendingTasks(); @@ -361,11 +375,12 @@ TEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsDisconnected) { std::unique_ptr<CloudPolicyRefreshScheduler> scheduler( new CloudPolicyRefreshScheduler( - &client_, &store_, task_runner_, + &client_, &store_, service_.get(), task_runner_, network::TestNetworkConnectionTracker::CreateGetter())); scheduler->SetDesiredRefreshDelay(kPolicyRefreshRate); scheduler->SetInvalidationServiceAvailability(true); // Initial fetch. + EXPECT_CALL(*service_.get(), RefreshPolicy(_)).Times(1); EXPECT_CALL(client_, FetchPolicy()).Times(1); task_runner_->RunUntilIdle(); Mock::VerifyAndClearExpectations(&client_); @@ -375,6 +390,7 @@ // The next refresh has been scheduled using a lower refresh rate. // Flush that task. CheckTiming(CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs); + EXPECT_CALL(*service_.get(), RefreshPolicy(_)).Times(1); EXPECT_CALL(client_, FetchPolicy()).Times(1); task_runner_->RunPendingTasks(); Mock::VerifyAndClearExpectations(&client_);
diff --git a/components/policy/core/common/cloud/cloud_policy_service.h b/components/policy/core/common/cloud/cloud_policy_service.h index 1894450..e4a69ef 100644 --- a/components/policy/core/common/cloud/cloud_policy_service.h +++ b/components/policy/core/common/cloud/cloud_policy_service.h
@@ -50,7 +50,7 @@ // Refreshes policy. |callback| will be invoked after the operation completes // or aborts because of errors. - void RefreshPolicy(const RefreshPolicyCallback& callback); + virtual void RefreshPolicy(const RefreshPolicyCallback& callback); // Unregisters the device. |callback| will be invoked after the operation // completes or aborts because of errors. All pending refresh policy requests
diff --git a/components/policy/core/common/cloud/cloud_policy_service_unittest.cc b/components/policy/core/common/cloud/cloud_policy_service_unittest.cc index 10cdd8d..ee6296c 100644 --- a/components/policy/core/common/cloud/cloud_policy_service_unittest.cc +++ b/components/policy/core/common/cloud/cloud_policy_service_unittest.cc
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "components/policy/core/common/cloud/mock_cloud_policy_client.h" +#include "components/policy/core/common/cloud/mock_cloud_policy_service.h" #include "components/policy/core/common/cloud/mock_cloud_policy_store.h" #include "components/policy/proto/device_management_backend.pb.h" #include "testing/gmock/include/gmock/gmock.h" @@ -21,17 +22,6 @@ namespace policy { -class MockCloudPolicyServiceObserver : public CloudPolicyService::Observer { - public: - MockCloudPolicyServiceObserver() {} - ~MockCloudPolicyServiceObserver() override {} - - MOCK_METHOD0(OnCloudPolicyServiceInitializationCompleted, void()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyServiceObserver); -}; - class CloudPolicyServiceTest : public testing::Test { public: CloudPolicyServiceTest()
diff --git a/components/policy/core/common/cloud/machine_level_user_cloud_policy_metrics.h b/components/policy/core/common/cloud/machine_level_user_cloud_policy_metrics.h index 7af0aa9..8423d0db 100644 --- a/components/policy/core/common/cloud/machine_level_user_cloud_policy_metrics.h +++ b/components/policy/core/common/cloud/machine_level_user_cloud_policy_metrics.h
@@ -10,7 +10,7 @@ // This enum is used for recording the metrics. It must match the // MachineLevelUserCloudPolicyEnrollmentResult in enums.xml and should not be // reordered. |kMaxValue| must be assigned to the last entry of the enum. -enum MachineLevelUserCloudPolicyEnrollmentResult { +enum class MachineLevelUserCloudPolicyEnrollmentResult { kSuccess = 0, kFailedToFetch = 1, kFailedToStore = 2,
diff --git a/components/policy/core/common/cloud/mock_cloud_policy_service.cc b/components/policy/core/common/cloud/mock_cloud_policy_service.cc new file mode 100644 index 0000000..1d83ede --- /dev/null +++ b/components/policy/core/common/cloud/mock_cloud_policy_service.cc
@@ -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. + +#include "components/policy/core/common/cloud/mock_cloud_policy_service.h" +#include "components/policy/core/common/cloud/cloud_policy_client.h" +#include "components/policy/core/common/cloud/cloud_policy_store.h" + +namespace policy { + +MockCloudPolicyService::MockCloudPolicyService(CloudPolicyClient* client, + CloudPolicyStore* store) + : CloudPolicyService(std::string(), std::string(), client, store) { + // Besides recording the mock call, invoke real RefreshPolicy() method. + // That way FetchPolicy() is called on the |client|. + ON_CALL(*this, RefreshPolicy(testing::_)) + .WillByDefault( + testing::Invoke(this, &MockCloudPolicyService::InvokeRefreshPolicy)); +} + +MockCloudPolicyService::~MockCloudPolicyService() = default; + +void MockCloudPolicyService::InvokeRefreshPolicy( + const RefreshPolicyCallback& callback) { + CloudPolicyService::RefreshPolicy(callback); +} + +MockCloudPolicyServiceObserver::MockCloudPolicyServiceObserver() = default; + +MockCloudPolicyServiceObserver::~MockCloudPolicyServiceObserver() = default; + +} // namespace policy
diff --git a/components/policy/core/common/cloud/mock_cloud_policy_service.h b/components/policy/core/common/cloud/mock_cloud_policy_service.h new file mode 100644 index 0000000..d5b82b29 --- /dev/null +++ b/components/policy/core/common/cloud/mock_cloud_policy_service.h
@@ -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. + +#ifndef COMPONENTS_POLICY_CORE_COMMON_CLOUD_MOCK_CLOUD_POLICY_SERVICE_H_ +#define COMPONENTS_POLICY_CORE_COMMON_CLOUD_MOCK_CLOUD_POLICY_SERVICE_H_ + +#include "base/macros.h" +#include "components/policy/core/common/cloud/cloud_policy_service.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace policy { + +class CloudPolicyClient; +class CloudPolicyStore; + +class MockCloudPolicyService : public CloudPolicyService { + public: + MockCloudPolicyService(CloudPolicyClient* client, CloudPolicyStore* store); + ~MockCloudPolicyService() override; + + MOCK_METHOD1(RefreshPolicy, void(const RefreshPolicyCallback&)); + + private: + // Invokes real RefreshPolicy() method. + void InvokeRefreshPolicy(const RefreshPolicyCallback& callback); + + DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyService); +}; + +class MockCloudPolicyServiceObserver : public CloudPolicyService::Observer { + public: + MockCloudPolicyServiceObserver(); + ~MockCloudPolicyServiceObserver() override; + + MOCK_METHOD0(OnCloudPolicyServiceInitializationCompleted, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyServiceObserver); +}; + +} // namespace policy + +#endif // COMPONENTS_POLICY_CORE_COMMON_CLOUD_MOCK_CLOUD_POLICY_SERVICE_H_
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto index a2f4fd8..ced883c 100644 --- a/components/policy/proto/chrome_device_policy.proto +++ b/components/policy/proto/chrome_device_policy.proto
@@ -761,6 +761,13 @@ optional Rotation display_rotation_default = 1; } +// This setting is configured by the device policy DeviceDisplayResolution. +// If |device_display_resolution| contains a value, then it's treated as a JSON +// object that uses the schema defined for DeviceDisplayResolution policy. +message DeviceDisplayResolutionProto { + optional string device_display_resolution = 1; +} + // Settings that control whether to allow Chrome to be pinned to a specific // version according to the auto-launched kiosk app’s requirement. message AllowKioskAppControlChromeVersionProto { @@ -1178,4 +1185,5 @@ device_unaffiliated_crostini_allowed = 72; optional DeviceWiFiFastTransitionEnabledProto device_wifi_fast_transition_enabled = 73; + optional DeviceDisplayResolutionProto device_display_resolution = 74; }
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 246cbb1..f5dd806 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -13833,6 +13833,62 @@ For more information on Internet Explorer's <ph name="IEEM_SITELIST_POLICY">SiteList</ph> policy: https://docs.microsoft.com/internet-explorer/ie11-deploy-guide/what-is-enterprise-mode''', }, + { + 'name': 'DeviceDisplayResolution', + 'type': 'dict', + 'schema': { + 'type': 'object', + 'properties': { + 'external_width': { 'type': 'integer', 'minimum': 1 }, + 'external_height': { 'type': 'integer', 'minimum': 1 }, + 'external_scale_percentage': { 'type': 'integer', 'minimum': 1 }, + 'external_use_native': { 'type': 'boolean' }, + 'internal_scale_percentage': { 'type': 'integer', 'minimum': 1 }, + 'recommended': { 'type': 'boolean' } + } + }, + 'supported_on': [ 'chrome_os:72-' ], + 'features': { + 'can_be_recommended': False, + 'dynamic_refresh': True, + 'per_profile': False, + }, + 'device_only': True, + 'example_value': { + 'external_width': 1920, + 'external_height': 1080, + 'external_use_native': False, + 'external_scale_percentage': 100, + 'internal_scale_percentage': 150, + 'recommended': True + }, + 'id': 502, + 'caption': '''Set display resolution and scale factor''', + 'tags': [], + 'desc': '''When this policy is set, resolution and scale factor of each + display are set to the specified values. External display settings are + applied to all connected external displays. + + Values of "external_width" and "external_height" should be specified in + pixels. Values of "external_scale_percentage" and + "internal_scale_percentage" should be specified in percents. + + If "external_use_native" is set to true, policy will ignore values of + "external_height" and "external_width" and set resolution of the external + displays to their native resolution. + + If "external_use_native" is false or not provided and either + "external_height" or "external_width" is not provided, policy doesn't + affect the external display settings. If specified resolution or + scale factor is not supported by some display, policy is not applied to + that display. + + If "recommended" flag is set to true, users may change resolution and + scale factor of any display via the settings page after logging in, but + their settings will be overriden by the policy value at the next reboot. + If "recommended" flag is set to false or not set, users can't change the + display settings.''', + } ], 'messages': { @@ -13974,5 +14030,5 @@ }, 'placeholders': [], 'deleted_policy_ids': [412], - 'highest_id_currently_used': 501 + 'highest_id_currently_used': 502 }
diff --git a/components/policy/resources/policy_templates_am.xtb b/components/policy/resources/policy_templates_am.xtb index 9458f76..40940b94 100644 --- a/components/policy/resources/policy_templates_am.xtb +++ b/components/policy/resources/policy_templates_am.xtb
@@ -2174,11 +2174,6 @@ <translation id="6689792153960219308">የሃርድዌር ሁኔታን ሪፓርት ያድርጉ</translation> <translation id="6698632841807204978">የሞኖክሮም ህትመትን ያንቁ</translation> <translation id="6699880231565102694">ባለሁለት ክፍል ማረጋገጫ ለሩቅ መዳረሻ አስተናጋጆችን ያንቁ</translation> -<translation id="6724842112053619797">ይህን ቅንብር ካነቁት እንደ ዕልባቶች፣ የራስ-ሙላ ውሂብ፣ የይለፍ ቃላት፣ ወዘተ ያሉ በ<ph name="PRODUCT_NAME" /> መገለጫዎች ውስጥ የተከማቹት ቅንብሮች እንዲሁም በተንዣባቢ የተጠቃሚ መገለጫ አቃፊ ውስጥ ባለ የተከማቸ ፋይል ወይም በ<ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> መመሪያ በኩል በአስተዳዳሪው በተገለጸ ቦታ ላይ ይጻፋሉ። ይህን መመሪያ ማንቃት የደመና ስምረትን ያሰናከላል። - - ይህ መመሪያ ከተሰናከለ ወይም ካልተዋቀረ መደበኛዎቹ አካባቢያዊ መገለጫዎች ብቻ ናቸው ጥቅም ላይ የሚውሉት። - - የ<ph name="SYNC_DISABLED_POLICY_NAME" /> መመሪያ RoamingProfileSupportEnabledን በመሻር ሁሉንም የውሂብ ስምረት ያሰናክላል።</translation> <translation id="6731757988219967594">ለዐዋቂ ይዘት ከፍተኛ ደረጃ ጣቢያዎችን (ሆኖንም ግን ያልተካተቱ iframes) አጣራ</translation> <translation id="6734521799274931721">የአውታረ መረብ ፋይል ማጋሪያዎችን ለChromeOS ተገኝነትን ይቆጣጠራል</translation> <translation id="6735701345096330595">የፊደል ማረሚያ ቋንቋዎችን በግዳጅ ያንቁ</translation>
diff --git a/components/policy/resources/policy_templates_ar.xtb b/components/policy/resources/policy_templates_ar.xtb index 1c18ade..ff366fd 100644 --- a/components/policy/resources/policy_templates_ar.xtb +++ b/components/policy/resources/policy_templates_ar.xtb
@@ -2063,11 +2063,6 @@ <translation id="6689792153960219308">الإبلاغ عن حالة الأجهزة</translation> <translation id="6698632841807204978">تفعيل الطباعة أحادية اللون</translation> <translation id="6699880231565102694">تفعيل المصادقة الثنائية لعمليات استضافة الدخول عن بُعد</translation> -<translation id="6724842112053619797">في حالة تفعيل هذا الإعداد، سيتم أيضًا تسجيل الإعدادات المخزّنة في الملفات الشخصية في <ph name="PRODUCT_NAME" />، مثل الإشارات المرجعية، وبيانات الملء التلقائي، وكلمات المرور وغيرها، في ملف مخزّن في مجلد الملف الشخصي للتجوال التابع للمستخدم أو في موقع تم تحديده من قِبل المشرف من خلال سياسة <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. ويعمل تفعيل هذه السياسة على إيقاف المزامنة عبر السحاب. - - في حالة إيقاف هذه السياسة أو تركها بدون تعيين، سيتم استخدام الملفات الشخصية المحلية العادية فقط. - - تعمل السياسة <ph name="SYNC_DISABLED_POLICY_NAME" /> على إيقاف جميع عمليات المزامنة للبيانات، وتجاوز RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">تصفية مواقع الويب ذات المستوى الأعلى (باستثناء أطُر iframe المدمجة) لمحتوى البالغين</translation> <translation id="6734521799274931721">تتحكّم في مدى توفُّر خوادم مشاركة الملفات على الشبكة لنظام التشغيل Chrome.</translation> <translation id="6735701345096330595">فرض تفعيل التدقيق الإملائي للغات</translation>
diff --git a/components/policy/resources/policy_templates_bg.xtb b/components/policy/resources/policy_templates_bg.xtb index ae6bd93..4ec9138 100644 --- a/components/policy/resources/policy_templates_bg.xtb +++ b/components/policy/resources/policy_templates_bg.xtb
@@ -2091,11 +2091,6 @@ <translation id="6689792153960219308">Изпращане на информация за състоянието на хардуера</translation> <translation id="6698632841807204978">Активиране на монохромното отпечатване</translation> <translation id="6699880231565102694">Активиране на двуфакторното удостоверяване за хостове за отдалечен достъп</translation> -<translation id="6724842112053619797">Ако активирате това правило, запазените в потребителските профили в <ph name="PRODUCT_NAME" /> настройки, като например отметки, данни за автоматично попълване, пароли и др., ще се записват и във файл, съхраняван в папката за подвижни потребителски профили или в местоположение, посочено от администратора чрез <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. При активиране на правилото синхронизирането с облака ще се изключи. - -В случай че правилото е деактивирано или не е зададено, ще се използват само обикновените локални потребителски профили. - -<ph name="SYNC_DISABLED_POLICY_NAME" /> деактивира синхронизирането на всички данни, заменяйки правилото RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Филтриране на сайтовете от първо ниво (без вложените рамки) заради съдържание за пълнолетни</translation> <translation id="6734521799274931721">Управление на наличността на функцията на Chrome OS за споделяне на файлове в мрежата</translation> <translation id="6735701345096330595">Принудително активиране на езици за проверка на правописа</translation>
diff --git a/components/policy/resources/policy_templates_bn.xtb b/components/policy/resources/policy_templates_bn.xtb index d94a7eb..44baf6a 100644 --- a/components/policy/resources/policy_templates_bn.xtb +++ b/components/policy/resources/policy_templates_bn.xtb
@@ -128,15 +128,15 @@ <translation id="1291880496936992484">সতর্কতা: সংস্করণ 52 (সেপ্টেম্বর ২০১৬ এর কাছাকাছি) এর পরে <ph name="PRODUCT_NAME" /> থেকে RC4 সম্পূর্ণভাবে সরিয়ে ফেলা হবে এবং তখন এই নীতি কাজ করবে না। এই নীতিটি সেট না করা হলে, বা মিথ্যাতে সেট করা থাকলে, TLS এ RC4 সাইফার স্যুট সক্ষম করা হবে না। অন্যথায়, এটি একটি পুরোনো সার্ভারের সাথে সামঞ্জস্য বজায় রাখার জন্য সত্যতে সেট করা যেতে পারে। এটি একটি অস্থায়ী সমাধান এবং সার্ভারটি আবার কনফিগার করা উচিত।</translation> -<translation id="1297117713060236551">এই নীতি এমন ওয়েবসাইটগুলির তালিকা নিয়ন্ত্রণ করে যেগুলি কখনই ব্রাউজার সুইচের কারণ হবে না। +<translation id="1297117713060236551">এই নীতি এমন ওয়েবসাইটগুলির তালিকা নিয়ন্ত্রণ করে যেগুলির কারণে একটি ব্রাউজার থেকে অন্য ব্রাউজারে যাওয়ার প্রয়োজন পড়বে না। - মনে রাখবেন যে <ph name="USE_IE_SITELIST_POLICY_NAME" /> নীতির দ্বারা এই তালিকায় উপাদানগুলি যোগও করা যেতে পারে। + এছাড়াও মনে রাখবেন যে <ph name="USE_IE_SITELIST_POLICY_NAME" /> নীতির দ্বারা এই তালিকায় উপাদানগুলি যোগ করা যেতে পারে। - এই নীতিটিকে সেট না করা অবস্থায় রেখে দিলে, তালিকায় কোনও ওয়েবসাইট যোগ হয় না। + নীতিটি সেট না করা অবস্থায় রেখে দিলে, তালিকায় কোনও ওয়েবসাইট যোগ করা হয় না। - নীতি সেট করা থাকলে, প্রতিবার <ph name="URL_LIST_POLICY_NAME" /> নীতির অনুরূপ নিয়ম হিসেবে বিবেচনা করা হয়। তবে, যুক্তিটি উল্টো: মিলে যাওয়া নিয়ম বিকল্প ব্রাউজার খুলবে না। + নীতিটি সেট করা থাকলে, প্রতিটি আইটেমকে <ph name="URL_LIST_POLICY_NAME" /> নীতির অনুরূপ একটি নিয়ম হিসেবে বিবেচনা করা হয়। তবে, যুক্তিটি উল্টো: মিলে যাওয়া নিয়ম বিকল্প ব্রাউজার খুলবে না। - <ph name="URL_LIST_POLICY_NAME" />-এ না হলেও, এই ক্ষেত্রে উভয় দিকেই নিয়ম প্রযোজ্য হয়। Internet Explorer অ্যাড-ইন চালু অবস্থায় থাকলে <ph name="IE_PRODUCT_NAME" />-এর <ph name="PRODUCT_NAME" />-এ এই ইউআরএলগুলি খোলা উচিত কিনা তাও নিয়ন্ত্রণ করে।</translation> + <ph name="URL_LIST_POLICY_NAME" />-এ না হলেও, এক্ষেত্রে উভয় দিকেই নিয়ম প্রযোজ্য হয়। Internet Explorer অ্যাড-ইন চালু অবস্থায় থাকলে <ph name="IE_PRODUCT_NAME" />, <ph name="PRODUCT_NAME" />-এ এই ইউআরএলগুলি খুলবে কিনা এটি তাও নিয়ন্ত্রণ করে।</translation> <translation id="1297182715641689552">একটি .pac প্রক্সি স্ক্রিপ্ট ব্যবহার করুন</translation> <translation id="1304973015437969093">এক্সটেনশন/অ্যাপ আইডিগুলি এবং আপডেট ইউআরএলগুলি নীরবে ইনস্টল হবে</translation> <translation id="1307454923744766368">উৎস অথবা হোস্টনেম প্যাটার্ন যার জন্য অনিরাপদ উৎসের @@ -263,7 +263,7 @@ <translation id="1509692106376861764"><ph name="PRODUCT_NAME" /> ২৯ সংস্করণে এই নীতিটি সরানো হয়েছে৷</translation> <translation id="1514888685242892912"><ph name="PRODUCT_NAME" /> চালু করুন</translation> <translation id="1522425503138261032">ব্যবহারকারীর শারীরিক লোকেশন ট্র্যাক করতে সাইটগুলিকে অনুমতি দিন</translation> -<translation id="1523774894176285446">কনফিগার করার ওয়েবসাইটগুলির জন্য বিকল্প ব্রাউজার চালু করা।</translation> +<translation id="1523774894176285446">কনফিগার করা ওয়েবসাইটগুলির জন্য বিকল্প ব্রাউজার খোলা।</translation> <translation id="152657506688053119">ডিফল্ট সার্চ প্রদানকারীর জন্য পরিবর্ত URLগুলির তালিকা</translation> <translation id="1530812829012954197">আয়োজক ব্রাউজারে সর্বদা নিম্নোক্ত URL রীতি উপস্থাপন করুন</translation> <translation id="1541170838458414064">প্রিন্টের পৃষ্ঠার সাইজ সীমাবদ্ধ করা</translation> @@ -275,10 +275,10 @@ এই সেটিং বন্ধ করা থাকলে বা কনফিগার করা না থাকলে, এন্টারপ্রাইজ ব্যবহারকারীরা ARC ব্যবহার করতে পারবে না।</translation> <translation id="1559980755219453326">এক্সটেনশন এবং প্লাগইন সংক্রান্ত তথ্য রিপোর্ট করা হবে কিনা তা এই নীতি নিয়ন্ত্রণ করে। - এই নীতি ট্রু হিসেবে সেট করা থাকলে এক্সটেনশন এবং প্লাগইন সংক্রান্ত ডেটা সংগ্রহ করা হয়। + এই নীতি সেট করা না থাকলে অথবা ট্রু হিসেবে সেট করা থাকলে এক্সটেনশন এবং প্লাগইন সংক্রান্ত ডেটা সংগ্রহ করা হয়। এই নীতি ফলস হিসেবে সেট করা থাকলে এক্সটেনশন এবং প্লাগইন সংক্রান্ত ডেটা সংগ্রহ করা হয় না। - <ph name="CHROME_REPORTING_EXTENSION_NAME" /> চালু থাকলে এবং <ph name="MACHINE_LEVEL_USER_CLOUD_POLICY_ENROLLMENT_TOKEN_POLICY_NAME" />-এর সাথে মেশিন নথিভুক্ত করা থাকলে এই নীতিটি কার্যকর হয়।</translation> + শুধু <ph name="CHROME_REPORTING_EXTENSION_NAME" /> চালু থাকলে এবং <ph name="MACHINE_LEVEL_USER_CLOUD_POLICY_ENROLLMENT_TOKEN_POLICY_NAME" />-এর সাথে মেশিন নথিভুক্ত করা থাকলে এই নীতিটি কার্যকর হয়।</translation> <translation id="1561424797596341174">দূরবর্তী অ্যাক্সেস হোস্টের ত্রুটিমুক্তকরণ বিল্ডের জন্য নীতি ওভাররাইড</translation> <translation id="1561967320164410511">স্বতন্ত্রভাবে নিশ্চিত করার জন্য U2F এবং এক্সটেনশন</translation> <translation id="1574554504290354326">এই সেটিংসটি শীঘ্রই বন্ধ হয়ে যাবে, এর পরিবর্তে SafeBrowsingExtendedReportingEnabled ব্যবহার করুন। SafeBrowsingExtendedReportingOptInAllowed 'ফল্সে' সেট করা থাকলে, SafeBrowsingExtendedReportingEnabled চালু বা বন্ধ করলে কোনও কাজ হয় না। @@ -752,7 +752,7 @@ এই নীতি সাইন-ইন স্ক্রিনের ক্ষেত্রে প্রযোজ্য। <ph name="SITE_PER_PROCESS_POLICY_NAME" /> নীতি দেখুন যা ব্যবহারকারীর সেশনের ক্ষেত্রে প্রযোজ্য। উভয় নীতির জন্য সমান মান সেট করার সাজেশন দেওয়া হয়। যদি মানগুলি না মেলে তাহলে ব্যবহারকারীর সেশনে প্রবেশ করার সময় ব্যবহারকারী নীতি দ্বারা নির্দিষ্ট মানটি প্রয়োগ করার কারণে দেরী হতে পারে। আইসোলেশন চালু রাখা এবং ব্যবহারকারীদের উপরে সম্ভাব্য নেতিবাচক প্রভাব সীমিত রাখা, দুধরনেরই সুবিধা পাওয়ার জন্য আপনি IsolateOrigins নীতির সেটিং দেখে নিতে চাইতে পারেন যাতে IsolateOrigins ব্যবহার করে আপনার বেছে নেওয়া সাইটগুলি অন্যান্য সাইটের থেকে আইসোলেট করতে পারেন। SitePerProcess সেটিংস সমস্ত সাইট আইসোলেট করে। নীতিটি চালু থাকলে প্রতিটি সাইট তার নিজস্ব প্রসেসের মধ্যে কাজ করবে। - নীতিটি বন্ধ থাকলে IsolateOrigins ও SitePerProcess ফিচার বন্ধ থাকবে। ব্যবহারকারীরা তাও কম্যান্ড লাইন ফ্ল্যাগের দ্বারা ম্যানুয়ালভাবে SitePerProcess চালু করতে পারবেন। + নীতিটি বন্ধ থাকলে IsolateOrigins ও SitePerProcess ফিচার বন্ধ থাকবে। ব্যবহারকারীরা তাও কমান্ড লাইন ফ্ল্যাগের দ্বারা ম্যানুয়ালভাবে SitePerProcess চালু করতে পারবেন। নীতিটি কনফিগার করা না থাকলে ব্যবহারকারী এই সেটিং পরিবর্তন করতে পারবেন। </translation> <translation id="2672012807430078509">SMB মাউন্ট করার জন্য যাচাইকরণের একটি প্রোটোকল হিসেবে NTLM চালু করাকে নিয়ন্ত্রণ করে</translation> @@ -900,17 +900,17 @@ <translation id="3038323923255997294">পটভূমি অ্যাপ্লিকেশন অবিরত চলমান যখন <ph name="PRODUCT_NAME" /> বন্ধ হয়</translation> <translation id="3046192273793919231">অনলাইন অবস্থা পর্যবেক্ষণ করতে ব্যবস্থাপনা সার্ভারে নেটওয়ার্ক প্যাকেট পাঠায়</translation> <translation id="3047732214002457234">Chrome ক্লিনআপ Google-এ কোন কোন তথ্য রিপোর্ট করবে তা নিয়ন্ত্রণ করুন</translation> -<translation id="304775240152542058">বিকল্প ব্রাউজার চালু করতে এই নীতি কম্যান্ড-লাইন প্যারামিটারগুলি নিয়ন্ত্রণ করে। +<translation id="304775240152542058">বিকল্প ব্রাউজার খুলতে এই নীতি কমান্ড-লাইন প্যারামিটারগুলি নিয়ন্ত্রণ করে। - নীতি সেট না করা অবস্থায় থাকলে ইউআরএল শুধুমাত্র কম্যান্ড-লাইন প্যারামিটার হিসেবে পাস করা হয়। + নীতি সেট না করা অবস্থায় থাকলে ইউআরএল শুধুমাত্র কমান্ড-লাইন প্যারামিটার হিসেবে পাস করা হয়। - নীতিটি স্ট্রিংয়ের তালিকায় সেট করা থাকলে, প্রতিটি স্ট্রিংকে আলাদা কম্যান্ড-লাইন প্যারামিটার হিসেবে বিকল্প ব্রাউজারে পাস করা হয়। Windows-এ, প্যারামিটারগুলি স্পেস সহ যুক্ত হয়। Mac OS X এবং Linux-এ, প্যারামিটারের মধ্যে স্পেস থাকতে পারে এবং তাও একক প্যারামিটার গণ্য করা হয়। + নীতিটি স্ট্রিংয়ের তালিকায় সেট করা থাকলে, প্রতিটি স্ট্রিংকে আলাদা কমান্ড-লাইন প্যারামিটার হিসেবে বিকল্প ব্রাউজারে পাস করা হয়। Windows-এ, প্যারামিটারগুলি স্পেস সহ যুক্ত হয়। Mac OS X এবং Linux-এ, প্যারামিটারের মধ্যে স্পেস থাকতে পারে এবং তাও একক প্যারামিটার গণ্য করা হয়। - যদি কোনও উপাদানে ${url} থাকে তাহলে যে পৃষ্ঠাটি খোলা হবে সেটির ইউআরএলের দ্বারা এটি বদলে যাবে। + যদি কোনও উপাদানে ${url} থাকে তাহলে যে পৃষ্ঠাটি খোলা হবে সেটির ইউআরএলের দ্বারা এটি প্রতিস্থাপিত হবে। - যদি কোনও উপাদানে ${url} না থাকে তাহলে ইউআরএলটি কম্যান্ড-লাইনের শেষে যুক্ত করা হয়। + যদি কোনও উপাদানে ${url} না থাকে তাহলে ইউআরএলটি কমান্ড-লাইনের শেষে যুক্ত করা হয়। - এনভায়রনমেন্ট ভেরিয়েবলগুলি বড় করা হয়েছে। Windows-এ, ABC এনভায়রনমেন্ট ভেরিয়েবলের দ্বারা %ABC% বদলে যায়। Mac OS X এবং Linux-এ, ABC এনভায়রনমেন্ট ভেরিয়েবলের দ্বারা ${ABC} বদলে যায়।</translation> + এনভায়রনমেন্ট ভেরিয়েবলগুলি বড় করা হয়েছে। Windows-এ, ABC এনভায়রনমেন্ট ভেরিয়েবলের মান দ্বারা %ABC% প্রতিস্থাপিত হয়। Mac OS X এবং Linux-এ, ABC এনভায়রনমেন্ট ভেরিয়েবলের মান দ্বারা ${ABC} প্রতিস্থাপিত হয়।</translation> <translation id="3048744057455266684">যদি এই নীতিটি সেট করা হয় এবং ক্যোয়েরি স্ট্রিং বা বিভাগ সনাক্তকারীতে বহুউপয়োগী ক্ষেত্র থেকে প্রস্তাবিত কোনো সার্চ URL এ এই মাপদণ্ডটি থাকে, তখন শুধুমাত্র একটি সার্চ URL এর পরিবর্তে পরামর্শটি সার্চ পদগুলি এবং সার্চ প্রদানকারী দেখাবে৷ এই নীতিটি হল ঐচ্ছিক৷ যদি সেট করা না থাকে, তাহলে কোনো সার্চ পদের প্রতিস্থাপন করা যাবে না৷ @@ -1000,9 +1000,9 @@ যখন এই নীতিটিকে সেট করা হয় না , তখন একটি ডিফল্ট সময়কাল ব্যবহৃত হয়৷ নীতির মানটি মিলিসেকেন্ডে নির্ধারণ করা উচিত৷ স্ক্রিন বন্ধ হওয়ার এবং নিষ্ক্রিয়তা বিলম্বের শেষ সীমা থেকে কম বা এর সমান হিসাবে মানগুলি ধার্য করা হয়ে থাকে (যদি সেট থাকে)৷</translation> -<translation id="3251500716404598358">ব্রাউজারগুলির মধ্যে সুইচ করার জন্য নীতি কনফিগার করুন। +<translation id="3251500716404598358">ব্রাউজারগুলির মধ্যে একটি থেকে অন্যটিতে যাওয়ার জন্য নীতিগুলি কনফিগার করুন। - কনফিগার করা ব্রাউজারগুলি নিজে থেকেই <ph name="PRODUCT_NAME" />-এর পরিবর্তে অন্য একটি ব্রাউজারে খুলবে।</translation> + কনফিগার করা ওয়েবসাইটগুলি নিজে থেকেই <ph name="PRODUCT_NAME" />-এর পরিবর্তে অন্য একটি ব্রাউজারে খুলবে।</translation> <translation id="3264793472749429012">ডিফল্ট সার্চ সরবরাহকারী এনকোডিংগুলি</translation> <translation id="3273221114520206906">ডিফল্ট JavaScript সেটিং</translation> <translation id="3284094172359247914">WebUSB এপিআই-এর ব্যবহার নিয়ন্ত্রণ করুন</translation> @@ -1150,11 +1150,11 @@ <translation id="3577251398714997599">যে সাইটে ব্যাঘাতকারী বিজ্ঞাপন দেখানো হয় সেই সাইটের জন্য বিজ্ঞাপন সেটিংস</translation> <translation id="3591584750136265240">লগইন প্রমাণীকরণ আচরণ কনফিগার করে</translation> <translation id="3624171042292187668"> - আইসোলেশন চালু রাখা এবং ব্যবহারকারীদের উপরে সম্ভাব্য নেতিবাচক প্রভাব সীমিত রাখা, দুধরনেরই সুবিধা পাওয়ার জন্য আপনি IsolateOrigins নীতির সেটিং দেখে নিতে চাইতে পারেন যাতে IsolateOrigins ব্যবহার করে আপনার বেছে নেওয়া সাইটগুলি অন্যান্য সাইটের থেকে বিচ্ছিন্ন করতে পারেন। SitePerProcess সেটিংস সমস্ত সাইট বিচ্ছিন্ন করে। + আইসোলেশন চালু রাখা এবং ব্যবহারকারীদের উপরে সম্ভাব্য নেতিবাচক প্রভাব সীমিত রাখা, দুধরনেরই সুবিধা পাওয়ার জন্য আপনি IsolateOrigins নীতির সেটিং দেখে নিতে চাইতে পারেন যাতে IsolateOrigins ব্যবহার করে আপনার বেছে নেওয়া সাইটগুলি অন্যান্য সাইটের থেকে আইসোলেট করতে পারেন। SitePerProcess সেটিংস সমস্ত সাইট আইসোলেট করে। নীতিটি চালু থাকলে প্রতিটি সাইট তার নিজস্ব প্রসেসের মধ্যে কাজ করবে। - নীতিটি বন্ধ থাকলে IsolateOrigins ও SitePerProcess ফিচার বন্ধ থাকবে। ব্যবহারকারীরা তাও কম্যান্ড লাইন ফ্ল্যাগের দ্বারা ম্যানুয়ালভাবে SitePerProcess চালু করতে পারবেন। + নীতিটি বন্ধ থাকলে IsolateOrigins ও SitePerProcess ফিচার বন্ধ থাকবে। ব্যবহারকারীরা তাও কমান্ড লাইন ফ্ল্যাগের দ্বারা ম্যানুয়ালভাবে SitePerProcess চালু করতে পারবেন। নীতিটি কনফিগার করা না থাকলে ব্যবহারকারী এই সেটিং পরিবর্তন করতে পারবেন। - <ph name="PRODUCT_OS_NAME" />-এ, <ph name="DEVICE_LOGIN_SCREEN_SITE_PER_PROCESS_POLICY_NAME" /> ডিভাইস নীতি একই মানে সেট করার সাজেশন দেওয়া হয়। উভয় নীতির দ্বারা নির্দিষ্ট করা মান যদি না মেলে তাহলে ব্যবহারকারীর সেশন লেখার সময় বিলম্ব হতে পারে কিন্তু ব্যবহারকারীর নীতি দ্বারা নির্দিষ্ট করা মান প্রযোজ্য হবে। + <ph name="PRODUCT_OS_NAME" />-এ, <ph name="DEVICE_LOGIN_SCREEN_SITE_PER_PROCESS_POLICY_NAME" /> ডিভাইস নীতি একই মানে সেট করার সাজেশন দেওয়া হয়। যদি উভয় নীতির দ্বারা নির্দিষ্ট করা মানগুলি না মেলে তাহলে ব্যবহারকারীর সেশনে প্রবেশ করার সময় ব্যবহারকারী নীতি দ্বারা নির্দিষ্ট মানটি প্রয়োগ করার কারণে দেরী হতে পারে। দ্রষ্টব্য: এই নীতি Android-এর ক্ষেত্রে প্রযোজ্য নয়। Android-এ SitePerProcess চালু করতে SitePerProcessAndroid নীতি সেটিং ব্যবহার করুন। </translation> <translation id="3627678165642179114">বানান পরীক্ষা ওয়েব পরিষেবা সক্ষম বা অক্ষম করুন</translation> @@ -1328,7 +1328,7 @@ নীতিটি সত্যতে সেট করা থাকলে, মনিটরিং নেটওয়ার্ক প্যাকেট (তথাকথিত <ph name="HEARTBEATS_TERM" />) পাঠানো হবে। যদি তা মিথ্যাতে সেট করা থাকে বা সেট না করা থাকে, তাহলে কোনো প্যাকেট পাঠানো হবে না।</translation> <translation id="3950239119790560549">আপডেট করার সীমাবদ্ধতা</translation> -<translation id="3956686688560604829">পুরানো ব্রাউজারের বিষয়ে সহায়তার জন্য Internet Explorer-এর সাইটের তালিকা নীতি ব্যবহার করুন</translation> +<translation id="3956686688560604829">পুরনো ভার্সনের ব্রাউজারের বিষয়ে সহায়তার জন্য Internet Explorer-এর SiteList নীতি ব্যবহার করুন।</translation> <translation id="3957134519352019843">ডিফল্ট সার্চ প্রদানকারীর ব্যবহার চালু করতে দেয়। আপনি এই সেটিং চালু করলে, ব্যবহারকারীরা ওমনিবক্সে ইউআরএল ছাড়া অন্য কোনও টেক্সট লিখলে ডিফল্টভাবে সার্চ হবে। @@ -1859,7 +1859,7 @@ <translation id="5208240613060747912">বিজ্ঞপ্তিগুলি প্রদর্শনের জন্য অনুমোদিত এমন সাইটগুলি নির্দিষ্ট করে এমন url ধরণগুলির একটি তালিকা আপনাকে সেট করার অনুমতি দেয়৷ যদি এই নীতিটি বামে সেট না করে ছেড়ে যাওয়া হয়, তাহলে গ্লোবাল ডিফল্ট মান সব সাইটগুলির জন্য ব্যবহার করা হবে যদি 'ডিফল্ট বিজ্ঞপ্তি সেটিং' নীতি সেট করা হয় তা থেকে, নয়তো ব্যবহারকারীদের ব্যক্তিগত কনফিগারেশান থেকে৷</translation> -<translation id="5213038356678567351">এমন ওয়েবসাইট যেটি কখনও ব্রাউজার সুইচ ট্রিগার করে না।</translation> +<translation id="5213038356678567351">এমন ওয়েবসাইট যেগুলি কখনও অন্য ব্রাউজারে খোলার অনুরোধ করে না।</translation> <translation id="5219844027738217407">Android অ্যাপ্লিকেশানগুলির জন্য, এই নীতিটি কেবলমাত্র মাইক্রোফোনকে প্রভাবিত করে। এই নীতিটি সত্যতে সেট করা থাকলে, কোনো ব্যতিক্রম ছাড়াই সব Android অ্যাপ্লিকেশানগুলির জন্য মাইক্রোফোন মিউট করা থাকে।</translation> <translation id="5228316810085661003">ডিভাইস-স্থানীয় অ্যাকাউন্টে নিজে থেকে লগ-ইনে বিলম্ব। @@ -1944,7 +1944,7 @@ অন্যথায় এগুলির মধ্যে যেকোনও একটি মানে এটিকে সেট করা যেতে পারে: "tls1.2" বা "tls1.3"। সেট করা থাকলে, <ph name="PRODUCT_NAME" /> উল্লিখিত ভার্সনের পরের কোনও SSL/TLS ভার্সন ব্যবহার করবে না। অপরিচিত মানকে উপেক্ষা করা হবে।</translation> <translation id="5330684698007383292">নিম্নোক্ত সামগ্রী প্রকার পরিচালনা করতে <ph name="PRODUCT_FRAME_NAME" /> কে মঞ্জুরি দিন৷</translation> -<translation id="5365476955714838841">বিকল্প ব্রাউজারের জন্য কম্যান্ড-লাইন প্যারামিটার।</translation> +<translation id="5365476955714838841">বিকল্প ব্রাউজারের জন্য কমান্ড-লাইন প্যারামিটার।</translation> <translation id="5365946944967967336">টুলবারে হোম বোতাম দেখুন</translation> <translation id="5366745336748853475">কোনও সাইটে যদি সার্টিফিকেট প্রয়োজন হয় তাহলে এই নীতির মাধ্যমে আপনি URL প্যাটার্নের একটি তালিকা নির্দিষ্ট করতে পারেন যেখানে এমন সাইট উল্লেখ করা থাকবে যেগুলির ক্ষেত্রে SAML ফ্লো হোস্ট করা ফ্রেমের সাইন-ইন স্ক্রিনে ক্লায়েন্ট সার্টিফিকেট নিজে থেকেই বেছে নেওয়া হয়। ডিভাইসের সমস্ত কাজে প্রযোজ্য যে সার্টিফিকেট SAML IdP তে জমা দিতে হয়, সেটি কনফিগার করার ক্ষেত্রে এটি ব্যবহার করা হয়। @@ -2099,13 +2099,13 @@ প্রতিটি উল্লিখিত উৎস নিজস্ব প্রসেসের মধ্যে কাজ করবে। এর ফলে সাবডোমেন দিয়ে উল্লেখ করা উৎসগুলিও আইসোলেট হবে; যেমন https://example.com/ উল্লেখ করা হলে https://example.com/ - সাইটের অংশ হিসেবে https://foo.example.com/ ও আইসোলেট হবে। - নীতিটি বন্ধ করা হলে কোনও অনুপযুক্ত সাইট আইসোলেট হবে না এবং IsolateOrigins ও SitePerProcess-এর ফিল্ড ট্রায়াল বন্ধ করা হবে। ব্যবহারকারী তাও কম্যান্ড লাইন ফ্ল্যাগের দ্বারা ম্যানুয়ালি IsolateOrigins চালু করতে পারবেন। + সাইটের অংশ হিসেবে https://foo.example.com/-ও আইসোলেট হবে। + নীতিটি বন্ধ করা হলে কোনও অনুপযুক্ত সাইট আইসোলেট হবে না এবং IsolateOriginsAndroid ও SitePerProcessAndroid-এর ফিল্ড ট্রায়াল বন্ধ করা হবে। ব্যবহারকারী তাও কমান্ড লাইন ফ্ল্যাগের দ্বারা ম্যানুয়ালি IsolateOrigins চালু করতে পারবেন। নীতি যদি কনফিগার না করা হয় তাহলে ব্যবহারকারী এই সেটিং পরিবর্তন করতে পারবেন। - দ্রষ্টব্য: Android-এ, সাইটের লোকেশন পরীক্ষামূলক। সময়ের সাথে সাথে সহায়তা বৃদ্ধি পাবে তবে বর্তমানে এটি পারফর্ম্যান্স সংক্রান্ত সমস্যার সৃষ্টি করতে পারে। + দ্রষ্টব্য: Android-এ, সাইটের আইসোলেশন পরীক্ষামূলক। সময়ের সাথে সাথে আরও ভালোভাবে কাজ করবে, তবে বর্তমানে এটি পারফর্ম্যান্স সংক্রান্ত সমস্যার সৃষ্টি করতে পারে। - দ্রষ্টব্য: এই নীতি শুধুমাত্র ডিভাইসে চলা অ্যান্ড্রয়েড ক্রোমের ক্ষেত্রে প্রযোজ্য যাতে 1GB-এর বেশি র্যাম আছে। অ্যান্ড্রয়েড নয় এমন প্ল্যাটফর্মে নীতি প্রয়োগ করতে, IsolateOrigins ব্যবহার করুন। + দ্রষ্টব্য: শুধু ১ জিবির বেশি র্যাম আছে এমন Android ডিভাইসে থাকা Chrome-এ এই নীতি প্রযোজ্য। Android নয় এমন প্ল্যাটফর্মে নীতি প্রয়োগ করতে IsolateOrigins ব্যবহার করুন। </translation> <translation id="5610104657949692379">যখন এই নীতি সেট করা থাকে, তখন ব্যবহারকারী যদি নিষ্ক্রিয়তা বিলম্বের জন্য প্রদত্ত সময়সীমা পর্যন্ত নিষ্ক্রিয় থাকে তাহলে <ph name="PRODUCT_OS_NAME" /> কি ব্যবস্থা নেবে তা নির্দিষ্ট করে, যা পৃথকভাবেও কনফিগার করা যেতে পারে। @@ -2145,11 +2145,11 @@ <translation id="5728154254076636808"><ph name="PRODUCT_NAME" /> প্রোফাইল ডেটার জন্য রোমিং কপি তৈরি করা সক্ষম করে</translation> <translation id="5728661376331491504">একটি বিকল্প ব্রাউজারে খোলার জন্য এই নীতি ওয়েবসাইটের তালিকা নিয়ন্ত্রণ করে। - মনে রাখবেন যে <ph name="USE_IE_SITELIST_POLICY_NAME" /> নীতির দ্বারা এই তালিকায় উপাদানগুলি যোগ করাও যেতে পারে। + এছাড়াও মনে রাখবেন যে <ph name="USE_IE_SITELIST_POLICY_NAME" /> নীতির দ্বারা এই তালিকায় উপাদানগুলি যোগ করা যেতে পারে। এই নীতিটিকে সেট না করা অবস্থায় রেখে দিলে, তালিকায় কোনও ওয়েবসাইট যোগ হয় না। - এই নীতি সেট করা থাকলে প্রতিবার বিকল্প ব্রাউজারে কিছু খোলার নিয়ম হিসেবে গণ্য করা হয়। ইউআরএল বিকল্প ব্রাউজারে খোলা উচিত কিনা তা বেছে নেওয়ার সময় <ph name="PRODUCT_NAME" /> নিয়মগুলি ব্যবহার করে। + এই নীতি সেট করা থাকলে প্রতিটি আইটেমকে, প্রতিবার বিকল্প ব্রাউজারে কিছু খোলার নিয়ম হিসেবে গণ্য করা হয়। ইউআরএল বিকল্প ব্রাউজারে খোলা উচিত কিনা তা বেছে নেওয়ার সময় <ph name="PRODUCT_NAME" /> নিয়মগুলি ব্যবহার করে। Internet Explorer অ্যাড-ইন চালু অবস্থায় থাকলে, নিয়ম না মিললে Internet Explorer <ph name="PRODUCT_NAME" />-এ ফিরে যায়। @@ -2228,8 +2228,8 @@ <translation id="5898486742390981550">যখন একাধিক ব্যবহারকারী লগ ইন করে থাকেন, তখন শুধুমাত্র প্রাথমিক ব্যবহারকারী Android অ্যাপ্লিকেশানগুলি ব্যবহার করতে পারেন।</translation> <translation id="5900196529149231477"> এই নীতি সাইন-ইন স্ক্রিনের ক্ষেত্রে প্রযোজ্য। <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> নীতি দেখুন যা ব্যবহারকারীর সেশনের ক্ষেত্রে প্রযোজ্য। উভয় নীতির জন্য সমান মান সেট করার সাজেশন দেওয়া হয়। যদি মানগুলি না মেলে তাহলে ব্যবহারকারীর সেশনে প্রবেশ করার সময় ব্যবহারকারী নীতি দ্বারা নির্দিষ্ট মানটি প্রয়োগ করার কারণে দেরী হতে পারে। - নীতিটি চালু করা হলে কমা দিয়ে আলাদা তালিকার প্রতিটি উল্লিখিত উৎস নিজস্ব প্রসেসের মধ্যে কাজ করবে। এর ফলে সাবডোমেন দিয়ে উল্লেখ করা উৎসগুলিও আইসোলেট করা হবে; যেমন, https://example.com/ উল্লেখ করা হলে https://example.com/ সাইটের অংশ হিসেবে https://foo.example.com/ ও আইসোলেট করা হবে। - নীতিটি বন্ধ করা হলে কোনও অনুপযুক্ত সাইট আইসোলেশন হবে না এবং IsolateOrigins ও SitePerProcess-এর ফিল্ড ট্রায়াল বন্ধ করা হবে। ব্যবহারকারী তাও কম্যান্ড লাইন ফ্ল্যাগের দ্বারা ম্যানুয়ালি IsolateOrigins চালু করতে পারবেন। + নীতিটি চালু করা হলে, কমা দিয়ে আলাদা করা তালিকার প্রতিটি উল্লিখিত উৎস নিজস্ব প্রসেসের মধ্যে কাজ করবে। এর ফলে সাবডোমেন দিয়ে উল্লেখ করা উৎসগুলিও আইসোলেট করা হবে; যেমন, https://example.com/ উল্লেখ করা হলে https://example.com/ সাইটের অংশ হিসেবে https://foo.example.com/-ও আইসোলেট করা হবে। + নীতিটি বন্ধ করা হলে, IsolateOrigins ও SitePerProcess ফিচার বন্ধ থাকবে। ব্যবহারকারী তাও কমান্ড লাইন ফ্ল্যাগের দ্বারা ম্যানুয়ালি IsolateOrigins চালু করতে পারবেন। নীতি যদি কনফিগার না করা হয় তাহলে সাইন-ইন স্ক্রিনের জন্য প্ল্যাটফর্ম ডিফল্ট আসিসোলেশন সেটিংস ব্যবহার করা হবে। </translation> <translation id="5901427587865226597">শুধুমাত্র ডুপ্লেক্স প্রিন্টিং</translation> @@ -2529,11 +2529,6 @@ <translation id="6689792153960219308">হার্ডওয়্যার স্থিতি প্রতিবেদন করে</translation> <translation id="6698632841807204978">একরঙা প্রিন্টিং চালু করুন</translation> <translation id="6699880231565102694">দূরবর্তী অ্যাক্সেস হোস্টের জন্য দুইবার-প্রয়োজনীয় প্রমাণীকরণ সক্ষম করুন</translation> -<translation id="6724842112053619797">যদি আপনি এই সেটিংটি সক্ষম করেন তাহলে <ph name="PRODUCT_NAME" /> প্রোফাইলে সংরক্ষিত সেটিংস যেমন বুকমার্ক, স্বয়ংসম্পূর্ণ ডেটা, পাসওয়ার্ড ইত্যাদিও রোমিং ইউজার প্রোফাইল ফোল্ডারে বা <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> পলিসির মাধ্যমে প্রশাসকের নির্দিষ্ট করা জায়গায় একটি ফাইলে সংরক্ষিত হবে। এই পলিসি সক্ষম করলে ক্লাউড সিঙ্ক অক্ষম হয়ে যায়। - - যদি এই পলিসিটি অক্ষম করা থাকে বা সেট না করে ছেড়ে দেওয়া হয় তাহলে শুধুমাত্র নিয়মিত স্থানীয় প্রোফাইল ব্যবহার করা হবে। - - <ph name="SYNC_DISABLED_POLICY_NAME" /> পলিসিটি RoamingProfileSupportEnabled ওভাররাইড করার মাধ্যমে সব ডেটা সিঙ্ক্রোনাইজেশনকে অক্ষম করে।</translation> <translation id="6731757988219967594">প্রাপ্তবয়স্কদের কন্টেন্ট আছে এমন সর্বোচ্চ লেভেলের সাইটগুলি (এম্বেড করা iframes ছাড়া) ফিল্টার করুন</translation> <translation id="6734521799274931721">ChromeOS উপলভ্যতার জন্য নেটওয়ার্ক ফাইল শেয়ার নিয়ন্ত্রণ করুন</translation> <translation id="6735701345096330595">ভাষাতে বানান পরীক্ষা বাধ্যতামূলকভাবে সক্ষম করুন</translation> @@ -2782,16 +2777,16 @@ যদি এই নীতি আনসেট করা হয়, ব্যবহারকারী লঞ্চার বারে পিন করা অ্যাপ্লিকেশনের তালিকায় পরিবর্তন করতে পারেন৷</translation> <translation id="7132877481099023201">এই URLগুলিকে বিজ্ঞপ্তি ছাড়াই ভিডিও ক্যাপচার ডিভাইসগুলিতে অ্যাক্সেস দেওয়া হবে</translation> -<translation id="7158064522994309072">বিকল্প ব্রাউজারে ইউআরএল খোলার জন্য কোন কম্যান্ড ব্যবহার করা হবে তা এই নীতি নিয়ন্ত্রণ করে। +<translation id="7158064522994309072">বিকল্প ব্রাউজারে ইউআরএল খোলার জন্য কোন কমান্ড ব্যবহার করা হবে তা এই নীতি নিয়ন্ত্রণ করে। - এই নীতি সেট না করা অবস্থায় থাকলে, একটি প্ল্যাটফর্ম নির্দিষ্ট ডিফল্ট ব্যবহৃত হয়: সেট করা না থাকলে Windows-এর জন্য Internet Explorer, বা Mac OS X-এর জন্য Safari বা Linux-এ বিকল্প ব্রাউজার চালু করতে ব্যর্থ হয়। + এই নীতি সেট না করা অবস্থায় থাকলে, একটি প্ল্যাটফর্ম নির্দিষ্ট ডিফল্ট ব্যবহৃত হয়: সেট করা না থাকলে Windows-এর জন্য Internet Explorer বা Mac OS X-এর জন্য Safari বা Linux-এ বিকল্প ব্রাউজার খুলতে পারে না। - নীতি ${ie}-এর যেকোনও একটিতে সেট করা থাকলে, ${firefox}, ${safari} বা - ${opera}, ব্রাউজারটি ইনস্টল করা থাকলে ব্রাউজার চালু হবে। Windows এবং ${safari}-তে - শুধুমাত্র ${ie} পাওয়া যায় এবং Windows and Mac - OS X ${safari} পাওয়া যায়। + নীতিটি ${ie}, ${firefox}, ${safari} বা ${opera}-এর যেকোনও একটিতে সেট করা থাকলে + ও সেই নির্দিষ্ট ব্রাউজারটি ইনস্টল করা থাকলে তা চালু হবে। ${ie} শুধু Windows-এ এবং ${safari} শুধু + Windows ও Mac + OS X-এ উপলভ্য। - এই নীতি একটি ফাইলে পাথে সেট করা হলে ফাইলটি এক্সিকিউটেবল ফাইল হিসেবে + এই নীতি একটি ফাইল পাথে সেট করা হলে ফাইলটি এক্সিকিউটেবল ফাইল হিসেবে ব্যবহৃত হয়।</translation> <translation id="7167436895080860385">পাসওয়ার্ড পরিচালকে পাসওয়ার্ড দেখানোর জন্য ব্যবহারকারীদের মঞ্জুরি দেয় (থামানো রয়েছে)</translation> <translation id="7173856672248996428">অল্পক্ষণস্থায়ী প্রোফাইল</translation> @@ -3420,9 +3415,9 @@ <translation id="8390049129576938611"><ph name="PRODUCT_NAME" /> এ অভ্যন্তরীণ PDF ভিউয়ার অক্ষম করে। এর পরিবর্তে এটিকে ডাউনলোড হিসাবে বিবেচনা করে এবং ডিফল্ট অ্যাপ্লিকেশান দিয়ে PDF ফাইল খোলার জন্য ব্যবহারকারীকে অনুমতি দেয়। এই নীতিটি সেট করা না থাকলে বা অক্ষম করা থাকলে, ব্যবহারকারী যদি PDF প্লাগইনটি অক্ষম না করে থাকে, তাহলে PDF ফাইলগুলি খোলার জন্য এটি ব্যবহার করা হবে।</translation> -<translation id="8396145449084377015">Internet Explorer-এর সাইটের তালিকা নীতি থেকে নিয়ম লোড করা হবে কিনা তা এই নীতি নিয়ন্ত্রণ করে।. +<translation id="8396145449084377015">Internet Explorer-এর SiteList নীতি থেকে নিয়ম লোড করা হবে কিনা তা এই নীতি নিয়ন্ত্রণ করে। - এই নীতি সেট না করা অবস্থায় থাকলে বা ফলস হিসেবে সেট করা থাকলে, ব্রাউজার সুইচ করার উৎস হিসেবে <ph name="PRODUCT_NAME" /> Internet Explorer-এর <ph name="IEEM_SITELIST_POLICY" /> নীতি ব্যবহার করে না। + এই নীতি সেট না করা অবস্থায় থাকলে বা ফলস হিসেবে সেট করা থাকলে, একটি ব্রাউজার থেকে অন্য ব্রাউজারে যাওয়ার ক্ষেত্রে নিয়মের উৎস হিসেবে <ph name="PRODUCT_NAME" /> Internet Explorer-এর <ph name="IEEM_SITELIST_POLICY" /> নীতি ব্যবহার করে না। এই নীতি যখন ট্রু হিসেবে সেট করা থাকে তখন সাইটের তালিকার ইউআরএল পাওয়ার জন্য <ph name="PRODUCT_NAME" /> Internet Explorer-এর <ph name="IEEM_SITELIST_POLICY" /> পড়ে। তারপর <ph name="PRODUCT_NAME" /> সেই ইউআরএল থেকে সাইটের তালিকা ডাউনলোড করে এবং নিয়মগুলি <ph name="SITELIST_POLICY_NAME" /> নীতির সাথে কনফিগার করা থাকলে সেগুলি প্রয়োগ করে। @@ -3742,13 +3737,11 @@ নীতিটি চালু করা থাকলে কমা দিয়ে বিভক্ত তালিকার প্রতিটি উল্লিখিত উৎস নিজস্ব প্রসেসের মধ্যে কাজ করবে। এর ফলে সাবডোমেন দিয়ে উল্লেখ করা উৎসগুলিও আইসোলেট হবে; যেমন https://example.com/ উল্লেখ করা হলে https://example.com/ - সাইটের অংশ হিসেবে https://foo.example.com/ ও আইসোলেট হবে। এর ফলে - সাবডোমেন দিয়ে উল্লেখ করা উৎসগুলিও আইসোলেট করা হবে; যেমন, - https://example.com/ উল্লেখ করা হলে https://example.com/ সাইটের অংশ হিসেবে - https://foo.example.com/ ও আইসোলেট করা হবে। + সাইটের অংশ হিসেবে https://foo.example.com/-ও আইসোলেট হবে। নীতিটি যদি বন্ধ করা থাকে তাহলে IsolateOrigins ও SitePerProcess ফিচার বন্ধ - হবে। ব্যবহারকারী কম্যান্ড লাইন ফ্ল্যাগের মাধ্যমে তাও ম্যানুয়ালভাবে IsolateOrigins চালু করতে পারবেন। - নীতি কনফিগার করা না থাকলে, ব্যবহারকারী <ph name="PRODUCT_OS_NAME" />-এ এই সেটিং পরিবর্তন করতে পারবেন, <ph name="DEVICE_LOGIN_SCREEN_ISOLATE_ORIGINS_POLICY_NAME" /> ডিভাইস নীতির জন্য সমান মান সেট করার সাজেশন দেওয়া হয়। যদি মানগুলি না মেলে তাহলে ব্যবহারকারীর সেশনে প্রবেশ করার সময় ব্যবহারকারী নীতি দ্বারা নির্দিষ্ট মানটি প্রয়োগ করার কারণে দেরী হতে পারে। + হবে। তবে ব্যবহারকারীরা কমান্ড লাইন ফ্ল্যাগের মাধ্যমে ম্যানুয়ালভাবে IsolateOrigins চালু করতে পারবেন। + নীতি কনফিগার করা না থাকলে, ব্যবহারকারী এই সেটিং পরিবর্তন করতে পারবেন। + <ph name="PRODUCT_OS_NAME" />-এ, <ph name="DEVICE_LOGIN_SCREEN_ISOLATE_ORIGINS_POLICY_NAME" /> ডিভাইস নীতি একই মানে সেট করার সাজেশন দেওয়া হয়। যদি উভয় নীতির দ্বারা নির্দিষ্ট করা মানগুলি না মেলে তাহলে ব্যবহারকারীর সেশনে প্রবেশ করার সময় ব্যবহারকারী নীতি দ্বারা নির্দিষ্ট মানটি প্রয়োগ করার কারণে দেরী হতে পারে। দ্রষ্টব্য: এই নীতি Android-এর ক্ষেত্রে প্রযোজ্য নয়। Android-এ IsolateOrigins চালু করতে IsolateOriginsAndroid নীতি সেটিংস ব্যবহার করুন। </translation>
diff --git a/components/policy/resources/policy_templates_ca.xtb b/components/policy/resources/policy_templates_ca.xtb index 147c2c5..9099d16 100644 --- a/components/policy/resources/policy_templates_ca.xtb +++ b/components/policy/resources/policy_templates_ca.xtb
@@ -2088,11 +2088,6 @@ <translation id="6689792153960219308">Informa de l'estat del maquinari</translation> <translation id="6698632841807204978">Permet la impressió monocroma</translation> <translation id="6699880231565102694">Activació de l'autenticació de dos factors per als amfitrions d'accés remot</translation> -<translation id="6724842112053619797">Si actives aquesta opció de configuració, les opcions de configuració emmagatzemades als perfils que hi ha a <ph name="PRODUCT_NAME" />, com ara les adreces d'interès, les dades d'Emplenament automàtic o les contrasenyes, entre d'altres, també s'introduiran en un fitxer emmagatzemat a la carpeta Itinerància del perfil de l'usuari o a la ubicació especificada per l'administrador a la política <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. En activar aquesta política, es desactiva la sincronització en núvol. - - Si aquesta política es desactiva o no es defineix, només s'utilitzaran els perfils locals habituals. - - La política <ph name="SYNC_DISABLED_POLICY_NAME" /> desactiva la sincronització de totes les dades i substitueix RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtra els llocs web de nivell superior amb contingut per a adults (però no els iframes inserits)</translation> <translation id="6734521799274931721">Controla si la funció Fitxers compartits de la xarxa estarà disponible per a Chrome OS</translation> <translation id="6735701345096330595">Força l'activació del corrector ortogràfic d'idiomes</translation>
diff --git a/components/policy/resources/policy_templates_cs.xtb b/components/policy/resources/policy_templates_cs.xtb index 61d250a..f4e6127 100644 --- a/components/policy/resources/policy_templates_cs.xtb +++ b/components/policy/resources/policy_templates_cs.xtb
@@ -2141,11 +2141,6 @@ <translation id="6689792153960219308">Nahlásit stav hardwaru</translation> <translation id="6698632841807204978">Povolit monochromatický tisk</translation> <translation id="6699880231565102694">Povolit dvoufázové ověření pro hostitele vzdáleného přístupu</translation> -<translation id="6724842112053619797">Pokud zapnete toto nastavení, budou nastavení uložená v profilech <ph name="PRODUCT_NAME" /> (např. záložky, data automatického vyplňování nebo hesla) zapsána také do souboru uloženého ve složce cestovního uživatelského profilu nebo v umístění, které definuje administrátor prostřednictvím zásady <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Aktivací této zásady deaktivujete cloudovou synchronizaci. - - Pokud je tato zásada zakázána nebo není nastavena, budou se používat pouze běžné místní profily. - - Zásada <ph name="SYNC_DISABLED_POLICY_NAME" /> zakáže veškerou synchronizaci dat a tím zásadu RoamingProfileSupportEnabled přepíše.</translation> <translation id="6731757988219967594">Filtrovat weby nejvyšší úrovně (ale nikoliv vložené prvky iframe) s obsahem pouze pro dospělé</translation> <translation id="6734521799274931721">Ovládá dostupnost sdílených síťových složek pro Chrome OS</translation> <translation id="6735701345096330595">Vynutit povolení jazyků kontroly pravopisu</translation>
diff --git a/components/policy/resources/policy_templates_da.xtb b/components/policy/resources/policy_templates_da.xtb index 187cdd4..ffea4f8 100644 --- a/components/policy/resources/policy_templates_da.xtb +++ b/components/policy/resources/policy_templates_da.xtb
@@ -2103,11 +2103,6 @@ <translation id="6689792153960219308">Rapportér hardwarestatus</translation> <translation id="6698632841807204978">Aktivér udskrivning i sort/hvid</translation> <translation id="6699880231565102694">Aktivér godkendelse med to faktorer for værter med fjernadgang</translation> -<translation id="6724842112053619797">Hvis du aktiverer denne indstilling, skrives indstillingerne, der er gemt i <ph name="PRODUCT_NAME" />-profiler, f.eks. bogmærker, autofylddata og adgangskoder, også i en fil, der er gemt i roamingmappen for brugerprofilen eller et andet sted som angivet af administratoren via <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />-politikken. Når du aktiverer denne politik, deaktiveres synkronisering i skyen. - - Hvis denne politik deaktiveres eller ikke angives, er det kun de almindelige lokale profiler, der bruges. - - Politikken <ph name="SYNC_DISABLED_POLICY_NAME" /> deaktiverer al datasynkronisering og tilsidesætter RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtrér voksenindhold fra på websites på øverste niveau (men ikke integrerede iframes)</translation> <translation id="6734521799274931721">Styrer tilgængelighed af fildeling via netværk for Chrome OS</translation> <translation id="6735701345096330595">Gennemtving aktivering af stavekontrol af sprog</translation>
diff --git a/components/policy/resources/policy_templates_de.xtb b/components/policy/resources/policy_templates_de.xtb index 3690302..2ee611c 100644 --- a/components/policy/resources/policy_templates_de.xtb +++ b/components/policy/resources/policy_templates_de.xtb
@@ -2104,11 +2104,6 @@ <translation id="6689792153960219308">Hardwarestatus senden</translation> <translation id="6698632841807204978">Schwarz-Weiß-Druck aktivieren</translation> <translation id="6699880231565102694">Zwei-Faktor-Authentifizierung für Remotezugriff-Hosts aktivieren</translation> -<translation id="6724842112053619797">Wenn Sie diese Einstellung aktivieren, werden die in <ph name="PRODUCT_NAME" />-Profilen gespeicherten Einstellungen, etwa Lesezeichen, AutoFill-Daten und Passwörter, zusätzlich in eine Datei geschrieben, die sich im Roaming-Nutzerprofilordner oder an einem vom Administrator über die Richtlinie <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> festgelegten Ort befindet. Durch die Aktivierung dieser Richtlinie wird die Cloudsynchronisierung deaktiviert. - - Wenn diese Richtlinie deaktiviert oder nicht konfiguriert ist, kommen nur die regulären lokalen Profile zum Einsatz. - - Durch die Richtlinie <ph name="SYNC_DISABLED_POLICY_NAME" /> wird die gesamte Datensynchronisierung deaktiviert und somit RoamingProfileSupportEnabled überschrieben.</translation> <translation id="6731757988219967594">Websites auf oberster Ebene (aber nicht eingebettete iFrames) mit Inhalten nur für Erwachsene filtern</translation> <translation id="6734521799274931721">Steuert die Verfügbarkeit von Netzwerkfreigaben unter Chrome OS</translation> <translation id="6735701345096330595">Aktivierung von Sprachen für die Rechtschreibprüfung erzwingen</translation>
diff --git a/components/policy/resources/policy_templates_el.xtb b/components/policy/resources/policy_templates_el.xtb index a9b56318..6f5d474 100644 --- a/components/policy/resources/policy_templates_el.xtb +++ b/components/policy/resources/policy_templates_el.xtb
@@ -2181,11 +2181,6 @@ <translation id="6689792153960219308">Αναφορά κατάστασης εξοπλισμού</translation> <translation id="6698632841807204978">Ενεργοποίηση μονόχρωμης εκτύπωσης</translation> <translation id="6699880231565102694">Ενεργοποίηση ελέγχου ταυτότητας δύο παραγόντων για κεντρικούς υπολογιστές απομακρυσμένης πρόσβασης</translation> -<translation id="6724842112053619797">Εάν ενεργοποιήσετε αυτήν τη ρύθμιση, οι ρυθμίσεις που είναι αποθηκευμένες στα προφίλ του προϊόντος <ph name="PRODUCT_NAME" />, όπως σελιδοδείκτες, δεδομένα αυτόματης συμπλήρωσης, κωδικοί πρόσβασης, κ.λπ., θα εγγραφούν επίσης σε κάποιο αρχείο που είναι αποθηκευμένο στον φάκελο του Προφίλ χρήστη περιαγωγής ή σε μια τοποθεσία η οποία καθορίζεται από τον διαχειριστή μέσω της πολιτικής <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Με την ενεργοποίηση αυτής της πολιτικής, ο συγχρονισμός στο cloud απενεργοποιείται. - - Εάν αυτή η πολιτική είναι απενεργοποιημένη ή δεν οριστεί, θα χρησιμοποιούνται μόνο τυπικά τοπικά προφίλ. - - Η πολιτική <ph name="SYNC_DISABLED_POLICY_NAME" /> απενεργοποιεί όλο τον συγχρονισμό δεδομένων, αντικαθιστώντας το RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Φιλτράρισμα ιστοτόπων ανώτερου επιπέδου (αλλά όχι ενσωματωμένων iframe) για περιεχόμενο για ενηλίκους</translation> <translation id="6734521799274931721">Ελέγχει τη λειτουργία "Κοινόχρηστα αρχεία δικτύου" για τη διαθεσιμότητα του ChromeOS</translation> <translation id="6735701345096330595">Αναγκαστική ενεργοποίηση ορθογραφικού ελέγχου γλωσσών</translation>
diff --git a/components/policy/resources/policy_templates_en-GB.xtb b/components/policy/resources/policy_templates_en-GB.xtb index 8b391477..8ea64a61 100644 --- a/components/policy/resources/policy_templates_en-GB.xtb +++ b/components/policy/resources/policy_templates_en-GB.xtb
@@ -2190,11 +2190,6 @@ <translation id="6689792153960219308">Report hardware status</translation> <translation id="6698632841807204978">Enable monochrome printing</translation> <translation id="6699880231565102694">Enable two-factor authentication for remote access hosts</translation> -<translation id="6724842112053619797">If you enable this setting, the settings stored in <ph name="PRODUCT_NAME" /> profiles like bookmarks, auto-fill data, passwords, etc. will also be written to a file stored in the roaming user profile folder or a location specified by the Administrator through the <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> policy. Enabling this policy disables cloud sync. - - If this policy is disabled or left not set, only the regular local profiles will be used. - - The <ph name="SYNC_DISABLED_POLICY_NAME" /> policy disables all data synchronisation, overriding RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filter top-level sites (but not embedded iframes) for adult content</translation> <translation id="6734521799274931721">Controls Network File Shares for ChromeOS availability</translation> <translation id="6735701345096330595">Force enable spellcheck languages</translation>
diff --git a/components/policy/resources/policy_templates_es-419.xtb b/components/policy/resources/policy_templates_es-419.xtb index aab1d3e..2035b273b 100644 --- a/components/policy/resources/policy_templates_es-419.xtb +++ b/components/policy/resources/policy_templates_es-419.xtb
@@ -2106,11 +2106,6 @@ <translation id="6689792153960219308">Informar estado de hardware</translation> <translation id="6698632841807204978">Habilitar la impresión monocromática</translation> <translation id="6699880231565102694">Habilitar autenticación de dos factores para los hosts de acceso remoto.</translation> -<translation id="6724842112053619797">Si habilitas esta configuración, los datos almacenados en los perfiles de <ph name="PRODUCT_NAME" />, como los favoritos, los datos de Autocompletar, las contraseñas, etc. también se guardarán en un archivo almacenado en la carpeta de perfil del usuario Roaming o una ubicación que el administrador especifique mediante la política <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Si habilitas esta política, se inhabilita la sincronización en la nube. - - Si esta política se inhabilita o no se establece, solo se usarán los perfiles locales comunes. - - La política <ph name="SYNC_DISABLED_POLICY_NAME" /> inhabilita la sincronización de todos los datos y anula la política RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Aplicar filtros de contenido para adultos a los sitios principales (pero no a los iframes incorporados)</translation> <translation id="6734521799274931721">Controlar la disponibilidad de "Network File Shares" para el Sistema operativo Chrome</translation> <translation id="6735701345096330595">Habilitar la corrección ortográfica de idiomas</translation>
diff --git a/components/policy/resources/policy_templates_es.xtb b/components/policy/resources/policy_templates_es.xtb index 08401d4e..28bcf74 100644 --- a/components/policy/resources/policy_templates_es.xtb +++ b/components/policy/resources/policy_templates_es.xtb
@@ -2190,12 +2190,6 @@ <translation id="6689792153960219308">Informar sobre el estado del hardware</translation> <translation id="6698632841807204978">Habilitar la impresión en monocromo</translation> <translation id="6699880231565102694">Habilitar la autenticación de dos factores para hosts de acceso remoto</translation> -<translation id="6724842112053619797">Si habilitas esta opción, la configuración almacenada en los perfiles de <ph name="PRODUCT_NAME" /> (como los marcadores, los datos de Autocompletar y las contraseñas) también se escribirá en un archivo almacenado en la carpeta Itinerancia del perfil de usuario o en una ubicación especificada por el administrador en la política <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. -Al habilitar esta política, se inhabilita la sincronización en la nube. - - Si esta política se inhabilita o no se establece, solo se utilizarán los perfiles locales habituales. - - La política <ph name="SYNC_DISABLED_POLICY_NAME" /> inhabilita todas las sincronizaciones de datos y anula RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtrar contenido para adultos de sitios web de nivel superior (y no de los iframes insertados)</translation> <translation id="6734521799274931721">Controlar si el uso compartido de archivos del sistema estará disponible en Chrome OS</translation> <translation id="6735701345096330595">Forzar que se habilite el corrector ortográfico de idiomas</translation>
diff --git a/components/policy/resources/policy_templates_et.xtb b/components/policy/resources/policy_templates_et.xtb index 484215f..ac41933 100644 --- a/components/policy/resources/policy_templates_et.xtb +++ b/components/policy/resources/policy_templates_et.xtb
@@ -2188,11 +2188,6 @@ <translation id="6689792153960219308">Riistvara oleku aruanne</translation> <translation id="6698632841807204978">Mustvalge printimise lubamine</translation> <translation id="6699880231565102694">Kahetasandilise autentimise lubamine kaugjuurdepääsu hostidele</translation> -<translation id="6724842112053619797">Kui lubate selle seade, kirjutatakse teenuse <ph name="PRODUCT_NAME" /> profiilide salvestatud seaded, näiteks järjehoidjad, automaatse täitmise andmed, paroolid jms, faili, mis talletatakse rändlust kasutava profiili kausta või asukohta, mille administraator määrab reegliga <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Reegli lubamine keelab pilveteenusega sünkroonimise. - - Kui keelate selle reegli või jätate selle määramata, kasutatakse ainult tavalisi kohalikke profiile. - - Reegel <ph name="SYNC_DISABLED_POLICY_NAME" /> keelab kogu andmete sünkroonimise, alistades reegli RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtreeri täiskasvanutele mõeldud sisuga ülataseme saidid (kuid mitte manustatud iframe'id)</translation> <translation id="6734521799274931721">Juhib Network File Shares for ChromeOS saadavalolekut</translation> <translation id="6735701345096330595">Õigekirjakontrolli keelte sundlubamine</translation>
diff --git a/components/policy/resources/policy_templates_fa.xtb b/components/policy/resources/policy_templates_fa.xtb index 62d18401..8554b6b 100644 --- a/components/policy/resources/policy_templates_fa.xtb +++ b/components/policy/resources/policy_templates_fa.xtb
@@ -2100,10 +2100,6 @@ <translation id="6689792153960219308">گزارش وضعیت سختافزار</translation> <translation id="6698632841807204978">فعال کردن چاپ تکرنگ</translation> <translation id="6699880231565102694">فعال کردن احراز هویت با دو فاکتور برای میزبانهای دسترسی ازراهدور</translation> -<translation id="6724842112053619797">اگر این تنظیم را فعال کنید، تنظیمات ذخیرهشده در نمایههای <ph name="PRODUCT_NAME" /> (ازجمله نشانکها، دادههای تکمیل خودکار، گذرواژهها و غیره) روی فایل ذخیرهشدهای در پوشه نمایه کاربر «رومینگ» یا مکانی که توسط «سرپرست سیستم» ازطریق خطمشی <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> مشخص شده است نیز نوشته خواهد شد. فعال کردن این خطمشی همگامسازی ابری را غیرفعال میکند. - - اگر این خطمشی غیرفعال شود یا تنظیمنشده باقی بماند، فقط از نمایههای محلی معمولی استفاده خواهد شد. - خطمشی <ph name="SYNC_DISABLED_POLICY_NAME" /> با لغو کردن RoamingProfileSupportEnabled، همه همگامسازی دادهها را غیرفعال میکند.</translation> <translation id="6731757988219967594">فیلتر کردن سایتهای سطح بالا (اما نه iframe جاسازیشده) که محتوای بزرگسالان دارند</translation> <translation id="6734521799274931721">دردسترس بودن «دستگاه ذخیرهسازی متصل به شبکه» برای سیستمعامل Chrome را کنترل میکند</translation> <translation id="6735701345096330595">فعال کردن اجباری غلطگیر املای زبانها</translation>
diff --git a/components/policy/resources/policy_templates_fi.xtb b/components/policy/resources/policy_templates_fi.xtb index ebf3636..df34226 100644 --- a/components/policy/resources/policy_templates_fi.xtb +++ b/components/policy/resources/policy_templates_fi.xtb
@@ -2113,11 +2113,6 @@ <translation id="6689792153960219308">Laitteiston tilan raportointi</translation> <translation id="6698632841807204978">Mustavalkotulostuksen käyttöönotto</translation> <translation id="6699880231565102694">Ota kahden tekijän todennus käyttöön etäisännille</translation> -<translation id="6724842112053619797">Jos tämä asetus on käytössä, <ph name="PRODUCT_NAME" /> ‑profiileihin tallennetut tiedot, esim. kirjanmerkit, automaattisen täytön tiedot ja salasanat, tallennetaan myös roaming-käyttäjän profiilitiedostoon tai järjestelmänvalvojan <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />-käytännössä määrittämään sijaintiin. Pilvisynkronointi poistetaan käytöstä, kun tämä käytäntö on käytössä. - - Jos tämä käytäntö ei ole käytössä tai sitä ei ole määritetty, vain paikallisia profiileja käytetään. - - <ph name="SYNC_DISABLED_POLICY_NAME" /> poistaa kaiken tietojen synkronoinnin käytöstä ja ohittaa RoamingProfileSupportEnabled-käytännön .</translation> <translation id="6731757988219967594">Suodata vain aikuisille suunnattua sisältöä (mutta ei upotettua sisältöä) ylimmän tason sivustoilta</translation> <translation id="6734521799274931721">Määrittää, onko Verkkotiedostojen jakaminen käytettävissä Chrome-käyttöjärjestelmässä</translation> <translation id="6735701345096330595">Pakota oikeinkirjoituksen tarkistuskielten käyttöönotto</translation>
diff --git a/components/policy/resources/policy_templates_fil.xtb b/components/policy/resources/policy_templates_fil.xtb index 573dd73..860fa35 100644 --- a/components/policy/resources/policy_templates_fil.xtb +++ b/components/policy/resources/policy_templates_fil.xtb
@@ -2185,11 +2185,6 @@ <translation id="6689792153960219308">Iulat ang status ng hardware</translation> <translation id="6698632841807204978">I-enable ang monochrome na pag-print</translation> <translation id="6699880231565102694">Paganahin ang pagpapatotoong may dalawang salik para sa mga host ng malayuang pag-access</translation> -<translation id="6724842112053619797">Kung ie-enable mo ang setting na ito, ang mga setting na naka-store sa mga profile sa <ph name="PRODUCT_NAME" /> tulad ng mga bookmark, data ng autofill, mga password, atbp. ay ira-write din sa isang file na naka-store sa folder ng profile ng user ng Roaming o sa isang lokasyong tinukoy ng Administrator sa pamamagitan ng patakarang <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Madi-disable ang pag-sync sa cloud kapag na-enable ang patakarang ito. - - Kung idi-disable ang patakarang ito o kaya ay hahayaang hindi nakatakda, ang mga regular na lokal na profile lang ang gagamitin. - - Dini-disable ng patakarang <ph name="SYNC_DISABLED_POLICY_NAME" /> ang lahat ng pag-synchronize ng data, na nag-o-override sa RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Mag-filter ng mga nangungunang site (ngunit hindi mga naka-embed na iframe) para sa pang-adult na content</translation> <translation id="6734521799274931721">Kumokontrol sa Mga File Share sa Network para sa availability ng ChromeOS</translation> <translation id="6735701345096330595">Puwersahang ine-enable ang mga wika ng spellcheck</translation>
diff --git a/components/policy/resources/policy_templates_fr.xtb b/components/policy/resources/policy_templates_fr.xtb index 388e64e..ceb19a3e2 100644 --- a/components/policy/resources/policy_templates_fr.xtb +++ b/components/policy/resources/policy_templates_fr.xtb
@@ -2203,11 +2203,6 @@ <translation id="6689792153960219308">Envoyer des rapports sur l'état du matériel</translation> <translation id="6698632841807204978">Activer l'impression monochrome</translation> <translation id="6699880231565102694">Activer l'authentification forte pour les hôtes d'accès à distance</translation> -<translation id="6724842112053619797">Si vous activez cette option, les paramètres stockés dans les profils <ph name="PRODUCT_NAME" />, comme les favoris, les données de saisie automatique et les mots de passe, sont également enregistrés dans un fichier stocké dans le dossier des profils utilisateur itinérants ou à un emplacement défini par l'administrateur tel que spécifié dans la règle <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. L'activation de cette règle entraîne la désactivation de la synchronisation cloud. - - Si cette règle est désactivée ou si elle n'est pas configurée, seuls les profils locaux standards sont utilisés. - - La règle <ph name="SYNC_DISABLED_POLICY_NAME" /> entraîne la désactivation de la synchronisation des données, remplaçant ainsi RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtrer les sites de premier niveau (mais pas les iFrame intégrés) présentant des contenus réservés aux adultes</translation> <translation id="6734521799274931721">Vérifie la disponibilité de la fonctionnalité Partages de fichiers en réseau pour Chrome OS</translation> <translation id="6735701345096330595">Forcer l'activation des langues de la vérification orthographique</translation>
diff --git a/components/policy/resources/policy_templates_gu.xtb b/components/policy/resources/policy_templates_gu.xtb index e5d3a6a9..d5282d2 100644 --- a/components/policy/resources/policy_templates_gu.xtb +++ b/components/policy/resources/policy_templates_gu.xtb
@@ -2522,11 +2522,6 @@ <translation id="6689792153960219308">હાર્ડવેરની સ્થિતિ અંગે જાણ કરવી</translation> <translation id="6698632841807204978">મોનોક્રોમ પ્રિન્ટિંગ ચાલુ કરો</translation> <translation id="6699880231565102694">રીમોટ ઍક્સેસ હોસ્ટ માટે બે-પરિબળ પ્રમાણીકરણ ચાલુ કરો</translation> -<translation id="6724842112053619797">જો તમે આ સેટિંગને ચાલુ કરો છો, તો <ph name="PRODUCT_NAME" /> પ્રોફાઇલમાં સંગ્રહિત કરેલું સેટિંગ જેમ કે બુકમાર્ક, ઑટોમૅટિક રીતે ભરાવા માટેનો ડેટા, પાસવર્ડ વગેરેને રોમિંગ વપરાશકર્તા પ્રોફાઇલ ફોલ્ડર અથવા <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> નીતિ મારફતે વ્યવસ્થાપક દ્વારા ઉલ્લેખિત સ્થાનમાં સંગ્રહિત ફાઇલમાં પણ લખવામાં આવશે. આ નીતિને ચાલુ કરવાથી ક્લાઉડ સિંક બંધ થઈ જાય છે. - - જો આ નીતિ બંધ કરી હોય અથવા સેટ કર્યા વિના છોડી દીધી હોય તો જ નિયમિત સ્થાનિક પ્રોફાઇલનો ઉપયોગ કરવામાં આવશે. - - <ph name="SYNC_DISABLED_POLICY_NAME" /> નીતિ RoamingProfileSupportEnabledને ઓવરરાઇડ કરીને, બધા ડેટાને સિંક કરવાનું બંધ કરે છે.</translation> <translation id="6731757988219967594">પુખ્ત લોકો માટેના કન્ટેન્ટ માટે ઉચ્ચ લેવલની સાઇટને ફિલ્ટર કરો (પણ એમ્બેડેડ iframes નહીં)</translation> <translation id="6734521799274931721">ChromeOSની ઉપલબ્ધતા માટે 'નેટવર્ક ફાઇલ શેર'નું નિયંત્રણ કરે છે</translation> <translation id="6735701345096330595">જોડણીની તપાસ માટે ભાષાઓને ચાલુ ફરજિયાતપણે ચાલુ કરો</translation>
diff --git a/components/policy/resources/policy_templates_hi.xtb b/components/policy/resources/policy_templates_hi.xtb index 77e07e8..417599d 100644 --- a/components/policy/resources/policy_templates_hi.xtb +++ b/components/policy/resources/policy_templates_hi.xtb
@@ -2196,11 +2196,6 @@ <translation id="6689792153960219308">हार्डवेयर स्थिति की रिपोर्ट करना</translation> <translation id="6698632841807204978">मोनोक्रोम प्रिंटिंग चालू करें</translation> <translation id="6699880231565102694">दूरस्थ पहुंच होस्ट के लिए द्वि-कारक प्रमाणीकरण सक्षम करें</translation> -<translation id="6724842112053619797">अगर आप इस सेटिंग को चालू करते हैं तो, <ph name="PRODUCT_NAME" /> प्रोफ़ाइल में बुकमार्क, अपने आप भरने वाला डेटा और पासवर्ड जैसे इकट्ठा किए गए सेटिंग भी, रोमिंग उपयोगकर्ता प्रोफ़ाइल फ़ोल्डर में जमा किसी फ़ाइल में या <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> नीति के ज़रिए एडमिन की ओर से तय किसी जगह में लिख दी जाएंगी. अगर यह नीति चालू की जाती है तो क्लाउड सिंक बंद हो जाता है. - - अगर यह नीति बंद है या सेट किए बिना छोड़ दी गई है तो, सिर्फ़ नियमित स्थानीय प्रोफ़ाइल का उपयोग किया जाएगा. - - <ph name="SYNC_DISABLED_POLICY_NAME" /> नीति RoamingProfileSupportEnabled को रद्द करके सभी डेटा सिंक्र प्रक्रिया को बंद करती है.</translation> <translation id="6731757988219967594">वयस्क सामग्री के लिए टॉप लेवल की साइटें फ़िल्टर करें (लेकिन एम्बेड किए गए iframe नहीं)</translation> <translation id="6734521799274931721">ChromeOS की उपलब्धता के लिए, नेटवर्क फ़ाइल शेयर करने की सुविधा को नियंत्रित करती है</translation> <translation id="6735701345096330595">वर्तनी जांच की भाषाएं बलपूर्वक चालू करें</translation>
diff --git a/components/policy/resources/policy_templates_hr.xtb b/components/policy/resources/policy_templates_hr.xtb index db3696f..107c8b2 100644 --- a/components/policy/resources/policy_templates_hr.xtb +++ b/components/policy/resources/policy_templates_hr.xtb
@@ -2102,11 +2102,6 @@ <translation id="6689792153960219308">Izvješćivanje o statusu hardvera</translation> <translation id="6698632841807204978">Omogući jednobojni ispis</translation> <translation id="6699880231565102694">Omogući autentifikaciju s dva čimbenika za hostove daljinskog pristupa</translation> -<translation id="6724842112053619797">Ako omogućite tu postavku, postavke pohranjene u <ph name="PRODUCT_NAME" /> profilima kao što su oznake, podaci za automatsko popunjavanje, zaporke itd. također će se bilježiti u datoteku pohranjenu u mapu korisničkog profila na Roamingu ili na lokaciju koju je odredio administrator pomoću pravila <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Omogućivanjem tog pravila onemogućuje se sinkronizacija u oblaku. - - Ako se to pravilo onemogući ili ne postavi, upotrebljavat će se samo uobičajeni lokalni profili. - - Pravilo <ph name="SYNC_DISABLED_POLICY_NAME" /> onemogućuje svu sinkronizaciju podataka nadjačavajući RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtriraj vršne web-lokacije (ali ne ugrađene iframeove) na temelju sadržaja za odrasle</translation> <translation id="6734521799274931721">Određuje dostupnost mrežnog dijeljenja datoteka za OS Chrome</translation> <translation id="6735701345096330595">Nametni omogućivanje provjere pravopisa za jezike</translation>
diff --git a/components/policy/resources/policy_templates_hu.xtb b/components/policy/resources/policy_templates_hu.xtb index f4e57c4..63f6afe 100644 --- a/components/policy/resources/policy_templates_hu.xtb +++ b/components/policy/resources/policy_templates_hu.xtb
@@ -2110,11 +2110,6 @@ <translation id="6689792153960219308">Hardverállapot jelentése</translation> <translation id="6698632841807204978">Monokróm nyomtatás engedélyezése</translation> <translation id="6699880231565102694">A kétlépcsős azonosítás engedélyezése távoli hozzáférésű gazdagépekhez</translation> -<translation id="6724842112053619797">Ha engedélyezi ezt a beállítást, a rendszer a(z) <ph name="PRODUCT_NAME" />-profilokban tárolt beállításokat (például könyvjelzők, automatikus kitöltési adatok, jelszavak stb.) a Barangoló felhasználói profil mappájában, illetve a rendszergazda által, a(z) <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> házirendnek megfelelően megadott helyen tárolt fájlba is beírja. A házirend engedélyezésével letiltja a felhőalapú szinkronizálást. - - Ha a házirend le van tiltva, vagy ha nincs beállítva, a rendszer kizárólag a normál helyi profilokat használja. - - A(z) <ph name="SYNC_DISABLED_POLICY_NAME" /> házirend letilt minden adatszinkronizálást, felülbírálva a RoamingProfileSupportEnabled házirendet.</translation> <translation id="6731757988219967594">Legfelső szintű (de nem iframe keretekbe beágyazott) webhelyek szűrése felnőtteknek szóló tartalmak szerint</translation> <translation id="6734521799274931721">A ChromeOS rendelkezésre állására vonatkozó hálózati fájlmegosztásokat szabályozza</translation> <translation id="6735701345096330595">A helyesírás-ellenőrzéshez használt nyelvek engedélyezésének kényszerítése</translation>
diff --git a/components/policy/resources/policy_templates_id.xtb b/components/policy/resources/policy_templates_id.xtb index d6facf1..c70da929 100644 --- a/components/policy/resources/policy_templates_id.xtb +++ b/components/policy/resources/policy_templates_id.xtb
@@ -2104,11 +2104,6 @@ <translation id="6689792153960219308">Melaporkan status hardware</translation> <translation id="6698632841807204978">Aktifkan pencetakan monokrom</translation> <translation id="6699880231565102694">Mengaktifkan autentikasi dua faktor untuk hosting akses jarak jauh</translation> -<translation id="6724842112053619797">Jika Anda mengaktifkan setelan ini, setelan yang disimpan di profil <ph name="PRODUCT_NAME" /> seperti bookmark, data IsiOtomatis, sandi, dan informasi lainnya juga akan ditulis ke file yang disimpan di folder profil pengguna Roaming atau lokasi yang ditentukan oleh Administrator melalui kebijakan <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Mengaktifkan kebijakan ini akan menonaktifkan sinkronisasi cloud. - - Jika kebijakan ini dinonaktifkan atau tidak disetel, hanya profil lokal reguler yang akan digunakan. - - Kebijakan <ph name="SYNC_DISABLED_POLICY_NAME" /> menonaktifkan semua sinkronisasi data, menggantikan RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filter konten khusus dewasa dari situs level teratas (namun bukan iframe yang tersemat)</translation> <translation id="6734521799274931721">Mengontrol fitur Berbagi File Jaringan untuk ketersediaan ChromeOS</translation> <translation id="6735701345096330595">Mengaktifkan paksa pemeriksaan ejaan bahasa</translation>
diff --git a/components/policy/resources/policy_templates_it.xtb b/components/policy/resources/policy_templates_it.xtb index 31dd8bdb..b0b18d0a 100644 --- a/components/policy/resources/policy_templates_it.xtb +++ b/components/policy/resources/policy_templates_it.xtb
@@ -2060,11 +2060,6 @@ <translation id="6689792153960219308">Segnala lo stato dell'hardware</translation> <translation id="6698632841807204978">Attiva la stampa monocromatica</translation> <translation id="6699880231565102694">Abilita autenticazione a due fattori per gli host di accesso remoto</translation> -<translation id="6724842112053619797">Se attivi questa impostazione, le impostazioni memorizzate nei profili <ph name="PRODUCT_NAME" />, come i preferiti, i dati della compilazione automatica, le password e così via, saranno scritte anche in un file memorizzato nella cartella del profilo utente Roaming o in una posizione specificata dall'amministratore tramite la norma <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Se si attiva questa norma, viene disattivata la sincronizzazione nella cloud. - - Se questa norma viene disattivata o non viene impostata, saranno utilizzati solo i normali profili locali. - - La norma <ph name="SYNC_DISABLED_POLICY_NAME" /> consente di disattivare la sincronizzazione di tutti i dati e sostituisce la norma RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtra i siti di contenuti per adulti di primo livello (ma non gli iframe incorporati)</translation> <translation id="6734521799274931721">Consente di controllare la disponibilità della funzione Condivisioni file di rete per Chrome OS</translation> <translation id="6735701345096330595">Forza attivazione lingue per controllo ortografico</translation>
diff --git a/components/policy/resources/policy_templates_iw.xtb b/components/policy/resources/policy_templates_iw.xtb index 4afbac5a..42891d1 100644 --- a/components/policy/resources/policy_templates_iw.xtb +++ b/components/policy/resources/policy_templates_iw.xtb
@@ -119,7 +119,7 @@ <translation id="1291880496936992484">אזהרה: RC4 יוסר לחלוטין מ-<ph name="PRODUCT_NAME" /> לאחר גרסה 52 (בסביבות ספטמבר 2016), ולאחר מכן מדיניות זו תפסיק לפעול. אם המדיניות לא תוגדר או תוגדר כ-false, חבילות הצפנים של RC4 ב-TLS (אבטחת שכבת התעבורה) לא יופעלו. כדי למנוע זאת, אפשר להגדיר את המדיניות כ-true וכך לשמור על תאימות לשרת מיושן. זהו פתרון זמני, ויש להגדיר את השרת מחדש.</translation> -<translation id="1297117713060236551">המדיניות הזו קובעת את רשימת האתרים שלעולם לא יגרמו להחלפת דפדפן. +<translation id="1297117713060236551">המדיניות הזו קובעת את רשימת האתרים שאף פעם לא יגרמו להחלפת דפדפן. לתשומת ליבך, אפשר להוסיף רכיבים לרשימה הזו גם בעזרת המדיניות <ph name="USE_IE_SITELIST_POLICY_NAME" />. @@ -776,11 +776,11 @@ <translation id="3038323923255997294">המשך הפעלת יישומים ברקע כאשר <ph name="PRODUCT_NAME" /> סגור</translation> <translation id="3046192273793919231">שלח מנות רשת לשרת הניהול כדי לנטר את הסטטוס המקוון</translation> <translation id="3047732214002457234">שליטה בדיווח הנתונים של Chrome Cleanup ל-Google</translation> -<translation id="304775240152542058">המדיניות הזו קובעת פרמטרים של שרת הפקודה להפעלת הדפדפן החלופי. +<translation id="304775240152542058">המדיניות הזו קובעת פרמטרים של שורת הפקודה להפעלת הדפדפן החלופי. אם המדיניות הזו לא הוגדרה, רק כתובת ה-URL מועברת כפרמטר בשורת הפקודה. - כשהמדיניות הזו מוגדרת כרשימת מחרוזות, כל מחרוזת מועברת אל הדפדפן החלופי כפרמטר נפרד בשורת הפקודה. ב-Windows, הפרמטרים מחוברים בעזרת רווחים. ב-Mac OS X וב- Linux, פרמטר עשוי לכלול רווחים, ועדיין יטופל כפרמטר יחיד. + כשהמדיניות הזו מוגדרת כרשימת מחרוזות, כל מחרוזת מועברת אל הדפדפן החלופי כפרמטר נפרד בשורת הפקודה. ב-Windows, הפרמטרים מחוברים בעזרת רווחים. ב-Mac OS X וב- Linux, גם פרמטרים שכוללים רווחים יטופלו כפרמטר יחיד. אם רכיב כולל את המשתנה ${url}, הוא מוחלף בכתובת ה-URL של הדף שיש לפתוח. @@ -868,7 +868,7 @@ ערך המדיניות צריך להיות באלפיות שנייה. הערכים מצומצמים כך שיהיו קטנים יותר או שווים להשהיה לפני כיבוי המסך (אם הוגדרה) ולהשהיה לפני מצב לא פעיל.</translation> <translation id="3251500716404598358">הגדרת מדיניות להחלפה בין דפדפנים. - אתרים שהוגדרו ייפתחו באופן אוטומטי בדפדפן אחר שאינו <ph name="PRODUCT_NAME" />.</translation> + אתרים שהוגדרו ייפתחו באופן אוטומטי בדפדפן אחר במקום ב-<ph name="PRODUCT_NAME" />.</translation> <translation id="3264793472749429012">קידודים של ספק חיפוש המוגדר כברירת מחדל</translation> <translation id="3273221114520206906">הגדרת ברירת מחדל של JavaScript</translation> <translation id="3284094172359247914">שליטה בשימוש של ה-WebUSB API</translation> @@ -1555,7 +1555,7 @@ אם המדיניות מוגדרת כ-true או אינה מוגדרת, תכונת מחזורי החיים של כרטיסיות מופעלת.</translation> <translation id="5208240613060747912">מאפשר לך להגדיר רשימה של דפוסי כתובות אתר המפרטת אתרים עם אישור להציג התראות. ם מדיניות זו לא הוגדרה, המערכת תשתמש בערך ברירת המחדל הכללי עבור כל האתרים לפי המדיניות 'DefaultNotificationsSetting' במקרה שהוגדרה, או לפי התצורה האישית שקבע המשתמש במקרה שלא הוגדרה.</translation> -<translation id="5213038356678567351">אתרים שלעולם לא אמורים להפעיל החלפת דפדפן.</translation> +<translation id="5213038356678567351">אתרים שאף פעם לא אמורים להפעיל החלפת דפדפן.</translation> <translation id="5219844027738217407">באפליקציות Android, המדיניות הזו משפיעה רק על המיקרופון. כשהמדיניות הזו מוגדרת כ-true, המיקרופון מושתק בכל אפליקציות Android, ללא חריגים.</translation> <translation id="5228316810085661003">העיכוב של ההתחברות האוטומטית לחשבון מקומי במכשיר. @@ -1718,14 +1718,14 @@ <translation id="5592242031005200087"> אם המדיניות מופעלת, כל אחד מהמקורות שצוינו ברשימה המופרדת באמצעות פסיקים יפעל בתהליך משלו. ההגדרה הזו תבודד גם מקורות שהשם שלהם הוא תת-דומיין. לדוגמה: ציון - הכתובת https://example.com/ יגרום גם לבידוד של https://foo.example.com/ כחלק האתר + הכתובת https://example.com/ יגרום גם לבידוד של https://foo.example.com/ כחלק מהאתר https://example.com/. אם המדיניות מושבתת, לא יתבצע בידוד מפורש של אתר, וניסויי השטח של IsolateOriginsAndroid ו-SitePerProcessAndroid יושבתו. משתמשים עדיין יוכלו להפעיל באופן ידני את IsolateOrigins דרך תכונה ניסיונית בשורת הפקודה. אם המדיניות לא מוגדרת, המשתמש יוכל לשנות את ההגדרה הזו. הערה: בידוד אתר הוא ניסיוני ב-Android. התמיכה תשתפר עם הזמן, אבל נכון לעכשיו התכונה עשויה לגרום לבעיות ביצועים. - הערה: המדיניות הזו חלק רק על Chrome ב-Android במכשירים עם יותר מ-1GB של זיכרון RAM. כדי להחיל את המדיניות על פלטפורמות שאינן Android, יש להשתמש ב-IsolateOrigins. + הערה: המדיניות הזו חלה רק על Chrome ב-Android במכשירים עם זיכרון RAM גדול מ-1GB. כדי להחיל את המדיניות על פלטפורמות אחרות, ולא על Android, יש להשתמש ב-IsolateOrigins. </translation> <translation id="5630352020869108293">שחזר את ההפעלה האחרונה</translation> <translation id="5645779841392247734">אפשר קובצי Cookie באתרים אלה</translation> @@ -1755,7 +1755,7 @@ אם המדיניות הזו לא מוגדרת, לא נוספים אתרים לרשימה. - כשהמדיניות הזו מוגדרת, כל פריט מטופל ככלל שקובע כי פריט כלשהו ייפתח בדפדפן חלופי. <ph name="PRODUCT_NAME" /> משתמש בכללים כאלה בעת הקביעה אם יש לפתוח כתובת URL כלשהי בדפדפן חלופי. + כשהמדיניות הזו מוגדרת, כל פריט מטופל ככלל שקובע כי פריט כלשהו ייפתח בדפדפן חלופי. <ph name="PRODUCT_NAME" /> משתמש בכללים כאלה כדי לקבוע אם יש לפתוח כתובת URL כלשהי בדפדפן חלופי. כשתוסף Internet Explorer קיים ומופעל, Internet Explorer חוזר אל <ph name="PRODUCT_NAME" /> כשאין התאמה בכללים. @@ -2099,11 +2099,6 @@ <translation id="6689792153960219308">דיווח על מצב חומרה</translation> <translation id="6698632841807204978">הפעלת הדפסה בשחור-לבן</translation> <translation id="6699880231565102694">אפשר אימות של שני גורמים עבור מארחים של גישה מרחוק</translation> -<translation id="6724842112053619797">אם תפעיל את ההגדרה הזו, גם ההגדרות השמורות בפרופילים ב-<ph name="PRODUCT_NAME" />, כמו סימניות, נתוני מילוי אוטומטי, סיסמאות וכו', ייכתבו בקובץ שמאוחסן בתיקיית פרופיל המשתמש Roaming או במיקום שצוין על-ידי מנהל המערכת במדיניות <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. הפעלת המדיניות הזו משביתה את הסינכרון בענן. - - אם המדיניות הזו מושבתת או אינה מוגדרת, ייעשה שימוש רק בפרופילים המקומיים הרגילים. - - המדיניות <ph name="SYNC_DISABLED_POLICY_NAME" /> משביתה לחלוטין את סינכרון הנתונים, ועוקפת את RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">סינון אתרים ברמה עליונה שמכילים תוכן למבוגרים בלבד (אבל לא מסגרות iframe מוטמעות)</translation> <translation id="6734521799274931721">שליטה בהגדרות התכונה 'התקן רשת לשיתוף קבצים' לקביעת הזמינות של ChromeOS</translation> <translation id="6735701345096330595">אילוץ הפעלה של שפות לבדיקת איות</translation> @@ -2186,7 +2181,7 @@ מדיניות זו מציינת את הסימונים שיש להחיל על <ph name="PRODUCT_NAME" /> כשהוא מופעל. החלת הסימונים שצוינו מתבצעת רק במסך ההתחברות. סימונים המוגדרים במסגרת מדיניות זו אינם מופצים לסשנים של משתמשים.</translation> <translation id="685769593149966548">אכיפת סינון תוכן קפדני ב-YouTube</translation> -<translation id="6857824281777105940">המדיניות הזו קובעת אם לדווח מידע לגבי גלישה בטוחה, כולל מספר האזהרות של גלישה בטוחה ומספר שיעור הקליקים של אזהרות גלישה בטוחה. +<translation id="6857824281777105940">המדיניות הזו קובעת אם לדווח מידע לגבי גלישה בטוחה, כולל מספר האזהרות של גלישה בטוחה ומספר הקליקים על אזהרות גלישה בטוחה. כאשר המדיניות הזו לא מוגדרת או מוגדרת כ-True, נתוני גלישה בטוחה נאספים. כאשר המדיניות הזו מוגדרת כ-False, נתוני גלישה בטוחה לא נאספים. @@ -2337,8 +2332,7 @@ כשהמדיניות הזו לא מוגדרת נעשה שימוש בברירת המחדל הספציפית לפלטפורמה: Internet Explorer ב-Windows או Safari ב-Mac OS X. הפעלת דפדפן חלופי ב-Linux תיכשל אם המדיניות הזו לא מוגדרת. - כשבמדיניות מוגדר אחד מהמשתנים ${ie}, ${firefox}, ${safari} או - ${opera}, הדפדפן הזה יופעל אם הוא מותקן. ${ie} זמין רק ב-Windows ו-${safari} זמין רק ב-Windows וב-Mac OS X. + כשבמדיניות מוגדר אחד מהמשתנים הבאים: ${ie}, ${firefox}, ${safari} או ${opera}, הדפדפן הזה יופעל אם הוא מותקן. ${ie} זמין רק ב-Windows ו-${safari} זמין רק ב-Windows וב-Mac OS X. כשבמדיניות הזו מוגדר נתיב קובץ, הקובץ הזה משמש כקובץ הפעלה.</translation> <translation id="7167436895080860385">התר למשתמשים להציג סיסמאות במנהל הסיסמאות (יצא משימוש)</translation>
diff --git a/components/policy/resources/policy_templates_ja.xtb b/components/policy/resources/policy_templates_ja.xtb index f4ef5ea..f6c772f 100644 --- a/components/policy/resources/policy_templates_ja.xtb +++ b/components/policy/resources/policy_templates_ja.xtb
@@ -2110,11 +2110,6 @@ <translation id="6689792153960219308">ハードウェア ステータスを報告する</translation> <translation id="6698632841807204978">白黒印刷を有効にする</translation> <translation id="6699880231565102694">リモート アクセス ホストの 2 段階認証プロセスを有効にする</translation> -<translation id="6724842112053619797">この設定を有効にした場合は、<ph name="PRODUCT_NAME" /> プロフィールに保存されている設定(ブックマーク、自動入力データ、パスワードなど)が、「ローミング」ユーザー プロフィール フォルダまたは管理者が <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> ポリシーで指定した場所に保存されるファイルにも書き込まれます。このポリシーを有効にすると、クラウド同期は無効になります。 - - このポリシーを無効にするか未設定のままにした場合は、通常のローカル プロフィールのみが使用されます。 - - <ph name="SYNC_DISABLED_POLICY_NAME" /> ポリシーが設定されている場合は、すべてのデータ同期が無効になります。この設定は、RoamingProfileSupportEnabled ポリシーの設定よりも優先されます。</translation> <translation id="6731757988219967594">アダルト コンテンツに基づいて最上位サイト(埋め込み iframe 以外)を除外する</translation> <translation id="6734521799274931721">Chrome OS でネットワーク ファイル共有を使用できるかどうかの設定</translation> <translation id="6735701345096330595">言語のスペルチェックを強制的に有効にする</translation>
diff --git a/components/policy/resources/policy_templates_kn.xtb b/components/policy/resources/policy_templates_kn.xtb index 8f25d7d9..3209475 100644 --- a/components/policy/resources/policy_templates_kn.xtb +++ b/components/policy/resources/policy_templates_kn.xtb
@@ -2285,12 +2285,6 @@ <translation id="6689792153960219308">ಹಾರ್ಡ್ವೇರ್ ಸ್ಥಿತಿ ವರದಿ ಮಾಡಿ</translation> <translation id="6698632841807204978">ಮೊನೊಕ್ರೋಮ್ ಮುದ್ರಣವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ</translation> <translation id="6699880231565102694">ರಿಮೋಟ್ ಪ್ರವೇಶ ಹೋಸ್ಟ್ಗಳಿಗಾಗಿ ಎರಡು ಅಂಶದ ಪ್ರಮಾಣೀಕರಣ ಸಕ್ರಿಯಗೊಳಿಸು</translation> -<translation id="6724842112053619797">ನೀವು ಈ ಸೆಟ್ಟಿಂಗ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿದರೆ, ಬುಕ್ಮಾರ್ಕ್ಗಳು, ಸ್ವಯಂ ಭರ್ತಿ ಡೇಟಾ, ಪಾಸ್ವರ್ಡ್ಗಳು, ಇತ್ಯಾದಿಯಂತಹ <ph name="PRODUCT_NAME" />ಪ್ರೊಫೈಲ್ನಲ್ಲಿ ಸಂಗ್ರಹಿತವಾದ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಸಂಗ್ರಹಿಸಲಾಗುತ್ತದೆ. ಇದನ್ನು <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />ನೀತಿಯ ಮೂಲಕ ನಿರ್ವಾಹಕರು ಸೂಚಿಸಲಾದ ರೋಮಿಂಗ್ ಬಳಕೆದಾರ ಪ್ರೊಫೈಲ್ ಫೋಲ್ಡರ್ ಅಥವಾ ಸ್ಥಳದಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾದ ಫೈಲ್ಗೆ ಸಹ ಬರೆಯಲಾಗುತ್ತದೆ. -ಈ ನೀತಿಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿದಾಗ ಕ್ಲೌಡ್ ಸಿಂಕ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ. - -ಈ ನೀತಿಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದರೆ ಅಥವಾ ಹಾಗೆಯೇ ಹೊಂದಿಸದೇ ಬಿಟ್ಟರೆ ನಿಯಮಿತ ಸ್ಥಳೀಯ ಪ್ರೊಫೈಲ್ಗಳನ್ನು ಮಾತ್ರ ಬಳಸಲಾಗುತ್ತದೆ. - -<ph name="SYNC_DISABLED_POLICY_NAME" /> ಈ ನೀತಿಯು ಸಿಂಕ್ರೊನೈಸೇಶನ್ ಮಾಡಿದ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ, RoamingProfileSupportEnabled ಅನ್ನು ಅತಿಕ್ರಮಿಸುತ್ತದೆ.</translation> <translation id="6731757988219967594">ವಯಸ್ಕರ ವಿಷಯಕ್ಕಾಗಿ ಉನ್ನತ ಮಟ್ಟದ ಸೈಟ್ಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಿ (ಆದರೆ ಎಂಬೆಡ್ ಮಾಡಿದ iframe ಗಳನ್ನಲ್ಲ)</translation> <translation id="6734521799274931721">ChromeOS ಲಭ್ಯತೆಗಾಗಿ ನೆಟ್ವರ್ಕ್ನಲ್ಲಿ ಫೈಲ್ ಹಂಚುವಿಕೆಯನ್ನು ನಿಯಂತ್ರಿಸುತ್ತದೆ</translation> <translation id="6735701345096330595">ಕಾಗುಣಿತ ಪರೀಕ್ಷೆ ಭಾಷೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲು ಒತ್ತಾಯಿಸಿ</translation>
diff --git a/components/policy/resources/policy_templates_ko.xtb b/components/policy/resources/policy_templates_ko.xtb index 8eafcaa..47bb951 100644 --- a/components/policy/resources/policy_templates_ko.xtb +++ b/components/policy/resources/policy_templates_ko.xtb
@@ -2188,11 +2188,6 @@ <translation id="6689792153960219308">하드웨어 상태 보고</translation> <translation id="6698632841807204978">단색 인쇄 사용 설정</translation> <translation id="6699880231565102694">원격 액세스 호스트를 위한 2단계 인증 사용</translation> -<translation id="6724842112053619797">이 설정을 사용하면 북마크, 데이터 자동 완성, 비밀번호 등 <ph name="PRODUCT_NAME" /> 프로필에 저장된 설정이 로밍 사용자 프로필 폴더나 <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> 정책을 통해 관리자가 지정한 위치에 저장된 파일에도 작성됩니다. 이 정책을 사용하면 클라우드 동기화는 사용 중지됩니다. - - 이 정책을 사용 중지하거나 설정하지 않으면 일반 로컬 프로필만 사용됩니다. - - <ph name="SYNC_DISABLED_POLICY_NAME" /> 정책은 모든 데이터 동기화를 사용 중지하며 RoamingProfileSupportEnabled를 무시합니다.</translation> <translation id="6731757988219967594">최상위 사이트(삽입된 iframe 제외)에 성인용 콘텐츠 필터링을 적용함</translation> <translation id="6734521799274931721">Chrome OS의 네트워크 파일 공유 가능 여부를 제어합니다.</translation> <translation id="6735701345096330595">언어 맞춤법 검사 강제 사용</translation>
diff --git a/components/policy/resources/policy_templates_lt.xtb b/components/policy/resources/policy_templates_lt.xtb index 2252e02..f5da206 100644 --- a/components/policy/resources/policy_templates_lt.xtb +++ b/components/policy/resources/policy_templates_lt.xtb
@@ -2190,11 +2190,6 @@ <translation id="6689792153960219308">Aparatinės įrangos būsenos ataskaitos pateikimas</translation> <translation id="6698632841807204978">Įgalinti vienspalvį spausdinimą</translation> <translation id="6699880231565102694">Įgalinti nuotolinės prieigos prieglobų autentifikavimą dviem veiksniais</translation> -<translation id="6724842112053619797">Jei įgalinsite šį nustatymą, saugomą „<ph name="PRODUCT_NAME" />“ profiliuose, pvz., žymėse, automatinio pildymo duomenyse, slaptažodžiuose ir kt., išsaugoti nustatymai taip pat bus įrašyti į failą, saugomą tarptinklinio ryšio naudotojo profilio aplanke arba administratoriaus nurodytoje vietoje pagal „<ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />“ politiką. Sinchronizavimas debesyje automatiškai išjungiamas, kai įgalinama ši politika. - - Jei ši politika išjungta ar nenustatyta, bus naudojami tik įprasti vietiniai profiliai. - - „<ph name="SYNC_DISABLED_POLICY_NAME" />“ politika išjungia visų duomenų sinchronizavimą ir nepaiso „RoamingProfileSupportEnabled“.</translation> <translation id="6731757988219967594">Filtruoti turinį suaugusiesiems aukščiausio lygio svetainėse (bet ne įterptuose „iframe“)</translation> <translation id="6734521799274931721">Valdomas „Chrome“ OS skirtų tinklo failų bendrinimo įrenginių pasiekiamumas</translation> <translation id="6735701345096330595">Priverstinis rašybos tikrinimo kalbų įgalinimas</translation>
diff --git a/components/policy/resources/policy_templates_lv.xtb b/components/policy/resources/policy_templates_lv.xtb index 587d05f..b188fd3 100644 --- a/components/policy/resources/policy_templates_lv.xtb +++ b/components/policy/resources/policy_templates_lv.xtb
@@ -2173,11 +2173,6 @@ <translation id="6689792153960219308">Ziņošana par aparatūras statusu</translation> <translation id="6698632841807204978">Iespējot vienkrāsaino drukāšanu</translation> <translation id="6699880231565102694">Divu faktoru autentifikācijas iespējošana attālās piekļuves saimniekdatoriem</translation> -<translation id="6724842112053619797">Ja iespējosiet šo iestatījumu, <ph name="PRODUCT_NAME" /> profilos saglabātie iestatījumi, piemēram, grāmatzīmes, automātiskās aizpildes dati, paroles, tiks saglabāti arī failā, kas tiks glabāts viesabonēšanas lietotāju profilu mapē vai vietā, ko norādījis administrators, izmantojot politiku “<ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />”. Iespējojot šo politiku, tiek atspējota sinhronizācija mākonī. - - Ja šī politika ir atspējota vai nav iestatīta, tiks izmantoti tikai parastie lokālie profili. - - Politika “<ph name="SYNC_DISABLED_POLICY_NAME" />” atspējo visu datu sinhronizāciju, ignorējot politiku “RoamingProfileSupportEnabled”.</translation> <translation id="6731757988219967594">Filtrēt augšējā līmeņa vietnes ar pieaugušajiem paredzētu saturu (bet ne iegultos iFrame tagus)</translation> <translation id="6734521799274931721">Kontrolē tīkla failu kopīgošanas ierīces Chrome OS pieejamībai</translation> <translation id="6735701345096330595">Iespējo pareizrakstības pārbaudes valodas piespiedu kārtā</translation>
diff --git a/components/policy/resources/policy_templates_ml.xtb b/components/policy/resources/policy_templates_ml.xtb index 8f1688b..4eb30a4 100644 --- a/components/policy/resources/policy_templates_ml.xtb +++ b/components/policy/resources/policy_templates_ml.xtb
@@ -2418,11 +2418,6 @@ <translation id="6689792153960219308">ഹാർഡ്വെയർ നില റിപ്പോർട്ട് ചെയ്യുക</translation> <translation id="6698632841807204978">ഏകവർണ്ണ അച്ചടി പ്രവർത്തനക്ഷമമാക്കുക</translation> <translation id="6699880231565102694">വിദൂര ആക്സസ്സ് ഹോസ്റ്റുകൾക്കായി ഇരട്ട-വസ്തുതാ പ്രാമാണീകരണം പ്രാപ്തമാക്കുക</translation> -<translation id="6724842112053619797">റോമിംഗ് ഉപയോക്തൃ പ്രൊഫൈൽ ഫോൾഡറിലോ <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> നയം വഴി അഡ്മിനിസ്ട്രേറ്റർ നൽകിയ ലൊക്കേഷനിലോ സൂക്ഷിച്ചിട്ടുള്ള ഒരു ഫയലിൽ, ബുക്ക്മാർക്കുകൾ, സ്വയമേവ പൂരിപ്പിക്കുന്ന വിവരങ്ങൾ, പാസ്വേഡുകൾ എന്നിവ പോലെ <ph name="PRODUCT_NAME" /> പ്രൊഫൈലുകളിൽ സൂക്ഷിച്ചിരിക്കുന്ന ക്രമീകരണവും റൈറ്റുചെയ്യും. ഈ നയം പ്രവർത്തനസജ്ജമാക്കുമ്പോൾ ക്ലൗഡ് സമന്വയിപ്പിക്കൽ പ്രവർത്തനരഹിതമാക്കുന്നു. - - ഈ നയം പ്രവർത്തനരഹിതമാക്കുകയോ അല്ലെങ്കിൽ സജ്ജമാക്കാതെ വിടുകയോ ആണെങ്കിൽ, സാധാരണ ലോക്കൽ പ്രൊഫൈലുകൾ മാത്രമേ ഉപയോഗിക്കൂ. - - ഈ <ph name="SYNC_DISABLED_POLICY_NAME" /> നയം എല്ലാ ഡാറ്റ സമന്വയിപ്പിക്കലും പ്രവർത്തനരഹിതമാക്കുകയും, RoamingProfileSupportEnabled അസാധുവാക്കുകയും ചെയ്യുന്നു.</translation> <translation id="6731757988219967594">മുതിർന്നവർക്കായുള്ള ഉള്ളടക്കത്തിനായി ഉന്നത നിലയിലുള്ള സൈറ്റുകൾ (എന്നാൽ ഉൾച്ചേർത്തിട്ടുള്ള iframe-കൾ അല്ല) ഫിൽട്ടർ ചെയ്യുക</translation> <translation id="6734521799274931721">ChromeOS ലഭ്യതയ്ക്കായി നെറ്റ്വർക്ക് ഫയൽ പങ്കിടൽ നിയന്ത്രിക്കുന്നു</translation> <translation id="6735701345096330595">ഭാഷകളുടെ അക്ഷരപ്പിശക് പരിശോധന പ്രവർത്തനക്ഷമമാക്കുന്നത് നിർബന്ധിക്കുക</translation>
diff --git a/components/policy/resources/policy_templates_mr.xtb b/components/policy/resources/policy_templates_mr.xtb index 4c8babd..44f5829 100644 --- a/components/policy/resources/policy_templates_mr.xtb +++ b/components/policy/resources/policy_templates_mr.xtb
@@ -2464,11 +2464,6 @@ <translation id="6689792153960219308">हार्डवेअर स्थितीची तक्रार करा</translation> <translation id="6698632841807204978">मोनोक्रोम प्रिंटिंग सुरू करा</translation> <translation id="6699880231565102694">दूरस्थ प्रवेश होस्टसाठी द्वि-घटक प्रमाणीकरण सक्षम करा</translation> -<translation id="6724842112053619797">तुम्ही ही सेटिंग चालू केल्यास, <ph name="PRODUCT_NAME" /> च्या प्रोफाइलमध्ये स्टोअर असलेल्या सेटिंग्ज जसे बुकमार्क, ऑटोफिल डेटा, पासवर्ड, इ. देखील रोमिंग वापरकर्ता प्रोफाइल फोल्डरमध्ये किंवा प्रशासकाने <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> धोरणामधून नमूद केलेल्या स्थानावर स्टोअर केलेल्या फाइलमध्ये लिहिल्या जातील. हे धोरण चालू केल्याने क्लाऊड सिंक बंद होईल. - - हे धोरण बंद केल्यास किंवा सेट न करता ठेवल्यास फक्त नेहमीच्या स्थानिक प्रोफाइल वापरात येतील. - - <ph name="SYNC_DISABLED_POLICY_NAME" /> धोरण RoamingProfileSupportEnabled ला अधिलिखित करून, सर्व डेटा सिंक्रोनायझेशन बंद करेल.</translation> <translation id="6731757988219967594">प्रौढांसाठी असलेल्या आशयाकरिता उच्च पातळी साइट (परंतु एंबेड केलेल्या iframes नव्हे) फिल्टर करा</translation> <translation id="6734521799274931721">ChromeOS च्या उपलब्धतेसाठी नेटवर्क फाइल शेअर नियंत्रित करते</translation> <translation id="6735701345096330595">शब्दलेखन भाषा जाणीवपूर्वक चालू करा</translation>
diff --git a/components/policy/resources/policy_templates_ms.xtb b/components/policy/resources/policy_templates_ms.xtb index e1bfac6..08c97f0d 100644 --- a/components/policy/resources/policy_templates_ms.xtb +++ b/components/policy/resources/policy_templates_ms.xtb
@@ -2189,11 +2189,6 @@ <translation id="6689792153960219308">Laporkan status perkakasan</translation> <translation id="6698632841807204978">Dayakan pencetakan monokrom</translation> <translation id="6699880231565102694">Dayakan pengesahan dua faktor untuk hos akses jauh</translation> -<translation id="6724842112053619797">Jika anda mendayakan tetapan ini, tetapan yang disimpan dalam profil <ph name="PRODUCT_NAME" /> seperti penanda halaman, data autolengkap, kata laluan dan sebagainya akan turut ditulis pada fail yang disimpan dalam folder profil "Roaming" pengguna atau lokasi yang ditentukan oleh Pentadbir melaui dasar <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Sekiranya dasar ini didayakan, penyegerakan awan akan dilumpuhkan. - - Jika dasar ini dilumpuhkan atau dibiarkan tidak ditetapkan, hanya profil "local" biasa akan digunakan. - - Dasar <ph name="SYNC_DISABLED_POLICY_NAME" /> melumpuhkan semua penyegerakan data, mengatasi RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Tapis tapak peringkat atas (tetapi bukan iframe yang dibenamkan) untuk kandungan dewasa</translation> <translation id="6734521799274931721">Mengawal Perkongsian Fail Rangkaian untuk ketersediaan OS Chrome</translation> <translation id="6735701345096330595">Paksa dayakan semakan ejaan bahasa</translation>
diff --git a/components/policy/resources/policy_templates_nl.xtb b/components/policy/resources/policy_templates_nl.xtb index f21f645..4c2e547 100644 --- a/components/policy/resources/policy_templates_nl.xtb +++ b/components/policy/resources/policy_templates_nl.xtb
@@ -2191,11 +2191,6 @@ <translation id="6689792153960219308">De hardwarestatus melden</translation> <translation id="6698632841807204978">Monochroom afdrukken inschakelen</translation> <translation id="6699880231565102694">Authenticatie in twee stappen inschakelen voor hosts voor externe toegang</translation> -<translation id="6724842112053619797">Als je deze instelling inschakelt, worden de instellingen die zijn opgeslagen in <ph name="PRODUCT_NAME" />-profielen (zoals bladwijzers, gegevens voor automatisch aanvullen, wachtwoorden, enzovoort), ook geschreven naar een bestand dat is opgeslagen in de map voor roaming-gebruikersprofielen of op een locatie die de beheerder heeft opgegeven via het beleid <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Als je dit beleid inschakelt, wordt cloud-synchronisatie uitgeschakeld. - - Als dit beleid is uitgeschakeld of niet wordt ingesteld, worden alleen de gewone lokale profielen gebruikt. - - Met het beleid <ph name="SYNC_DISABLED_POLICY_NAME" /> wordt alle gegevenssynchronisatie uitgeschakeld (RoamingProfileSupportEnabled wordt overschreven).</translation> <translation id="6731757988219967594">Sites op hoofdniveau (maar geen ingesloten iframes) filteren op content voor volwassenen</translation> <translation id="6734521799274931721">Beheert netwerkfileshares voor Chrome OS-beschikbaarheid</translation> <translation id="6735701345096330595">Inschakelen van spellingcontrole voor talen afdwingen</translation>
diff --git a/components/policy/resources/policy_templates_no.xtb b/components/policy/resources/policy_templates_no.xtb index cdcab30..af3b175 100644 --- a/components/policy/resources/policy_templates_no.xtb +++ b/components/policy/resources/policy_templates_no.xtb
@@ -2156,11 +2156,6 @@ <translation id="6689792153960219308">Rapportér maskinvarestatus</translation> <translation id="6698632841807204978">Slå på utskrift i svart/hvitt</translation> <translation id="6699880231565102694">Aktiver to-delt autentisering for verter med ekstern adgang</translation> -<translation id="6724842112053619797">Hvis du slår på denne innstillingen, blir innstillingene som er lagret i <ph name="PRODUCT_NAME" />-profiler (for eksempel bokmerker, autofylldata, passord også videre), også skrevet til en fil som lagres i mappen for roaming-brukerprofilen, eller på et sted som bestemmes av administratoren via regelen <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Når du slår på denne regelen, deaktiveres skysynkronisering. - - Hvis denne regelen er slått av eller ikke er angitt, blir bare de vanlige, lokale profilene brukt. - - <ph name="SYNC_DISABLED_POLICY_NAME" />-regelen deaktiverer all datasynkronisering og overstyrer RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtrer toppnivånettsteder (men ikke innebygde iframe-elementer) for seksuelt innhold</translation> <translation id="6734521799274931721">Kontrollerer tilgjengeligheten for delte nettverksressurser for ChromeOS</translation> <translation id="6735701345096330595">Tving aktivering av språk med stavekontroll</translation>
diff --git a/components/policy/resources/policy_templates_pl.xtb b/components/policy/resources/policy_templates_pl.xtb index 2472826..46a9625 100644 --- a/components/policy/resources/policy_templates_pl.xtb +++ b/components/policy/resources/policy_templates_pl.xtb
@@ -2116,11 +2116,6 @@ <translation id="6689792153960219308">Raportuj stan sprzętu</translation> <translation id="6698632841807204978">Włącz drukowanie monochromatyczne</translation> <translation id="6699880231565102694">Włącz uwierzytelnianie dwuskładnikowe dla hostów zdalnego dostępu</translation> -<translation id="6724842112053619797">Jeśli włączysz to ustawienie, ustawienia zapisane w profilach <ph name="PRODUCT_NAME" />, takie jak zakładki, dane autouzupełniania, hasła itp., będą też zapisywane w folderze profilu przenośnego (Roaming) użytkownika lub w lokalizacji ustawionej przez administratora w zasadzie <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Włączenie tej zasady wyłącza synchronizację z chmurą. - - Jeśli nie włączysz tej zasady lub jej nie skonfigurujesz, używane będą tylko zwykłe profile lokalne. - - Zasada <ph name="SYNC_DISABLED_POLICY_NAME" /> powoduje wyłączenie wszystkich synchronizacji danych i zastępuje zasadę RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtruj witryny najwyższego poziomu (ale nie osadzone elementy iframe) pod kątem treści dla dorosłych</translation> <translation id="6734521799274931721">Określa dostępność sieciowych udziałów plików w Chrome OS</translation> <translation id="6735701345096330595">Wymuś włączenie sprawdzania pisowni</translation>
diff --git a/components/policy/resources/policy_templates_pt-BR.xtb b/components/policy/resources/policy_templates_pt-BR.xtb index 6637979..a74415c1 100644 --- a/components/policy/resources/policy_templates_pt-BR.xtb +++ b/components/policy/resources/policy_templates_pt-BR.xtb
@@ -2102,11 +2102,6 @@ <translation id="6689792153960219308">Informar status de hardware</translation> <translation id="6698632841807204978">Ativar impressão monocromática</translation> <translation id="6699880231565102694">Ativar autenticação de dois fatores para hosts de acesso remoto</translation> -<translation id="6724842112053619797">Se você ativar esta configuração, as definições armazenadas nos perfis do <ph name="PRODUCT_NAME" />, como favoritos, dados de preenchimento automático, senhas, entre outros, serão gravadas em um arquivo armazenado na pasta Perfil de usuário de roaming ou em um local especificado pelo administrador por meio da política <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. A ativação dessa política desativa a sincronização em nuvem. - - Se essa política for desativada ou não for configurada, apenas os perfis locais normais serão usados. - - A política <ph name="SYNC_DISABLED_POLICY_NAME" /> desativa a sincronização de todos os dados por meio da modificação de RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtrar sites de nível superior (exceto iframes incorporados) com conteúdo adulto</translation> <translation id="6734521799274931721">Controla o compartilhamento de arquivos de rede para disponibilidade do Chrome OS</translation> <translation id="6735701345096330595">Forçar a ativação da correção ortográfica de idiomas</translation>
diff --git a/components/policy/resources/policy_templates_pt-PT.xtb b/components/policy/resources/policy_templates_pt-PT.xtb index 9c42ed53..f87bb83 100644 --- a/components/policy/resources/policy_templates_pt-PT.xtb +++ b/components/policy/resources/policy_templates_pt-PT.xtb
@@ -2121,11 +2121,6 @@ <translation id="6689792153960219308">Comunicar o estado do hardware</translation> <translation id="6698632841807204978">Ativar impressão monocromática</translation> <translation id="6699880231565102694">Ativar a autenticação de dois fatores para anfitriões de acesso remoto</translation> -<translation id="6724842112053619797">Se ativar esta definição, as definições armazenadas nos perfis do <ph name="PRODUCT_NAME" />, tais como marcadores, dados de preenchimento automático, palavras-passe, etc., também são escritas num ficheiro armazenado na pasta do perfil de utilizador Roaming ou numa localização especificada pelo gestor através da política <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Se ativar esta política, desativa a sincronização na nuvem. - - Se esta política estiver desativada ou não estiver definida, apenas são utilizados os perfis locais normais. - - A política <ph name="SYNC_DISABLED_POLICY_NAME" /> desativa a sincronização de todos os dados e substitui a política RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtrar sites de nível superior (mas não iFrames incorporados) com conteúdo para adultos</translation> <translation id="6734521799274931721">Controla a disponibilidade das Partilhas de ficheiros na rede para o Chrome OS</translation> <translation id="6735701345096330595">Forçar a ativação de idiomas com verificação ortográfica</translation>
diff --git a/components/policy/resources/policy_templates_ro.xtb b/components/policy/resources/policy_templates_ro.xtb index 0286c00..7e657655 100644 --- a/components/policy/resources/policy_templates_ro.xtb +++ b/components/policy/resources/policy_templates_ro.xtb
@@ -2113,11 +2113,6 @@ <translation id="6689792153960219308">Raportează starea hardware-ului</translation> <translation id="6698632841807204978">Activează printarea monocromă</translation> <translation id="6699880231565102694">Activați autentificarea cu doi factori pentru gazdele de acces la distanță</translation> -<translation id="6724842112053619797">Dacă activezi această setare, setările stocate în profilurile <ph name="PRODUCT_NAME" />, cum ar fi marcajele, datele de completare automată, parolele etc. vor fi scrise și într-un fișier stocat în dosarul profilului de utilizator pentru Roaming sau într-o locație specificată de administrator prin politica <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Dacă activezi această politică, se dezactivează sincronizarea în cloud. - - Dacă această politică este dezactivată sau nu este configurată, se vor folosi numai profilurile locale obișnuite. - - Politica <ph name="SYNC_DISABLED_POLICY_NAME" /> dezactivează integral sincronizarea datelor, ignorând RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtrează conținutul pentru adulți de pe site-urile de nivel superior (nu și pentru cadrele iframe încorporate)</translation> <translation id="6734521799274931721">Controlează funcția Dispozitive de stocare în rețea pentru disponibilitatea sistemului de operare Chrome</translation> <translation id="6735701345096330595">Forțează activarea verificării ortografice pentru limbi</translation>
diff --git a/components/policy/resources/policy_templates_ru.xtb b/components/policy/resources/policy_templates_ru.xtb index b41d4ca..f4ed005 100644 --- a/components/policy/resources/policy_templates_ru.xtb +++ b/components/policy/resources/policy_templates_ru.xtb
@@ -2099,11 +2099,6 @@ <translation id="6689792153960219308">Отчет о статусе оборудования</translation> <translation id="6698632841807204978">Включить черно-белую печать</translation> <translation id="6699880231565102694">Включение двухфакторной аутентификации для хостов удаленного доступа</translation> -<translation id="6724842112053619797">При включении этого правила настройки профиля для сервиса "<ph name="PRODUCT_NAME" />" (например, закладки, данные автозаполнения, пароли и т. д.) копируются в отдельный файл. Он хранится в папке перемещаемого профиля пользователя или в каталоге, который администратор определил в правиле <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Когда это правило включено, синхронизация с облаком не выполняется. - - Если это правило отключено или не установлено, будут использованы только обычные локальные профили. - - Правило <ph name="SYNC_DISABLED_POLICY_NAME" /> отключает синхронизацию всех данных, изменяя правило RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Фильтровать сайты верхнего уровня (кроме встроенных окон iframe), содержащие контент для взрослых</translation> <translation id="6734521799274931721">Управление функцией совместного доступа к файлам в сети для Chrome OS</translation> <translation id="6735701345096330595">Принудительная проверка правописания для определенных языков</translation>
diff --git a/components/policy/resources/policy_templates_sk.xtb b/components/policy/resources/policy_templates_sk.xtb index 912f52c..f66bd12 100644 --- a/components/policy/resources/policy_templates_sk.xtb +++ b/components/policy/resources/policy_templates_sk.xtb
@@ -2176,11 +2176,6 @@ <translation id="6689792153960219308">Nahlásiť stav hardvéru</translation> <translation id="6698632841807204978">Povoliť monochromatickú tlač</translation> <translation id="6699880231565102694">Povolenie dvojfázového overenia totožnosti pre hostiteľov vzdialeného prístupu</translation> -<translation id="6724842112053619797">Ak povolíte toto nastavenie, nastavenia uložené v profiloch <ph name="PRODUCT_NAME" /> (napr. záložky, údaje automatického dopĺňania, heslá atď.) sa zapíšu tiež do súboru uloženého v priečinku roamingového používateľského profilu alebo v umiestnení špecifikovanom správcom prostredníctvom pravidla <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Povolenie tohto pravidla vypne synchronizáciu s cloudom. - - Ak je toto pravidlo zakázané alebo nie je nastavené, budú sa používať iba miestne profily. - - Pravidlo <ph name="SYNC_DISABLED_POLICY_NAME" /> vypne synchronizáciu všetkých údajov a prepíše pravidlo RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtrovať weby najvyššej úrovne (ale nie vložené prvky iframe) podľa obsahu pre dospelých</translation> <translation id="6734521799274931721">Riadi dostupnosť zdieľaných súborov v sieti pre Chrome OS</translation> <translation id="6735701345096330595">Vynútiť povolenie jazykov kontroly pravopisu</translation>
diff --git a/components/policy/resources/policy_templates_sl.xtb b/components/policy/resources/policy_templates_sl.xtb index 401c452..ade4ce2 100644 --- a/components/policy/resources/policy_templates_sl.xtb +++ b/components/policy/resources/policy_templates_sl.xtb
@@ -2192,11 +2192,6 @@ <translation id="6689792153960219308">Poročanje o stanju strojne opreme</translation> <translation id="6698632841807204978">Omogočanje enobarvnega tiskanja</translation> <translation id="6699880231565102694">Omogočanje preverjanja pristnosti v dveh korakih za gostitelje oddaljenega dostopa</translation> -<translation id="6724842112053619797">Če omogočite to nastavitev, se podatki, shranjeni v profilih izdelka <ph name="PRODUCT_NAME" />, kot so zaznamki, podatki samodejnega izpolnjevanja, gesla in drugi podatki, prav tako zapišejo v datoteko, shranjeno v mapo uporabniškega profila za gostovanje ali na lokacijo, ki jo določi skrbnik s pravilnikom <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Če omogočite ta pravilnik, onemogočite sinhronizacijo z oblakom. - - Če je ta pravilnik onemogočen ali ni nastavljen, se uporabijo samo lokalni profili. - - Pravilnik <ph name="SYNC_DISABLED_POLICY_NAME" /> onemogoči vso sinhronizacijo podatkov in preglasi pravilnik RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtriranje vrhnjih spletnih mest (vendar ne vdelanih elementov iframe) zaradi izločanja vsebine za odrasle</translation> <translation id="6734521799274931721">Nadzira razpoložljivost omrežnih naprav za skupno rabo datotek v okolju OS Chrome</translation> <translation id="6735701345096330595">Vsiljeno preverjanje črkovanja jezikov</translation>
diff --git a/components/policy/resources/policy_templates_sr.xtb b/components/policy/resources/policy_templates_sr.xtb index 69697f5d..c45e0e3 100644 --- a/components/policy/resources/policy_templates_sr.xtb +++ b/components/policy/resources/policy_templates_sr.xtb
@@ -2184,11 +2184,6 @@ <translation id="6689792153960219308">Шаљи извештај о статусу хардвера</translation> <translation id="6698632841807204978">Омогући једнобојно штампање</translation> <translation id="6699880231565102694">Омогућавање потврде аутентичности помоћу два фактора за хостове са даљинским приступом</translation> -<translation id="6724842112053619797">Ако омогућите ово подешавање, подешавања сачувана на <ph name="PRODUCT_NAME" /> профилима, нпр. обележивачи, подаци за аутоматско попуњавање, лозинке итд. ће бити уписана и у датотеку која се чува у директоријуму корисничког профила Роминг или на локацији коју наведе администратор путем <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> смерница. Ако омогућите ове смернице, онемогућићете синхронизовање у клауду. - - Ако онемогућите ове смернице или их оставите неподешене, користиће се само стандардни локални профили. - - Смернице <ph name="SYNC_DISABLED_POLICY_NAME" /> онемогућавају сваку синхронизацију података, замењујући RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Филтрирај сајтове највишег нивоа (али не и уграђене iframe-ове) на основу садржаја за одрасле</translation> <translation id="6734521799274931721">Контролишу доступност функције дељења датотека у мрежи за Chrome ОС</translation> <translation id="6735701345096330595">Принудно омогућавају језике за проверу правописа</translation>
diff --git a/components/policy/resources/policy_templates_sv.xtb b/components/policy/resources/policy_templates_sv.xtb index 2b04869..577c74e 100644 --- a/components/policy/resources/policy_templates_sv.xtb +++ b/components/policy/resources/policy_templates_sv.xtb
@@ -2195,11 +2195,6 @@ <translation id="6689792153960219308">Rapportera maskinvarustatus</translation> <translation id="6698632841807204978">Aktivera utskrift i svartvitt</translation> <translation id="6699880231565102694">Aktivera tvåfaktorsautentisering för fjärråtkomstvärdar</translation> -<translation id="6724842112053619797">Om du aktiverar den här inställningen skrivs även inställningar för <ph name="PRODUCT_NAME" />-profiler (exempelvis bokmärken, autofylluppgifter och lösenord) till en fil som lagras i användarprofilmappen för roaming eller en plats som anges av administratören i principen <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Molnsynkronisering inaktiveras när principen aktiveras. - - Om den här principen är inaktiverad eller utan värde används endast vanliga lokala profiler. - - Principen <ph name="SYNC_DISABLED_POLICY_NAME" /> inaktiverar all synkronisering av data och åsidosätter RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Filtrera bort webbplatser på toppnivå (men inte inbäddade iframe) med barnförbjudet innehåll</translation> <translation id="6734521799274931721">Styr om Network File Share är tillgängligt i Chrome OS</translation> <translation id="6735701345096330595">Aktivera alltid språk för stavningskontroll</translation>
diff --git a/components/policy/resources/policy_templates_sw.xtb b/components/policy/resources/policy_templates_sw.xtb index bb72792..17531d4 100644 --- a/components/policy/resources/policy_templates_sw.xtb +++ b/components/policy/resources/policy_templates_sw.xtb
@@ -2148,11 +2148,6 @@ <translation id="6689792153960219308">Ripoti hali ya maunzi</translation> <translation id="6698632841807204978">Ruhusu uchapishaji wa rangi nyeusi na nyeupe</translation> <translation id="6699880231565102694">Wezesha uthibitishaji wa vipengee viwili kwa wapangishaji wa ufikivu wa mbali</translation> -<translation id="6724842112053619797">Ukiiwasha mipangilio hii, mipangilio iliyohifadhiwa kwenye wasifu wa <ph name="PRODUCT_NAME" /> kama vile alamisho, data ya kujaza kiotomatiki, manenosiri, n.k. pia vitaandikwa kwenye faili iliyohifadhiwa kwenye folda ya wasifu wa mtumiaji mwingine au kwenye eneo lililobainishwa na Msimamizi kupitia sera ya <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Ukiiwasha sera hii, usawazishaji kwenye wingu utazimwa. - - Ukiizima sera hii au usipoweka mipangilio, wasifu wa kawaida kwenye kifaa chako ndio utakaotumika pekee. - - Sera ya <ph name="SYNC_DISABLED_POLICY_NAME" /> huzima usawazishaji wote wa data, hivyo kubatilisha RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Chuja tovuti maarufu (lakini si iframes zinazopachikwa) zinazoonyesha maudhui ya watu wazima</translation> <translation id="6734521799274931721">Hudhibiti Faili za Kushiriki katika Mtandao kwa ajili ya upatikanaji wa ChromeOS</translation> <translation id="6735701345096330595">Lazimisha kuwasha sera ya kikagua tahajia</translation>
diff --git a/components/policy/resources/policy_templates_ta.xtb b/components/policy/resources/policy_templates_ta.xtb index a4f78527..382eed9 100644 --- a/components/policy/resources/policy_templates_ta.xtb +++ b/components/policy/resources/policy_templates_ta.xtb
@@ -114,7 +114,7 @@ கொள்கை அமைக்கப்படாவிட்டால், அல்லது false என அமைக்கப்பட்டால், TLS இல் உள்ள சைஃபர் பொதிகள் இயக்கப்படாது. அல்லது காலாவதியான சேவையகத்துடனான இணக்கத்தன்மையைத் தொடர அது true என அமைக்கப்படலாம். இது ஒரு இடைக்கால நடவடிக்கையாகும், சேவையகம் மீண்டும் உள்ளமைக்கப்பட வேண்டும்.</translation> <translation id="1297117713060236551">உலாவி மாற்றத்தை ஒருபோதும் தூண்டாத இணையதளங்களின் பட்டியலை இந்தக் கொள்கை கட்டுப்படுத்துகிறது. - <ph name="USE_IE_SITELIST_POLICY_NAME" /> கொள்கை மூலமும் இந்தப் பட்டியலில் உறுப்புகளைச் சேர்க்கலாம் என்பதைக் குறித்துக்கொள்ளவும். + <ph name="USE_IE_SITELIST_POLICY_NAME" /> கொள்கை மூலமும் இந்தப் பட்டியலில் உறுப்புகளைச் சேர்க்கலாம் என்பதை கவனத்தில் கொள்ளவும். இந்தக் கொள்கை அமைக்காமல் விடப்பட்டால், பட்டியலில் இணையதளங்கள் எதுவும் சேர்க்கப்படாது. @@ -2131,11 +2131,6 @@ <translation id="6689792153960219308">வன்பொருள் நிலையை அறிவிக்கும்</translation> <translation id="6698632841807204978">மோனோகுரோம் அச்சிடலை இயக்கு</translation> <translation id="6699880231565102694">தொலைநிலை அணுகல் ஹோஸ்ட்களின் இரு-காரணி அங்கீகாரத்தைச் செயல்படுத்து</translation> -<translation id="6724842112053619797">இந்த அமைப்பை இயக்கினால், <ph name="PRODUCT_NAME" /> கணக்குகளில் சேமிக்கப்பட்ட புக்மார்க்குகள், தன்னிரப்பித் தரவு, கடவுச்சொற்கள் போன்ற பல அமைப்புகளும், ரோமிங் பயனர் கனக்குக் கோப்புறையில் சேமிக்கப்பட்ட கோப்பிலோ, <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> கொள்கை மூலம் நிர்வாகி குறிப்பிட்ட இடத்திலோ எழுதப்படும். இந்தக் கொள்கையை இயக்கினால், கிளவுட் ஒத்திசைவு முடக்கப்படும். - - இந்தக் கொள்கை முடக்கப்பட்டாலோ அமைக்கப்படவில்லை என்றாலோ, வழக்கமான அகக் கணக்குகள் மட்டுமே பயன்படுத்தப்படும். - - <ph name="SYNC_DISABLED_POLICY_NAME" /> கொள்கை RoamingProfileSupportEnabledஐ மீறிச் செயல்பட்டு, எல்லா தரவு ஒத்திசைவையும் முடக்கும்.</translation> <translation id="6731757988219967594">வயதுவந்தோர் உள்ளடக்கத்திற்குப் பிரபலமான தளங்களை (உட்பொதிக்கப்பட்ட iframesஸை வடிகட்டாது) வடிகட்டு</translation> <translation id="6734521799274931721">ChromeOSஸின் கிடைக்கும்நிலைக்கான ‘நெட்வொர்க் கோப்புப் பகிர்வுகள்’ அம்சத்தைக் கட்டுப்படுத்தும்</translation> <translation id="6735701345096330595">மொழிகளுக்கான எழுத்துச்சரிபார்ப்பைக் கட்டாயப்படுத்தி இயக்கு</translation> @@ -2217,12 +2212,12 @@ <ph name="PRODUCT_NAME" /> தொடங்கும்போது பயன்படுத்தப்பட வேண்டிய கொடிகளைக் குறிப்பிடுகிறது. குறிப்பிட்ட கொடிகள், உள்நுழைவுத் திரையில் மட்டுமே பயன்படுத்தப்படும். இந்தக் கொள்கை மூலம் அமைக்கப்படும் கொடிகள், பயனர் அமர்வுகளில் செயல்படாது.</translation> <translation id="685769593149966548">YouTube இல் கண்டிப்புக் கட்டுப்பாட்டுப் பயன்முறையைக் கட்டாயப்படுத்து</translation> -<translation id="6857824281777105940">இந்தக் கொள்கை, ‘பாதுகாப்பு உலாவல்’ எச்சரிக்கை, பாதுகாப்பு உலாவல் எச்சரிக்கை கிளிக்குகளின் எண்ணிக்கை உள்ளிட்ட ‘பாதுகாப்பு உலாவல்’ குறித்த தகவல்களை அறிக்கையளிப்பதா என்பதைக் கட்டுப்படுத்துகிறது. +<translation id="6857824281777105940">இந்தக் கொள்கை, ‘பாதுகாப்பு உலாவல்’ எச்சரிக்கை, பாதுகாப்பு உலாவல் எச்சரிக்கை கிளிக்குகளின் எண்ணிக்கை உள்ளிட்ட ‘பாதுகாப்பு உலாவல்’ குறித்த தகவல்களை புகாரளிப்பதா என்பதைக் கட்டுப்படுத்துகிறது. இந்தக் கொள்கை அமைக்காமல் விடப்பட்டாலோ ‘சரி’ என அமைக்கப்பட்டாலோ, ‘பாதுகாப்பு உலாவல்’ குறித்த தரவு சேகரிக்கப்படும். இந்தக் கொள்கை ‘தவறு’ என அமைக்கப்பட்டால், ‘பாதுகாப்பு உலாவல்’ குறித்த தரவு சேகரிக்கப்படாது. - <ph name="CHROME_REPORTING_EXTENSION_NAME" /> இயக்கப்பட்டிருக்கும்போதும் <ph name="MACHINE_LEVEL_USER_CLOUD_POLICY_ENROLLMENT_TOKEN_POLICY_NAME" /> இல் சாதனம் பதிவுசெய்யப்பட்டிருந்தாலும் மட்டுமே இந்தக் கொள்கை செல்லுபடியாகும்.</translation> + <ph name="CHROME_REPORTING_EXTENSION_NAME" /> இயக்கப்பட்டிருக்கும்போதும் <ph name="MACHINE_LEVEL_USER_CLOUD_POLICY_ENROLLMENT_TOKEN_POLICY_NAME" /> இல் சாதனம் பதிவுசெய்யப்பட்டிருக்கும்போதும் மட்டுமே இந்தக் கொள்கை செல்லுபடியாகும்.</translation> <translation id="686079137349561371">Microsoft Windows 7 அல்லது அதற்குப் பிந்தைய பதிப்பு</translation> <translation id="687046793986382807">இந்தக் கொள்கையானது <ph name="PRODUCT_NAME" /> பதிப்பு 35 இல் முடிந்தது. @@ -2367,7 +2362,7 @@ <translation id="7132877481099023201">அறிவுறுத்தல் இல்லாமல் வீடியோ படமெடுப்புச் சாதனங்களுக்கு அணுகல் வழங்கப்படும் URLகள்.</translation> <translation id="7158064522994309072">மாற்று உலாவியில் URLகளைத் திறப்பதற்கு எந்தக் கட்டளையைப் பயன்படுத்துவது என்பதை இந்தக் கொள்கை கட்டுப்படுத்துகிறது. - இந்தக் கொள்கை அமைக்காமல் விடப்பட்டால், இயங்குதளம் சார்ந்த இயல்பு உலாவி பயன்படுத்தப்படும்: Windowsஸுக்கு Internet Explorer அல்லது Mac OS Xஸுக்கு Safari. Linuxஸில், இந்தக் கொள்கை அமைக்காமல் விடப்பட்டால் மாற்று உலாவி தொடங்கப்படாது. + இந்தக் கொள்கை அமைக்காமல் விடப்பட்டால், இயங்குதளம் சார்ந்த இயல்பு உலாவி பயன்படுத்தப்படும்: Windowsஸில் Internet Explorer அல்லது Mac OS Xஸில் Safari. Linuxஸில், இந்தக் கொள்கை அமைக்காமல் விடப்பட்டால் மாற்று உலாவி தொடங்கப்படாது. ${ie}, ${firefox}, ${safari} அல்லது ${opera} ஆகியவற்றில் ஏதேனும் ஒரு மதிப்புக்கு இந்தக் கொள்கை அமைக்கப்பட்டால், அந்த உலாவி நிறுவப்பட்டிருந்தால் அது தொடங்கப்படும். ${ie} என்பது Windowsஸில் மட்டுமே கிடைக்கும், ${safari} என்பது Windows மற்றும் Mac OS Xஸில் மட்டுமே கிடைக்கும். @@ -2887,11 +2882,11 @@ <translation id="8390049129576938611"><ph name="PRODUCT_NAME" /> இல் அக PDF வியூவரை முடக்கும். அதற்குப் பதிலாக, அதைப் பதிவிறக்கமாகக் கருதி, இயல்புப் பயன்பாட்டில் PDF கோப்புகளைத் திறக்க பயனரை அனுமதிக்கும். இந்தக் கொள்கை அமைக்கப்படவில்லை என்றாலோ அல்லது முடக்கப்பட்டிருந்தாலோ, பயனர் முடக்கும் வரை PDF கோப்புகளைத் திறக்க PDF செருகுநிரல் பயன்படுத்தப்படும்.</translation> -<translation id="8396145449084377015">Internet Explorerரின் SiteList கொள்கையிலிருந்து விதிகளை ஏற்றுவதா என்பதை இந்தக் கொள்கை கட்டுப்படுத்துகிறது. +<translation id="8396145449084377015">Internet Explorerரின் SiteList கொள்கையிலிருந்து விதிகளை பின்பற்றுவதா என்பதை இந்தக் கொள்கை கட்டுப்படுத்துகிறது. இந்தக் கொள்கை அமைக்காமல் விடப்பட்டாலோ ‘தவறு’ என அமைக்கப்பட்டாலோ, உலாவிகளை மாற்றுவதற்கான விதிகளின் ஆதாரமாக Internet Explorerரின் <ph name="IEEM_SITELIST_POLICY" /> கொள்கையை <ph name="PRODUCT_NAME" /> பயன்படுத்தாது. - இந்தக் கொள்கை ‘சரி’ என அமைக்கப்பட்டால், தளப் பட்டியலின் URLலைப் பெறுவதற்கு <ph name="PRODUCT_NAME" /> Internet Explorerரின் <ph name="IEEM_SITELIST_POLICY" />ஐப் படிக்கும். அதன் பின்னர் <ph name="PRODUCT_NAME" /> அந்த URLலில் இருந்து தளப் பட்டியலைப் பதிவிறக்கி, அவை <ph name="SITELIST_POLICY_NAME" /> கொள்கை மூலம் உள்ளமைக்கப்பட்டதைப் போல விதிகளைப் பயன்படுத்தும். + இந்தக் கொள்கை ‘சரி’ என அமைக்கப்பட்டால், தளப் பட்டியலின் URLலைப் பெறுவதற்கு <ph name="PRODUCT_NAME" /> Internet Explorerரின் <ph name="IEEM_SITELIST_POLICY" />ஐப் பயன்படுத்தும். அதன் பின்னர் <ph name="PRODUCT_NAME" /> அந்த URLலில் இருந்து தளப் பட்டியலைப் பதிவிறக்கி, அவை <ph name="SITELIST_POLICY_NAME" /> கொள்கை மூலம் உள்ளமைக்கப்பட்டதைப் போல விதிகளைப் பயன்படுத்தும். Internet Explorerரின் <ph name="IEEM_SITELIST_POLICY" /> கொள்கையைப் பற்றிய மேலும் தகவல்கள் இங்கே உள்ளன: https://docs.microsoft.com/internet-explorer/ie11-deploy-guide/what-is-enterprise-mode</translation> <translation id="8402079500086185021">எப்போதும் PDF கோப்புகளை பிற பயன்பாடுகளில் திற</translation> @@ -3187,7 +3182,7 @@ <translation id="9042911395677044526"><ph name="PRODUCT_OS_NAME" /> சாதனத்தில் பயன்படுத்துவதற்கு ஒவ்வொரு பயனருக்குமாக நெட்வொர்க் உள்ளமைவை வழங்க அனுமதிக்கிறது. நெட்வொர்க் உள்ளமைவு என்பது <ph name="ONC_SPEC_URL" /> இல் விளக்கப்பட்டுள்ளபடி திறந்த நெட்வொர்க் உள்ளமைவு வடிவத்தால் வரையறுக்கப்பட்ட JSON-வடிவமைப்புத் தொடர் ஆகும்.</translation> <translation id="906631898352326790"> இந்தக் கொள்கை இயக்கப்பட்டிருந்தால், காற்புள்ளியால் பிரிக்கப்பட்ட பட்டியலில் குறிப்பிடப்பட்டுள்ள ஒவ்வொரு தளமும் அதற்குரிய செயல்முறையை இயக்கும். இது துணை டொமைன்களின்படியும் தளங்களைத் தனிப்படுத்தும். எ.கா. https://example.com/ எனக் குறிப்பிட்டால், https://example.com/ தளத்தின் ஒரு பகுதியாக https://foo.example.com/ எனும் தளமும் தனிப்படுத்தப்படும். - இந்தக் கொள்கை முடக்கப்பட்டிருந்தால், வெளிப்படையாகத் தளத்தைத் தனிப்படுத்தும் செயல்முறை எதுவும் நடக்காது. IsolateOrigins, SitePerProcess ஆகியவற்றின் அம்சங்கள் முடக்கப்படும். அப்போதும் பயனர்களால் கட்டளை வரிக் கொடிகள் மூலம் IsolateOriginsஸை நேரடியாக இயக்க முடியும். + இந்தக் கொள்கை முடக்கப்பட்டிருந்தால், IsolateOrigins, SitePerProcess ஆகியவற்றின் அம்சங்கள் முடக்கப்படும். அப்போதும் பயனர்களால் கட்டளை வரிக் கொடிகள் மூலம் IsolateOriginsஸை நேரடியாக இயக்க முடியும். இந்தக் கொள்கை உள்ளமைக்கப்படவில்லை என்றால், பயனரால் இந்த அமைப்பை மாற்ற முடியும். <ph name="PRODUCT_OS_NAME" /> இல், <ph name="DEVICE_LOGIN_SCREEN_ISOLATE_ORIGINS_POLICY_NAME" /> இன் சாதனக் கொள்கைக்கும் அதே மதிப்பை அமைக்குமாறு பரிந்துரைக்கப்படுகிறது. இரு கொள்கைகளும் குறிப்பிடும் மதிப்புகள் பொருந்தவில்லை என்றால், பயனர் கொள்கையால் குறிப்பிடப்படும் மதிப்பு பயன்படுத்தப்படும், இதனால் பயனர் அமர்வில் உள்நுழையும்போது தாமதம் ஏற்படக்கூடும்.
diff --git a/components/policy/resources/policy_templates_te.xtb b/components/policy/resources/policy_templates_te.xtb index 0b912ee..d0ed378 100644 --- a/components/policy/resources/policy_templates_te.xtb +++ b/components/policy/resources/policy_templates_te.xtb
@@ -272,7 +272,7 @@ <translation id="1559980755219453326">ఈ విధానం ఎక్స్టెన్షన్లు మరియు ప్లగిన్లకు సంబంధించిన వివరాలను తెలపాలో లేదో నిర్ణయిస్తుంది. ఈ విధానాన్ని సెట్ చేయకుండా వదిలిపెట్టినప్పుడు లేదా ఒప్పుకు సెట్ చేసినప్పుడు, ఎక్స్టెన్షన్లు మరియు ప్లగిన్లకు సంబంధించిన వివరాలు సేకరించబడతాయి. - ఒకవేళ ఈ విధానాన్ని తప్పుకు సెట్ చేసినప్పుడు, ఎక్స్టెన్షన్లు మరియు ప్లగిన్ల`కు సంబంధించిన వివరాలు సేకరించబడవు. + ఒకవేళ ఈ విధానాన్ని తప్పుకు సెట్ చేసినప్పుడు, ఎక్స్టెన్షన్లు మరియు ప్లగిన్లకు సంబంధించిన వివరాలు సేకరించబడవు. ఈ విధానం <ph name="CHROME_REPORTING_EXTENSION_NAME" />ని ప్రారంభించినప్పుడు, అలాగే మెషీన్ని <ph name="MACHINE_LEVEL_USER_CLOUD_POLICY_ENROLLMENT_TOKEN_POLICY_NAME" />తో ప్రారంభించినప్పుడు మాత్రమే వర్తిస్తుంది.</translation> <translation id="1561424797596341174">విధానం రిమోట్ ప్రాప్యత హోస్ట్ యొక్క డీబగ్ బిల్డ్ల కోసం భర్తీ చేస్తుంది</translation> @@ -310,7 +310,7 @@ హెచ్చరిక: సాఫ్ట్వేర్ నవీకరణలు మరియు కీలకమైన భద్రతా పరిష్కారాలను పొందనివ్వకుండా పరికరాన్ని నిరోధిస్తుంది, కనుక <ph name="PRODUCT_OS_NAME" /> సంస్కరణ యొక్క నియంత్రణ అధికారాన్ని కియోస్క్ అనువర్తనానికి కేటాయించడం సమర్థనీయం కాదు. <ph name="PRODUCT_OS_NAME" /> సంస్కరణకు నియంత్రణ అధికారాన్ని కేటాయించడం వినియోగదారులను ఇబ్బందులకు గురిచేయవచ్చు.</translation> <translation id="1675002386741412210">లో మద్దతిస్తుంది:</translation> -<translation id="1689963000958717134"><ph name="PRODUCT_OS_NAME" /> పరికరం యొక్క మొత్తం వినియోగదారుల కోసం వర్తించడానికి నెట్వర్క్ కాన్ఫిగరేషన్ను అందిండానికి అనుమతిస్తుంది. నెట్వర్క్ కాన్ఫిగరేషన్ అనేది <ph name="ONC_SPEC_URL" />లో వివరించిన విధంగా ఓపెన్ నెట్వర్క్ కాన్ఫిగరేషన్ ఆకృతి ద్వారా నిర్వచించిన JSON-ఆకృతీకరణ స్ట్రింగ్</translation> +<translation id="1689963000958717134"><ph name="PRODUCT_OS_NAME" /> పరికరం యొక్క మొత్తం వినియోగదారులకు వర్తించేలా నెట్వర్క్ కాన్ఫిగరేషన్ను అందించడానికి అనుమతిస్తుంది. నెట్వర్క్ కాన్ఫిగరేషన్ అనేది <ph name="ONC_SPEC_URL" />లో వివరించిన విధంగా ఓపెన్ నెట్వర్క్ కాన్ఫిగరేషన్ ఆకృతి ద్వారా నిర్వచించిన JSON-ఆకృతీకరణ స్ట్రింగ్</translation> <translation id="1708496595873025510">వ్యత్యాసాల సీడ్ను పొందడంలో పరిమితిని సెట్ చేయండి</translation> <translation id="172374442286684480">స్థానిక డేటాని సెట్ చేయడానికి అన్ని సైట్లను అనుమతించడం</translation> <translation id="1734716591049455502">రిమోట్ ప్రాప్యత ఎంపికలను కాన్ఫిగర్ చేయండి</translation> @@ -466,7 +466,7 @@ మీరు ఈ సెట్టింగ్ను నిలిపివేస్తే, వెతకడానికి నొక్కండి ఫీచర్ పూర్తిగా నిలిపివేయబడుతుంది. ఈ విధానాన్ని సెట్ చేయకుండా వదిలేస్తే, దాన్ని ప్రారంభించి ఉండటంతో సమానం, ఎగువ వివరణను చూడండి.</translation> -<translation id="2113068765175018713">స్వయంచాలకంగా రీబూట్ చేయడం ద్వారా పరికరం యొక్క గరిష్ట సమయాన్ని పరిమితం చేయండి</translation> +<translation id="2113068765175018713">ఆటోమేటిక్ రీబూట్ పెట్టడం ద్వారా పరికరం పని చేసే సమయాన్ని పరిమితం చేయండి</translation> <translation id="2116790137063002724">వినియోగదారులను గుర్తించడానికి ఉపయోగించగల OS లాగిన్, <ph name="PRODUCT_NAME" /> ప్రొఫైల్ లాగిన్, <ph name="PRODUCT_NAME" /> ప్రొఫైల్ పేరు, <ph name="PRODUCT_NAME" /> ప్రొఫైల్ పాత్ మరియు <ph name="PRODUCT_NAME" /> అమలు చేయగలిగే పాత్ లాంటి సమాచారాన్ని నివేదించాలో లేదో ఈ విధానం నియంత్రిస్తుంది. ఈ విధానాన్ని సెట్ చేయకుండా వదిలివేస్తే లేదా ఒప్పుకు సెట్ చేస్తే, వినియోగదారులను గుర్తించడానికి ఉపయోగించగల సమాచారం సేకరించబడుతుంది. @@ -562,7 +562,7 @@ <translation id="2214880135980649323">ఈ విధానాన్ని ప్రారంభించేలా సెట్ చేసినప్పుడు, ఎంటర్ప్రైజ్ హార్డ్వేర్ ప్లాట్ఫామ్ APIని ఉపయోగించేందుకు, ఎంటర్ప్రైజ్ విధానం ద్వారా ఇన్స్టాల్ చేయబడిన ఎక్స్టెన్షన్లు అనుమతించబడతాయి. ఈ విధానాన్ని నిలిపివేసేలా సెట్ చేస్తే లేదా సెట్ చేయకపోతే, ఎంటర్ప్రైజ్ హార్డ్వేర్ ప్లాట్ఫామ్ APIని ఉపయోగించేందుకు ఎక్స్టెన్షన్లు ఏవీ అనుమతించబడవు. ఈ విధానం Hangout సేవల ఎక్స్టెన్షన్ లాంటి అంతర్భాగ ఎక్స్టెన్షన్లకు కూడా వర్తిస్తుంది.</translation> -<translation id="2223598546285729819">డిఫాల్ట్ ప్రకటన సెట్టింగ్</translation> +<translation id="2223598546285729819">డిఫాల్ట్ నోటిఫికేషన్ సెట్టింగ్</translation> <translation id="2231817271680715693">మొదటి అమలులోనే డిఫాల్ట్ బ్రౌజర్ నుండి బ్రౌజింగ్ చరిత్రను దిగుమతి చేయి</translation> <translation id="2236488539271255289">స్థానిక డేటాని సెట్ చెయ్యడానికి ఏ సైట్ని అనుమతించవద్దు</translation> <translation id="2240879329269430151">వెబ్సైట్లు పాప్-అప్లు చూపడానికి అనుమతించాలో, లేదో అని సెట్ చేయడానికి మిమ్మల్ని అనుమతిస్తుంది. పాప్అప్లను ప్రదర్శించడానికి అన్ని వెబ్సైట్లను అనుమతించవచ్చు లేదా నిరాకరించవచ్చు. ఈ విధానం సెట్ చేయకుండా వదిలివేస్తే, 'BlockPopups' ఉపయోగించబడుతుంది మరియు దీన్ని వినియోగదారు మార్పుచేయగలుగుతారు.</translation> @@ -801,13 +801,13 @@ విధానాన్ని తప్పు అని సెట్ చేసినట్లయితే, వినియోగదారులు తమ స్వంత స్థానిక ప్రింటర్లను జోడించలేరు మరియు కాన్ఫిగర్ చేయలేరు. మునుపు కాన్ఫిగర్ చేయబడిన స్థానిక ప్రింటర్లు వేటినైనా ఉపయోగించి కూడా వారు ముద్రించలేరు. </translation> <translation id="2805707493867224476">పాప్-అప్లను చూపించడానికి అన్ని సైట్లను అనుమతించు</translation> -<translation id="2808013382476173118">రిమోట్ క్లయింట్లు ఈ మెషీన్కి కనెక్షన్ను ఏర్పాటు చేయడానికి ప్రయత్నిస్తున్నప్పుడు STUN సర్వర్ల వినియోగాన్ని ప్రారంభిస్తుంది. +<translation id="2808013382476173118">ఈ మెషిన్తో కనెక్షన్ ఏర్పాటు చేయడానికి రిమోట్ క్లయింట్లు ప్రయత్నిస్తున్నప్పుడు STUN సర్వర్ల వినియోగాన్ని ప్రారంభిస్తుంది. - ఈ సెట్టింగ్ ప్రారంభించబడితే, అప్పుడు ఈ మెషీన్లు ఫైర్వాల్ ద్వారా వేరు చేయబడినప్పటికీ రిమోట్ క్లయింట్లు వాటిని గుర్తించగలుగుతాయి మరియు వాటికి కనెక్ట్ అవుతాయి. + ఈ సెట్టింగ్ ప్రారంభించినట్లయితే, ఈ మెషిన్లు ఫైర్వాల్ ద్వారా వేరు అయినా కూడా రిమోట్ క్లయింట్లు వాటిని గుర్తించగలుగుతాయి, వాటికి కనెక్ట్ అవుతాయి. - ఈ సెట్టింగ్ నిలిపివేయబడితే మరియు అవుట్గోయింగ్ UDP కనెక్షన్లు ఫైర్వాల్ ద్వారా ఫిల్టర్ చేయబడితే, అప్పుడు ఈ మెషీన్ స్థానిక నెట్వర్క్లోని క్లయింట్ మెషీన్ల నుండి మాత్రమే కనెక్షన్లను అనుమతిస్తుంది. + ఈ సెట్టింగ్ నిలిపివేసినట్లయితే, అవుట్గోయింగ్ UDP కనెక్షన్లు ఫైర్వాల్ ద్వారా ఫిల్టర్ అయినట్లయితే, అప్పుడు ఈ మెషిన్ స్థానిక నెట్వర్క్లోని క్లయింట్ మెషిన్ల నుండి మాత్రమే కనెక్షన్లను అనుమతిస్తుంది. - ఈ విధానాన్ని సెట్ చేయకుండా వదిలేస్తే, సెట్టింగ్ ప్రారంభించబడుతుంది.</translation> + ఈ విధానాన్ని సెట్ చేయకుండా వదిలేస్తే, సెట్టింగ్ ప్రారంభమవుతుంది.</translation> <translation id="2823870601012066791"><ph name="PRODUCT_OS_NAME" /> క్లయింట్ల కోసం Windows రిజిస్ట్రీ స్థానం:</translation> <translation id="2824715612115726353">అజ్ఞాత మోడ్ని ప్రారంభించు</translation> <translation id="283695852388224413">విధానం సెట్ చేయబడితే, కాన్ఫిగర్ చేయబడిన PIN యొక్క గరిష్ట అంకెల పరిమితి అమలు చేయబడుతుంది. విలువ 0 లేదా తక్కువ ఉంటే గరిష్ట అంకెల పరిమితి ఉండదు; ఆ సందర్భంలో వినియోగదారు ఎంత పొడవాటి PINని అయినా సెట్ చేసుకోవచ్చు. ఈ సెట్టింగ్ <ph name="PIN_UNLOCK_MINIMUM_LENGTH_POLICY_NAME" /> కంటే తక్కువ ఉండి, 0 కంటే పెద్దది అయితే, గరిష్ట అంకెల పరిమితి కనిష్ట అంకెల పరిమితికి సమానంగా ఉంటుంది. @@ -1091,8 +1091,7 @@ ఈ విధానాన్ని 'PasswordProtectionWarningOff'కి సెట్ చేసినట్లయితే, పాస్వర్డ్ రక్షణ హెచ్చరిక చూపబడదు. ఈ విధానాన్ని 'PasswordProtectionWarningOnPasswordReuse'కి సెట్ చేసినట్లయితే, వినియోగదారులు తమ సురక్షిత పాస్వర్డ్ని వైట్లిస్ట్లో లేని సైట్లో మళ్లీ వినియోగించినప్పుడు పాస్వర్డ్ రక్షణ హెచ్చరిక చూపబడుతుంది. - ఈ విధానాన్ని 'PasswordProtectionWarningOnPhishingReuse'కి సెట్ చేసినట్లయితే, వినియోగదారులు తమ రక్షిత పాస్వర్డ్ని ఫిషింగ్ సైట్లో మళ్లీ ఉపయోగించినప్పుడు పాస్వర్డ్ రక్షణ హెచ్చరిక చూపబడుతుంది. - ఈ విధానాన్ని సెట్ చేయకుంటే, పాస్వర్డ్ రక్షణ సేవ Google పాస్వర్డ్లను మాత్రమే కాపాడుతుంది, కానీ వినియోగదారు ఈ సెట్టింగ్ని మార్చగలుగుతారు.</translation> + ఈ విధానాన్ని 'PasswordProtectionWarningOnPhishingReuse'కి సెట్ చేసినట్లయితే, వినియోగదారులు తమ రక్షిత పాస్వర్డ్ని ఫిషింగ్ సైట్లో మళ్లీ ఉపయోగించినప్పుడు పాస్వర్డ్ రక్షణ హెచ్చరిక చూపబడుతుంది. ఈ విధానాన్ని సెట్ చేయకుంటే, పాస్వర్డ్ రక్షణ సేవ Google పాస్వర్డ్లను మాత్రమే కాపాడుతుంది, కానీ వినియోగదారు ఈ సెట్టింగ్ని మార్చగలుగుతారు.</translation> <translation id="3502555714327823858">అన్ని డూప్లెక్స్ మోడ్లను అనుమతించండి</translation> <translation id="350443680860256679">ARCని కాన్ఫిగర్ చేయండి</translation> <translation id="3504791027627803580">చిత్ర శోధనను అందించడానికి ఉపయోగించే శోధన ఇంజిన్ యొక్క URLని పేర్కొంటుంది. శోధన అభ్యర్థనలు GET పద్ధతిని ఉపయోగించి పంపబడతాయి. DefaultSearchProviderImageURLPostParams విధానాన్ని సెట్ చేస్తే అప్పుడు చిత్ర శోధన అభ్యర్థనలు బదులుగా POST పద్ధతిని ఉపయోగిస్తాయి. @@ -1310,8 +1309,8 @@ <translation id="3939893074578116847">పరికరం ఆఫ్లైన్లో ఉంటే గుర్తించేందుకు సర్వర్ను అనుమతించడానికి, ఆన్లైన్ స్థితిని పర్యవేక్షించడం కోసం నెట్వర్క్ ప్యాకెట్లను నిర్వహణ సర్వర్కు పంపుతుంది. - ఈ విధానాన్ని ఒప్పుకి సెట్ చేస్తే, పర్యవేక్షిత నెట్వర్క్ ప్యాకెట్లు (<ph name="HEARTBEATS_TERM" />గా పిలిచేవి) పంపబడతాయి. - తప్పుకి సెట్ చేస్తే లేదా సెట్ చేయకుండా ఉంటే, ప్యాకెట్లు ఏవీ పంపబడవు.</translation> + ఈ విధానాన్ని ఒప్పునకు సెట్ చేస్తే, పర్యవేక్షిత నెట్వర్క్ ప్యాకెట్లు (<ph name="HEARTBEATS_TERM" />గా పిలిచేవి) పంపబడతాయి. + తప్పునకు సెట్ చేస్తే లేదా సెట్ చేయకుండా ఉంటే, ప్యాకెట్లు ఏవీ పంపబడవు.</translation> <translation id="3950239119790560549">సమయ పరిమితులను అప్డేట్ చేయండి</translation> <translation id="3956686688560604829">లెగసీ బ్రౌజర్ మద్దతు కోసం Internet Explorer యొక్క SiteList విధానాన్ని ఉపయోగించడం.</translation> <translation id="3957134519352019843">డిఫాల్ట్ శోధన ప్రదాత వినియోగాన్ని ప్రారంభిస్తుంది. @@ -1422,19 +1421,19 @@ RemoteAccessHostDomainListని కూడా చూడండి.</translation> <translation id="4183229833636799228">డిఫాల్ట్ <ph name="FLASH_PLUGIN_NAME" /> సెట్టింగ్</translation> <translation id="4192388905594723944">రిమోట్ యాక్సెస్ క్లయింట్ ప్రమాణీకరణ టోకెన్ని ధృవీకరించే URL</translation> -<translation id="4203389617541558220">స్వయంచాలక రీబూట్లను షెడ్యూల్ చేయడం ద్వారా పరికరం యొక్క లభ్యతను పరిమితం చేయండి. +<translation id="4203389617541558220">ఆటోమేటిక్ రీబూట్లను షెడ్యూల్ చేయడం ద్వారా పరికరం లభ్యతను పరిమితం చేయండి. - ఈ విధానాన్ని సెట్ చేసినప్పుడు, ఇది స్వయంచాలక రీబూట్ షెడ్యూల్ చేయబడిన తర్వాత పరికరం యొక్క లభ్యత నిడివిని నిర్దేశిస్తుంది. + ఈ విధానాన్ని సెట్ చేసినప్పుడు, ఇది ఆటోమేటిక్ రీబూట్ షెడ్యూల్ చేయబడిన తర్వాత పరికరం లభ్యత నిడివిని నిర్దేశిస్తుంది. - ఈ విధానాన్ని సెట్ చేయనప్పుడు, పరికరం యొక్క లభ్యత పరిమితం చేయబడదు. + ఈ విధానాన్ని సెట్ చేయనప్పుడు, పరికరం లభ్యత పరిమితం చేయబడదు. మీరు ఈ విధానాన్ని సెట్ చేస్తే, వినియోగదారులు దీన్ని మార్చలేరు లేదా భర్తీ చేయలేరు. - షెడ్యూల్ చేసిన సమయానికి స్వయంచాలక రీబూట్ షెడ్యూల్ చేయబడుతుంది కానీ ప్రస్తుతం వినియోగదారు పరికరాన్ని ఉపయోగిస్తుంటే పరికరంలో గరిష్టంగా 24 గంటల వరకు ఆలస్యం కావచ్చు. + షెడ్యూల్ చేసిన సమయానికి ఆటోమేటిక్ రీబూట్ షెడ్యూల్ చేయబడుతుంది. కానీ ప్రస్తుతం వినియోగదారు పరికరాన్ని ఉపయోగిస్తుంటే పరికరంలో గరిష్టంగా 24 గంటల వరకు ఆలస్యం కావచ్చు. - గమనిక: ప్రస్తుతం, స్వయంచాలక రీబూట్లు లాగిన్ స్క్రీన్ చూపబడుతున్నప్పుడు లేదా కియోస్క్ అనువర్తన సెషన్ పురోగమనంలో ఉన్నప్పుడు మాత్రమే ప్రారంభించబడతాయి. ఇది భవిష్యత్తులో మారుతుంది మరియు విధానం ఎల్లప్పుడూ వర్తింపజేయబడుతుంది, ఏదైనా నిర్దిష్ట సెషన్ రకం పురోగమనంలో ఉందా లేదా అన్న దానిపై ఆధాపర పడి ఉండదు. + గమనిక: ప్రస్తుతం, లాగిన్ స్క్రీన్ చూపబడుతున్నప్పుడు లేదా కియోస్క్ యాప్ సెషన్ పురోగమనంలో ఉన్నప్పుడు మాత్రమే ఆటోమేటిక్ రీబూట్లు ప్రారంభమవుతాయి. ఇది ఏదైనా నిర్దిష్ట సెషన్ రకం పురోగమనంలో ఉందా లేదా అన్న దానితో సంబంధం లేకుండా భవిష్యత్తులో మారుతుంది. విధానం ఎల్లప్పుడూ వర్తిస్తుంది. - విధానం విలువను సెకన్లలో పేర్కొనాలి. విలువలు కనీసం 3600 (ఒక గంట)గా పరిమితి చేయబడ్డాయి.</translation> + విధానం విలువను సెకన్లలో పేర్కొనాలి. విలువలు కనీసం 3600 (ఒక గంట)గా పరిమితం చేయబడ్డాయి.</translation> <translation id="4203879074082863035">వైట్లిస్ట్లో ఉన్న ప్రింటర్లు మాత్రమే వినియోగదారులకు చూపబడతాయి</translation> <translation id="420512303455129789">హోస్ట్కు ప్రాప్యత అనుమతించాలో (ఒప్పు) లేదా బ్లాక్ చేయాలో (తప్పు) పేర్కొనే బులియన్ ఫ్లాగ్కు URLలను మ్యాప్ చేసే నిఘంటువు. @@ -1742,7 +1741,7 @@ ఉండాలి, $URL_PATTERN అనేది కంటెంట్ సెట్టింగ్ నమూనా. $FILTER బ్రౌజర్ ఆటోమేటిక్గా ఎంచుకునే క్లయింట్ సర్టిఫికెట్లను నియంత్రిస్తుంది. ఫిల్టర్తో సంబంధం లేకుండా, సర్వర్ సర్టిఫికెట్ అభ్యర్థనకు సరిపోలే సర్టిఫికెట్లు మాత్రమే ఎంచుకోబడతాయి. $FILTER { "ISSUER": { "CN": "$ISSUER_CN" } } ఫార్మాట్లో ఉంటే, అదనంగా CommonName $ISSUER_CNతో సర్టిఫికెట్ ద్వారా మంజూరు చేయబడిన క్లయింట్ సర్టిఫికెట్లు మాత్రమే ఎంచుకోబడతాయి. $FILTER ఖాళీ నిఘంటువు {} అయితే, క్లయింట్ సర్టిఫికెట్ల ఎంపిక అదనంగా నియంత్రించబడదు. ఈ విధానాన్ని సెట్ చేయకుండా వదిలేస్తే, ఏ సైట్ కోసం స్వీయ ఎంపిక చేయబడదు.</translation> -<translation id="4978405676361550165">"OffHours" విధానాన్ని సెట్ చేసినట్లయితే, పేర్కొనబడిన సమయ వ్యవధులలో పేర్కొనబడిన పరికర విధానాలు విస్మరించబడతాయి (ఈ విధానాల డిఫాల్ట్ సెట్టింగ్లు ఉపయోగించబడతాయి). "OffHours" ప్రారంభమైన లేదా ముగిసిన ప్రతిసారీ పరికర విధానాలను Chrome తిరిగి వర్తింపజేస్తుంది. "OffHours" సమయం ముగిసినప్పుడు మరియు పరికర విధాన సెట్టింగ్లు మార్చబడినప్పుడు (ఉదా., వినియోగదారు అనుమతి లేని ఖాతాతో సైన్ ఇన్ చేసినప్పుడు) వినియోగదారుకు తెలియజేయబడుతుంది మరియు నిర్బంధంగా సైన్ అవుట్ చేయాల్సి వస్తుంది.</translation> +<translation id="4978405676361550165">"OffHours" విధానాన్ని సెట్ చేసినట్లయితే, నిర్దేశించిన సమయ వ్యవధులలో నిర్దిష్ట పరికర విధానాలు విస్మరించబడతాయి (ఈ విధానాల డిఫాల్ట్ సెట్టింగ్లు ఉపయోగించబడతాయి). "OffHours" ప్రారంభమైన లేదా ముగిసిన ప్రతిసారీ పరికర విధానాలను Chrome తిరిగి వర్తింపజేస్తుంది. "OffHours" సమయం ముగిసినప్పుడు, పరికర విధాన సెట్టింగ్లు మార్చినప్పుడు ఆ విషయం వినియోగదారుకు తెలియజేయబడుతుంది. నిర్బంధంగా సైన్ అవుట్ చేసేలా చేస్తుంది (ఉదా., అనుమతి లేని ఖాతాతో వినియోగదారు సైన్ ఇన్ అయినప్పుడు).</translation> <translation id="4980635395568992380">డేటా రకం:</translation> <translation id="4983201894483989687">పాత ప్లగ్ఇన్లని అమలు చెయ్యడానికి అనుమతించు</translation> <translation id="4988291787868618635">నిష్క్రియ ఆలస్యం ఏర్పడినప్పుడు తీసుకోవలసిన చర్య</translation> @@ -1788,7 +1787,7 @@ ఈ విధానాన్ని సెట్ చేయకపోతే డిఫాల్ట్ ఆదేశ పంక్తి ఉపయోగించబడుతుంది.</translation> <translation id="5159469559091666409">పర్యవేక్షిత నెట్వర్క్ ప్యాకెట్లు పంపబడే సమయ వ్యవధి, మిల్లీసెకన్లలో ఉండాలి. - ఈ విధానాన్ని సెట్ చేయకుంటే, డిఫాల్ట్ సమయ వ్యవధి 3 నిమిషాలు ఉంటుంది. దీని కనీస సమయ వ్యవధి 30 సెకన్లు మరియు గరిష్ట సమయ వ్యవధి 24 గంటలు - ఈ పరిధిని విలువలు దాటితే నిర్బంధంగా ఈ పరిధిలోకి మార్చబడతాయి.</translation> + ఈ విధానాన్ని సెట్ చేయకుంటే, డిఫాల్ట్ సమయ వ్యవధి 3 నిమిషాలు ఉంటుంది. దీని కనీస సమయ వ్యవధి 30 సెకన్లు. గరిష్ట సమయ వ్యవధి 24 గంటలు. ఈ పరిధిని విలువలు దాటితే నిర్బంధంగా ఈ పరిధిలోకి మార్చబడతాయి.</translation> <translation id="5163002264923337812">పాత వెబ్-ఆధారిత సైన్ఇన్ విధానాన్ని ప్రారంభించండి</translation> <translation id="5182055907976889880"><ph name="PRODUCT_OS_NAME" />లో Google డిస్క్ని కాన్ఫిగర్ చేయండి.</translation> <translation id="5183383917553127163">ఆమోదంకానిజాబితాకి సంబంధించని పొడిగింపులని పేర్కొనడానికి మిమ్మల్ని అనుమతిస్తుంది. @@ -1995,7 +1994,7 @@ ఈ విధానాన్ని సెట్ చేయకుండా వదిలివేసినప్పుడు <ph name="PRODUCT_OS_NAME" /> 3 గంటల డిఫాల్ట్ విలువను ఉపయోగిస్తుంది. - ప్లాట్ఫారమ్ విధాన నోటిఫికేషన్లకు మద్దతు ఇచ్చే పక్షంలో, అత్యంత తరచుగా రిఫ్రెష్లు చేయడాన్ని నివారించడానికి రిఫ్రెష్ జాప్యం 24 గంటలకు సెట్ చేయబడుతుందని గమనించండి (ఈ సందర్భంలో అన్ని డిఫాల్ట్లు మరియు ఈ విధానం విలువ విస్మరించబడతాయి), ఎందుకంటే విధానంలో మార్పులు జరిగినప్పుడు విధాన నోటిఫికేషన్లు నిర్బంధంగా స్వయంచాలిత రిఫ్రెష్ చేయడానికి అవకాశం ఉంటుంది.</translation> + ప్లాట్ఫారమ్ విధాన నోటిఫికేషన్లకు మద్దతు ఇచ్చే పక్షంలో, అత్యంత తరచుగా రిఫ్రెష్లు చేయడాన్ని నివారించడానికి రిఫ్రెష్ జాప్యం 24 గంటలకు సెట్ చేయబడుతుందని గమనించండి (ఈ సందర్భంలో అన్ని డిఫాల్ట్లు, ఈ విధానం విలువ విస్మరించబడతాయి), ఎందుకంటే విధానంలో మార్పులు జరిగినప్పుడు విధాన నోటిఫికేషన్లు నిర్బంధంగా ఆటోమేటిక్ రిఫ్రెష్ చేయడానికి అవకాశం ఉంటుంది.</translation> <translation id="5530347722229944744">సంభావ్యంగా హానికరమైన డౌన్లోడ్లను బ్లాక్ చేయి</translation> <translation id="5535973522252703021">Kerberos ప్రతినిధి బృందం సర్వర్ ఆమోదిత జాబితా</translation> <translation id="555077880566103058"><ph name="FLASH_PLUGIN_NAME" /> ప్లగిన్ని ఆటోమేటిక్గా అమలు చేయడానికి అన్ని సైట్లను అనుమతించు</translation> @@ -2463,11 +2462,6 @@ <translation id="6689792153960219308">హార్డ్వేర్ స్థితిని నివేదిస్తుంది</translation> <translation id="6698632841807204978">మోనోక్రోమ్ ముద్రణని ప్రారంభించండి</translation> <translation id="6699880231565102694">రిమోట్ ప్రాప్యత హోస్ట్ల కోసం రెండు-కారక ప్రామాణీకరణను ప్రారంభిస్తుంది</translation> -<translation id="6724842112053619797">మీరు ఈ సెట్టింగ్ని ఆరంభించినట్లయితే, బుక్మార్క్లు, స్వీయపూరణ డేటా, పాస్వర్డ్లు మొదలైన <ph name="PRODUCT_NAME" /> ప్రొఫైల్లలో నిల్వ చేయబడిన సెట్టింగ్లు రోమింగ్ వినియోగదారు ప్రొఫైల్ ఫోల్డర్లో లేదా <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> విధానం ద్వారా నిర్వాహకుడు పేర్కొన్న స్థానంలో నిల్వ చేయబడిన ఫైల్లో కూడా వ్రాయబడతాయి. ఈ విధానం ఆరంభమైతే క్లౌడ్ సింక్ నిలిపివేయబడుతుంది. - - ఈ విధానం నిలిపివేయబడినా లేదా సెట్ చేయకుండా వదిలివేయబడినా, సాధారణ స్థానిక ప్రొఫైల్లు మాత్రమే వినియోగించబడతాయి. - - <ph name="SYNC_DISABLED_POLICY_NAME" /> విధానం RoamingProfileSupportEnabledను భర్తీ చేస్తూ మొత్తం డేటా సమకాలీకరణను నిలిపివేస్తుంది.</translation> <translation id="6731757988219967594">పెద్దలకు మాత్రమే విషయాల కంటెంట్ కోసం అగ్రశ్రేణి స్థాయి సైట్లను ఫిల్టర్ చేయండి (కానీ పొందుపరిచిన iframesను తప్ప)</translation> <translation id="6734521799274931721">ChromeOS లభ్యత కోసం నెట్వర్క్ ఫైల్ షేర్లను నియంత్రిస్తుంది</translation> <translation id="6735701345096330595">అక్షరదోష తనిఖీ భాషలను నిర్బంధంగా ప్రారంభించండి</translation> @@ -2617,13 +2611,13 @@ స్క్రీన్ ఎప్పుడైతే మసకబారే పరిస్థితిలో ఉంటుందో, అప్పుడు స్మార్ట్ కాంతివిహీనత మోడల్ అనేది స్క్రీన్ని మసకబారేలా చేయాలా లేక వాయిదా వేయాలా అనే విషయాలను అంచనా వేస్తుంది. ఒకవేళ స్మార్ట్ కాంతివిహీనత మోడల్ అనేది స్క్రీన్ను మసకబారేలా చేయకూడదు అనుకుంటే మాత్రం, అది సమర్థవంతంగా స్క్రీన్ మసకబారే సమయాన్ని పెంచుతుంది. ఇలాంటి సందర్భంలో, స్క్రీన్ ఆపివేత, స్క్రీన్ లాక్ మరియు నిష్క్రియ ఆలస్యాలు వాస్తవంగా కాన్ఫిగర్ చేయబడిన విధంగానే స్క్రీన్ కాంతివిహీనత ఆలస్యంతో ఒకే రకమైన వ్యత్యాసాన్ని కలిగి ఉండేలా సర్దుబాటు చేయబడతాయి. ఒకవేళ ఈ విధానాన్ని ఒప్పుగా సెట్ చేసినా లేదా అసలు సెట్ చేయకుండా వదిలేసినా, ఈ స్మార్ట్ కాంతివిహీనత మోడల్ ప్రారంభించబడుతుంది అలాగే స్క్రీన్ మసకబారేంత వరకు సమయాన్ని పెంచుకునేలా అనుమతిస్తుంది. ఒకవేళ ఈ విధానాన్ని తప్పుకు సెట్ చేస్తే, స్మార్ట్ కాంతివిహీనత మోడల్ అనేది స్క్రీన్ను మసకబారేలా చేయడంలో ఎలాంటి ప్రభావం చూపదు.</translation> -<translation id="6994082778848658360">రెండవ కారక ప్రమాణీకరణ ఈ ఫీచర్కు అనుకూలంగా ఉంటే దానిని అందించడానికి ఆన్-బోర్డ్ భద్రతా మూలకం హార్డ్వేర్ను ఎలా ఉపయోగించవచ్చో పేర్కొంటుంది. వినియోగదారు భౌగోళిక స్థానాన్ని గుర్తించడానికి యంత్ర శక్తి బటన్ ఉపయోగించబడుతుంది. +<translation id="6994082778848658360">రెండవ దశ ప్రమాణీకరణ ఈ ఫీచర్కు అనుకూలంగా ఉంటే దానిని అందించడానికి ఆన్-బోర్డ్ సురక్షిత మూలకం హార్డ్వేర్ను ఎలా ఉపయోగించవచ్చో పేర్కొంటుంది. వినియోగదారును భౌతికంగా గుర్తించడానికి మెషిన్ పవర్ బటన్ ఉపయోగించబడుతుంది. - 'నిలిపివేయబడింది' ఎంచుకున్నట్లయితే, రెండవ కారకం అందించబడదు. + 'నిలిపివేయబడింది' ఎంచుకున్నట్లయితే, రెండవ దశ అందించబడదు. - 'U2F' ఎంచుకున్నట్లయితే, ఏకీకృత రెండవ కారకం FIDO U2F నిర్దేశం ప్రకారం ప్రవర్తిస్తుంది. + 'U2F' ఎంచుకున్నట్లయితే, FIDO U2F నిర్దేశం ప్రకారం ఏకీకృత రెండవ దశ ప్రవర్తిస్తుంది. - 'U2F_EXTENDED' ఎంచుకున్నట్లయితే, ఏకీకృత రెండవ కారకం వ్యక్తిగత ధృవీకరణ కోసం కొన్ని పొడిగింపులతో పాటుగా U2F ఫంక్షన్లను అందిస్తుంది.</translation> + 'U2F_EXTENDED' ఎంచుకున్నట్లయితే, వ్యక్తిగత ధృవీకరణ కోసం కొన్ని ఎక్స్టెన్షన్లతో పాటుగా U2F ఫంక్షన్లను ఏకీకృత రెండవ దశ అందిస్తుంది.</translation> <translation id="6997592395211691850">స్థానిక విశ్వసనీయ యాంకర్ల కోసం ఆన్లైన్ OCSP/CRL తనిఖీలు చేయాలి లేదా చేయకూడదు</translation> <translation id="7003334574344702284">ప్రారంభించబడితే ఈ విధానం మునుపటి డిఫాల్ట్ బ్రౌజర్ నుండి సేవ్ చేయబడిన పాస్వర్డ్లను బలవంతంగా దిగుమతి చేస్తుంది. ప్రారంభించబడితే, ఈ విధానం దిగుమతి డైలాగ్ను కూడా ప్రభావితం చేస్తుంది. ఆపివేయబడితే, సేవ్ చేయబడిన పాస్వర్డ్లు దిగుమతి చేయబడవు. సెట్ చేయకపోతే, వినియోగదారు దిగుమతి చేయాలా అని అడగబడతారు లేదా దిగుమతి స్వయంచాలకంగా జరుగుతుంది.</translation> <translation id="7003746348783715221"><ph name="PRODUCT_NAME" /> ప్రాధాన్యతలు</translation> @@ -3198,9 +3192,9 @@ ఈ విధానాన్ని తప్పుకు సెట్ చేస్తే, విధాన డేటా మరియు విధాన సమీకరణ పొందిన సమయం సమీకరించబడవు. <ph name="CHROME_REPORTING_EXTENSION_NAME" />ని ప్రారంభించినప్పుడు, అలాగే మెషీన్ని <ph name="MACHINE_LEVEL_USER_CLOUD_POLICY_ENROLLMENT_TOKEN_POLICY_NAME" />తో ప్రారంభించినప్పుడు మాత్రమే ఈ విధానం వర్తిస్తుంది.</translation> -<translation id="8140204717286305802">నెట్వర్క్ ఇంటర్ఫేస్ల జాబితాను వాటి రకాలు మరియు హార్డ్వేర్ చిరునామాలతో సర్వర్కు నివేదించండి. +<translation id="8140204717286305802">నెట్వర్క్ ఇంటర్ఫేస్ల జాబితాను వాటి రకాలు, హార్డ్వేర్ చిరునామాలతో సర్వర్కు నివేదించండి. - విధానాన్ని తప్పుకు సెట్ చేస్తే, ఇంటర్ఫేస్ జాబితా నివేదించబడదు.</translation> + విధానాన్ని తప్పునకు సెట్ చేస్తే, ఇంటర్ఫేస్ జాబితా నివేదించబడదు.</translation> <translation id="8141795997560411818">ఈ విధానం Android Google డిస్క్ అనువర్తనాన్ని ఉపయోగించకుండా వినియోగదారుని నిరోధించలేదు. మీరు Google డిస్క్కి ప్రాప్యత నిరోధించాలనుకుంటే, మీరు Android Google డిస్క్ అనువర్తనం యొక్క ఇన్స్టాలేషన్ను కూడా అనుమతించకూడదు.</translation> <translation id="8142894094385450823">నిర్వహిత సెషన్ కోసం సిఫార్సు చేసిన లొకేల్లను సెట్ చేస్తుంది</translation> <translation id="8146727383888924340">Chrome OS నమోదు ద్వారా ఆఫర్లను రీడీమ్ చేయడానికి వినియోగదారులను అనుమతించండి</translation> @@ -3734,8 +3728,8 @@ ఈ విధానాన్ని ఒప్పుకు సెట్ చేస్తే, సిస్టమ్ లాగ్లు పంపబడతాయి. ఒకవేళ తప్పుకు సెట్ చేస్తే లేదా సెట్ చేయకుంటే, సిస్టమ్ లాగ్లు ఏవీ పంపబడవు.</translation> <translation id="9150416707757015439">ఈ విధానం విలువ తగ్గింది. దయచేసి, దీనికి బదులుగా IncognitoModeAvailabilityను ఉపయోగించండి. <ph name="PRODUCT_NAME" />లో అజ్ఞాత మోడ్ను ప్రారంభిస్తుంది. ఈ సెట్టింగ్ ప్రారంభించబడినా లేదా కాన్ఫిగర్ చేయబడకపోయినా, వినియోగదారులు వెబ్ పేజీలను అజ్ఞాత మోడ్లో తెరవగలరు. ఈ సెట్టింగ్ ఆపివేయబడితే, వినియోగదారులు వెబ్ పేజీలను అజ్ఞాత మోడ్లో తెరువలేరు. ఈ విధానాన్ని సెట్ చేయకుండా వదిలిపెడితే, ఇది ప్రారంభించబడుతుంది మరియు వినియోగదారు అజ్ఞాత మోడ్ను ఉపయోగించగలుగుతారు.</translation> -<translation id="915194831143859291">ఈ విధానాన్ని తప్పుకు సెట్ చేస్తే లేదా కాన్ఫిగర్ చేయకుంటే, పరికరాన్ని షట్ డౌన్ చేయడానికి <ph name="PRODUCT_OS_NAME" /> వినియోగదారును అనుమతిస్తుంది. - ఈ విధానాన్ని ఒప్పుకు సెట్ చేస్తే, వినియోగదారు పరికరాన్ని షట్ డౌన్ చేసినప్పుడు <ph name="PRODUCT_OS_NAME" /> రీబూట్ను ట్రిగ్గర్ చేస్తుంది. <ph name="PRODUCT_OS_NAME" /> UIలో అన్ని సందర్భాల్లో కనిపించే షట్డౌన్ బటన్లను రీబూట్ బటన్లతో భర్తీ చేస్తుంది. వినియోగదారు పవర్ బటన్ను ఉపయోగించి పరికరాన్ని షట్ డౌన్ చేస్తే, విధానం ప్రారంభించబడి ఉన్నప్పటికీ ఆటోమేటిక్గా రీబూట్ కాదు.</translation> +<translation id="915194831143859291">ఈ విధానాన్ని తప్పునకు సెట్ చేస్తే లేదా కాన్ఫిగర్ చేయకుంటే, పరికరాన్ని షట్ డౌన్ చేయడానికి <ph name="PRODUCT_OS_NAME" /> వినియోగదారును అనుమతిస్తుంది. + ఈ విధానాన్ని ఒప్పునకు సెట్ చేస్తే, వినియోగదారు పరికరాన్ని షట్ డౌన్ చేసినప్పుడు <ph name="PRODUCT_OS_NAME" /> రీబూట్ను ట్రిగ్గర్ చేస్తుంది. <ph name="PRODUCT_OS_NAME" /> UIలో అన్ని సందర్భాల్లో కనిపించే షట్డౌన్ బటన్లను రీబూట్ బటన్లతో భర్తీ చేస్తుంది. వినియోగదారు పవర్ బటన్ను ఉపయోగించి పరికరాన్ని షట్ డౌన్ చేస్తే, విధానం ప్రారంభించబడి ఉన్నప్పటికీ ఆటోమేటిక్గా రీబూట్ కాదు.</translation> <translation id="9152473318295429890">సంబంధిత వెబ్ పేజీల యొక్క సందర్భోచిత సూచనలను ప్రారంభించండి</translation> <translation id="9158929520101169054">బ్రౌజర్లో బహుళ సైన్-ఇన్లకు అనుమతించండి</translation> <translation id="9159126470527871268">పెండింగ్లోని అప్డేట్ని అమలు చేయడం కోసం <ph name="PRODUCT_NAME" /> రీలాంచ్ చేయాలని లేదా <ph name="PRODUCT_OS_NAME" /> పునఃప్రారంభించాలని వినియోగదారులకు తెలియజేస్తుంది.
diff --git a/components/policy/resources/policy_templates_th.xtb b/components/policy/resources/policy_templates_th.xtb index efc850c5..f19ba61 100644 --- a/components/policy/resources/policy_templates_th.xtb +++ b/components/policy/resources/policy_templates_th.xtb
@@ -2101,11 +2101,6 @@ <translation id="6689792153960219308">รายงานสถานะของฮาร์ดแวร์</translation> <translation id="6698632841807204978">เปิดใช้การพิมพ์ขาวดำ</translation> <translation id="6699880231565102694">เปิดใช้งานการตรวจสอบสิทธิ์แบบสองปัจจัยสำหรับโฮสต์การเข้าถึงระยะไกล</translation> -<translation id="6724842112053619797">หากคุณเปิดใช้การตั้งค่านี้ ระบบจะบันทึกการตั้งค่าที่เก็บไว้ในโปรไฟล์ <ph name="PRODUCT_NAME" /> เช่น บุ๊กมาร์ก ข้อมูลการป้อนอัตโนมัติ รหัสผ่าน ไปยังไฟล์ที่เก็บไว้ในโฟลเดอร์โปรไฟล์ผู้ใช้โรมมิ่งหรือตำแหน่งที่ผู้ดูแลระบบระบุไว้ผ่านนโยบาย <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> ด้วย การเปิดใช้นโยบายนี้จะปิดใช้คลาวด์ซิงค์ - - หากปิดใช้หรือไม่ได้ตั้งค่านโยบายนี้ ระบบจะใช้เฉพาะโปรไฟล์ปกติในเครื่องเท่านั้น - - นโยบาย <ph name="SYNC_DISABLED_POLICY_NAME" /> จะปิดใช้การซิงค์ข้อมูลทั้งหมดซึ่งลบล้าง RoamingProfileSupportEnabled</translation> <translation id="6731757988219967594">กรองเว็บไซต์ระดับบนสุด (แต่ไม่กรอง iframe ที่ฝังไว้) ที่มีเนื้อหาสำหรับผู้ใหญ่</translation> <translation id="6734521799274931721">ควบคุมพื้นที่แชร์ไฟล์ของเครือข่ายเพื่อความพร้อมใช้งานของ ChromeOS</translation> <translation id="6735701345096330595">บังคับให้เปิดใช้การตรวจการสะกดของภาษาต่างๆ</translation>
diff --git a/components/policy/resources/policy_templates_tr.xtb b/components/policy/resources/policy_templates_tr.xtb index 163ca445..9caca86 100644 --- a/components/policy/resources/policy_templates_tr.xtb +++ b/components/policy/resources/policy_templates_tr.xtb
@@ -2170,11 +2170,6 @@ <translation id="6689792153960219308">Donanım durumunu bildir</translation> <translation id="6698632841807204978">Tek renk yazdırmayı etkinleştir</translation> <translation id="6699880231565102694">Uzaktan erişim ana makineleri için iki öğeli kimlik doğrulamayı etkinleştir</translation> -<translation id="6724842112053619797">Bu ayarı etkinleştirirseniz <ph name="PRODUCT_NAME" /> profillerinde depolanan yer işaretleri, otomatik doldurma verileri, şifreler gibi ayarlar Dolaşım kullanıcı profili klasöründe veya Yönetici tarafından <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> politikası aracılığıyla belirlenen bir konumda depolanan bir dosyaya daha yazılır. Bu politikanın etkinleştirilmesi halinde bulut senkronizasyonu devre dışı bırakılır. - - Bu politika devre dışı bırakılırsa veya ayarlanmazsa yalnızca normal yerel profiller kullanılır. - - <ph name="SYNC_DISABLED_POLICY_NAME" /> politikası, RoamingProfileSupportEnabled'ı geçersiz kılarak tüm veri senkronizasyonunu devre dışı bırakır.</translation> <translation id="6731757988219967594">Üst düzey siteleri (ancak yerleştirilmiş iframe'leri değil) yetişkinlere yönelik içerik için filtrele</translation> <translation id="6734521799274931721">ChromeOS için Ağ Üzerinde Dosya Paylaşımı'nın kullanılabilirliğini kontrol eder</translation> <translation id="6735701345096330595">Yazım denetimi dillerini etkinleştirmeye zorla</translation>
diff --git a/components/policy/resources/policy_templates_uk.xtb b/components/policy/resources/policy_templates_uk.xtb index c6113cb8..3f2dc1c1 100644 --- a/components/policy/resources/policy_templates_uk.xtb +++ b/components/policy/resources/policy_templates_uk.xtb
@@ -2115,11 +2115,6 @@ <translation id="6689792153960219308">Повідомляти про стан апаратного забезпечення</translation> <translation id="6698632841807204978">Увімкнути одноколірний друк</translation> <translation id="6699880231565102694">Вмикати двофакторну автентифікацію для хостів віддаленого доступу</translation> -<translation id="6724842112053619797">Якщо ввімкнути цей параметр, налаштування з профілів <ph name="PRODUCT_NAME" /> (як-от закладки, дані автозаповнення, паролі тощо) також записуватимуться у файл у папці роумінгового профілю користувача або в місці, указаному адміністратором у правилі <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Якщо ввімкнути це правило, вимкнеться синхронізація в хмарі. - - Якщо це правило вимкнено або не налаштовано, використовуватимуться лише звичайні локальні профілі. - - Правило <ph name="SYNC_DISABLED_POLICY_NAME" /> вимикає синхронізацію всіх даних, замінюючи правило RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Фільтрувати сайти вищого рівня (але не вбудовані iframe) із вмістом для дорослих</translation> <translation id="6734521799274931721">Визначає, чи може ОС Chrome обмінюватися файлами в мережі</translation> <translation id="6735701345096330595">Примусово вмикати мови перевірки правопису</translation>
diff --git a/components/policy/resources/policy_templates_vi.xtb b/components/policy/resources/policy_templates_vi.xtb index 4d130cb6..ceaf386 100644 --- a/components/policy/resources/policy_templates_vi.xtb +++ b/components/policy/resources/policy_templates_vi.xtb
@@ -2188,11 +2188,6 @@ <translation id="6689792153960219308">Báo cáo trạng thái phần cứng</translation> <translation id="6698632841807204978">Bật chế độ in đen trắng</translation> <translation id="6699880231565102694">Bật xác thực hai bước cho máy chủ truy cập từ xa</translation> -<translation id="6724842112053619797">Nếu bạn bật cài đặt này, thì các cài đặt được lưu trữ trong cấu hình của <ph name="PRODUCT_NAME" /> như dấu trang, dữ liệu tự động điền, mật khẩu, v.v. cũng sẽ được ghi vào một tệp được lưu trữ trong thư mục cấu hình Người dùng chuyển vùng hoặc một vị trí do Quản trị viên chỉ định thông qua chính sách <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" />. Việc bật chính sách này sẽ tắt đồng bộ hóa trên đám mây. - - Nếu chính sách này bị tắt hoặc chưa được đặt thì chỉ các cấu hình cục bộ thông thường mới được sử dụng. - - Chính sách <ph name="SYNC_DISABLED_POLICY_NAME" /> sẽ tắt tất cả đồng bộ hóa dữ liệu, ghi đè RoamingProfileSupportEnabled.</translation> <translation id="6731757988219967594">Lọc các trang web cấp cao nhất (không phải iframe được nhúng) có nội dung người lớn</translation> <translation id="6734521799274931721">Kiểm soát khả năng sử dụng của ứng dụng Chia sẻ tệp trong mạng trên Chrome OS</translation> <translation id="6735701345096330595">Buộc bật tính năng kiểm tra chính tả ngôn ngữ</translation>
diff --git a/components/policy/resources/policy_templates_zh-CN.xtb b/components/policy/resources/policy_templates_zh-CN.xtb index 53efcc4..4abd351 100644 --- a/components/policy/resources/policy_templates_zh-CN.xtb +++ b/components/policy/resources/policy_templates_zh-CN.xtb
@@ -2064,11 +2064,6 @@ <translation id="6689792153960219308">报告硬件状态</translation> <translation id="6698632841807204978">启用单色打印</translation> <translation id="6699880231565102694">为远程访问主机启用双重身份验证</translation> -<translation id="6724842112053619797">如果您启用此设置,存储在 <ph name="PRODUCT_NAME" /> 个人资料中的设置(例如书签、自动填充数据、密码等)将会被写入一个存储在漫游用户个人资料文件夹内的文件中,或被写入一个由管理员通过 <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> 政策指定的位置中。启用此政策会停用云同步。 - - 如果此政策已停用或未设置,则系统只会使用常规的本地个人资料。 - - <ph name="SYNC_DISABLED_POLICY_NAME" /> 政策会停用所有数据同步,并会替换 RoamingProfileSupportEnabled。</translation> <translation id="6731757988219967594">滤除提供成人内容的顶级网站(但不滤除嵌入式 iframe)</translation> <translation id="6734521799274931721">控制是否允许在 Chrome 操作系统中使用网络文件共享功能</translation> <translation id="6735701345096330595">强制检查语言拼写</translation>
diff --git a/components/policy/resources/policy_templates_zh-TW.xtb b/components/policy/resources/policy_templates_zh-TW.xtb index 143c5dd..e8efa52 100644 --- a/components/policy/resources/policy_templates_zh-TW.xtb +++ b/components/policy/resources/policy_templates_zh-TW.xtb
@@ -2098,11 +2098,6 @@ <translation id="6689792153960219308">回報硬體狀態</translation> <translation id="6698632841807204978">啟用單色列印</translation> <translation id="6699880231565102694">為遠端存取主機啟用雙重驗證機制</translation> -<translation id="6724842112053619797">如果啟用這項設定,系統會將儲存在 <ph name="PRODUCT_NAME" /> 設定檔中的設定 (例如書籤、自動填入資料、密碼等) 一併寫入儲存在漫遊使用者設定檔資料夾中的檔案,或是管理員透過 <ph name="ROAMING_PROFILE_LOCATION_POLICY_NAME" /> 政策指定的位置。啟用這項政策時,雲端同步處理功能會遭到停用: - - 如果停用或未設定這項政策,系統只會使用一般本機設定檔。 - - <ph name="SYNC_DISABLED_POLICY_NAME" /> 政策會停用所有資料同步處理功能,並覆寫 RoamingProfileSupportEnabled。</translation> <translation id="6731757988219967594">針對成人內容篩選頂層網站 (但不篩選嵌入的 iframe)</translation> <translation id="6734521799274931721">控管是否允許在 Chrome 作業系統使用網路檔案共用功能</translation> <translation id="6735701345096330595">強制執行拼字檢查的語言</translation>
diff --git a/components/previews/content/previews_content_util.cc b/components/previews/content/previews_content_util.cc index e23bf98..1bf1b71 100644 --- a/components/previews/content/previews_content_util.cc +++ b/components/previews/content/previews_content_util.cc
@@ -40,6 +40,8 @@ // Previews URLLoader will not receive an updated PreviewsState, so the state // should stay consistent throughout the navigation. if (is_redirect) { + // Record that the navigation was redirected. + previews_data->set_is_redirect(true); // Keep the same OFFLINE previews bit as the original URL. previews_state |= (previews_data->allowed_previews_state() & content::OFFLINE_PAGE_ON);
diff --git a/components/previews/content/previews_content_util_unittest.cc b/components/previews/content/previews_content_util_unittest.cc index a208f1a..f1ac9ad 100644 --- a/components/previews/content/previews_content_util_unittest.cc +++ b/components/previews/content/previews_content_util_unittest.cc
@@ -142,12 +142,14 @@ previews::DetermineAllowedClientPreviewsState( &user_data, GURL("http://www.google.com"), is_reload, is_redirect, is_data_saver_user, enabled_previews_decider())); + EXPECT_FALSE(user_data.is_redirect()); user_data.set_allowed_previews_state(content::OFFLINE_PAGE_ON); is_redirect = true; EXPECT_EQ(content::OFFLINE_PAGE_ON, previews::DetermineAllowedClientPreviewsState( &user_data, GURL("http://www.google.com"), is_reload, is_redirect, is_data_saver_user, enabled_previews_decider())); + EXPECT_TRUE(user_data.is_redirect()); user_data.set_allowed_previews_state(content::PREVIEWS_OFF); EXPECT_EQ(content::PREVIEWS_UNSPECIFIED, previews::DetermineAllowedClientPreviewsState(
diff --git a/components/previews/content/previews_user_data.h b/components/previews/content/previews_user_data.h index 87d1db5..9da193e 100644 --- a/components/previews/content/previews_user_data.h +++ b/components/previews/content/previews_user_data.h
@@ -33,6 +33,10 @@ navigation_ect_ = navigation_ect; } + // Whether the navigation was redirected from the original URL. + bool is_redirect() const { return is_redirect_; } + void set_is_redirect(bool is_redirect) { is_redirect_ = is_redirect; } + // Returns the data savings inflation percent to use for this navigation // instead of the default if it is not 0. int data_savings_inflation_percent() const { @@ -114,6 +118,9 @@ net::EffectiveConnectionType navigation_ect_ = net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN; + // The navigation was redirected from the original URL. + bool is_redirect_ = false; + // A previews data savings inflation percent for the navigation if not 0. int data_savings_inflation_percent_ = 0;
diff --git a/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc b/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc index 633c47b..e05d1d0 100644 --- a/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc +++ b/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc
@@ -124,13 +124,16 @@ callback_id)); if (result_status != RESULT_STATUS_SUCCESS) { - CHECK(callback); // Remove after fixing crbug.com/889972 - CHECK(!callback->is_null()); // Remove after fixing crbug.com/889972 - if (result_status == RESULT_STATUS_TIMEOUT) { + CHECK(callback); // Remove after fixing crbug.com/889972 + CHECK(!callback->is_null()); // Remove after fixing crbug.com/889972 + ReportUmaResult(UMA_STATUS_TIMEOUT); VLOG(1) << "Safe browsing API call timed-out"; } else { + CHECK(callback); // Remove after fixing crbug.com/889972 + CHECK(!callback->is_null()); // Remove after fixing crbug.com/889972 + DCHECK_EQ(result_status, RESULT_STATUS_INTERNAL_ERROR); ReportUmaResult(UMA_STATUS_INTERNAL_ERROR); }
diff --git a/components/search_engines/BUILD.gn b/components/search_engines/BUILD.gn index 5bde3ac..e8ad401 100644 --- a/components/search_engines/BUILD.gn +++ b/components/search_engines/BUILD.gn
@@ -64,6 +64,7 @@ deps = [ ":prepopulated_engines", "//base:i18n", + "//components/country_codes", "//components/history/core/browser", "//components/infobars/core", "//components/pref_registry", @@ -130,6 +131,7 @@ ":test_support", "//base", "//base/test:test_support", + "//components/country_codes", "//components/google/core/browser", "//components/pref_registry:pref_registry", "//components/prefs",
diff --git a/components/search_engines/DEPS b/components/search_engines/DEPS index 4d290b9d..abe4ea3 100644 --- a/components/search_engines/DEPS +++ b/components/search_engines/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/country_codes", "+components/google/core", "+components/history/core", "+components/infobars/core",
diff --git a/components/search_engines/search_engines_pref_names.cc b/components/search_engines/search_engines_pref_names.cc index a65cff3..d9cca18 100644 --- a/components/search_engines/search_engines_pref_names.cc +++ b/components/search_engines/search_engines_pref_names.cc
@@ -26,11 +26,4 @@ const char kSearchProviderOverridesVersion[] = "search_provider_overrides_version"; -// Integer containing the system Country ID the first time we checked the -// template URL prepopulate data. This is used to avoid adding a whole bunch of -// new search engine choices if prepopulation runs when the user's Country ID -// differs from their previous Country ID. This pref does not exist until -// prepopulation has been run at least once. -const char kCountryIDAtInstall[] = "countryid_at_install"; - } // namespace prefs
diff --git a/components/search_engines/search_engines_pref_names.h b/components/search_engines/search_engines_pref_names.h index 0f07d01..3cc3479 100644 --- a/components/search_engines/search_engines_pref_names.h +++ b/components/search_engines/search_engines_pref_names.h
@@ -11,7 +11,6 @@ extern const char kDefaultSearchProviderEnabled[]; extern const char kSearchProviderOverrides[]; extern const char kSearchProviderOverridesVersion[]; -extern const char kCountryIDAtInstall[]; } // namespace prefs
diff --git a/components/search_engines/template_url_prepopulate_data.cc b/components/search_engines/template_url_prepopulate_data.cc index 55da1aba..faf88e1 100644 --- a/components/search_engines/template_url_prepopulate_data.cc +++ b/components/search_engines/template_url_prepopulate_data.cc
@@ -4,17 +4,10 @@ #include "components/search_engines/template_url_prepopulate_data.h" -#if defined(OS_POSIX) && !defined(OS_MACOSX) -#include <locale.h> -#endif - #include "base/logging.h" #include "base/macros.h" -#include "base/strings/string16.h" -#include "base/strings/string_piece.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "components/country_codes/country_codes.h" #include "components/google/core/common/google_util.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" @@ -25,17 +18,6 @@ #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "url/gurl.h" -#if defined(OS_WIN) -#include <windows.h> -#undef IN // On Windows, windef.h defines this, which screws up "India" cases. -#elif defined(OS_MACOSX) -#include "base/mac/scoped_cftyperef.h" -#endif - -#if defined(OS_ANDROID) -#include "base/android/locale_utils.h" -#endif - namespace TemplateURLPrepopulateData { // Helpers -------------------------------------------------------------------- @@ -609,120 +591,6 @@ &softonic, &sweetim, &terra_ar, &terra_es, &tut, &walla, &wp, &zoznam, }; -// Please refer to ISO 3166-1 for information about the two-character country -// codes; http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 is useful. In the -// following (C++) code, we pack the two letters of the country code into an int -// value we call the CountryID. - -const int kCountryIDUnknown = -1; - -inline int CountryCharsToCountryID(char c1, char c2) { - return c1 << 8 | c2; -} - -int CountryCharsToCountryIDWithUpdate(char c1, char c2) { - // SPECIAL CASE: In 2003, Yugoslavia renamed itself to Serbia and Montenegro. - // Serbia and Montenegro dissolved their union in June 2006. Yugoslavia was - // ISO 'YU' and Serbia and Montenegro were ISO 'CS'. Serbia was subsequently - // issued 'RS' and Montenegro 'ME'. Windows XP and Mac OS X Leopard still use - // the value 'YU'. If we get a value of 'YU' or 'CS' we will map it to 'RS'. - if ((c1 == 'Y' && c2 == 'U') || - (c1 == 'C' && c2 == 'S')) { - c1 = 'R'; - c2 = 'S'; - } - - // SPECIAL CASE: Timor-Leste changed from 'TP' to 'TL' in 2002. Windows XP - // predates this; we therefore map this value. - if (c1 == 'T' && c2 == 'P') - c2 = 'L'; - - return CountryCharsToCountryID(c1, c2); -} - -#if !defined(OS_WIN) && !defined(OS_MACOSX) - -int CountryStringToCountryID(const std::string& country) { - return (country.length() == 2) - ? CountryCharsToCountryIDWithUpdate(country[0], country[1]) - : kCountryIDUnknown; -} - -#endif - -#if defined(OS_WIN) - -// For reference, a list of GeoIDs can be found at -// http://msdn.microsoft.com/en-us/library/dd374073.aspx . -int GeoIDToCountryID(GEOID geo_id) { - const int kISOBufferSize = 3; // Two plus one for the terminator. - wchar_t isobuf[kISOBufferSize] = { 0 }; - int retval = GetGeoInfo(geo_id, GEO_ISO2, isobuf, kISOBufferSize, 0); - - if (retval == kISOBufferSize && - !(isobuf[0] == L'X' && isobuf[1] == L'X')) - return CountryCharsToCountryIDWithUpdate(static_cast<char>(isobuf[0]), - static_cast<char>(isobuf[1])); - - // Various locations have ISO codes that Windows does not return. - switch (geo_id) { - case 0x144: // Guernsey - return CountryCharsToCountryID('G', 'G'); - case 0x148: // Jersey - return CountryCharsToCountryID('J', 'E'); - case 0x3B16: // Isle of Man - return CountryCharsToCountryID('I', 'M'); - - // 'UM' (U.S. Minor Outlying Islands) - case 0x7F: // Johnston Atoll - case 0x102: // Wake Island - case 0x131: // Baker Island - case 0x146: // Howland Island - case 0x147: // Jarvis Island - case 0x149: // Kingman Reef - case 0x152: // Palmyra Atoll - case 0x52FA: // Midway Islands - return CountryCharsToCountryID('U', 'M'); - - // 'SH' (Saint Helena) - case 0x12F: // Ascension Island - case 0x15C: // Tristan da Cunha - return CountryCharsToCountryID('S', 'H'); - - // 'IO' (British Indian Ocean Territory) - case 0x13A: // Diego Garcia - return CountryCharsToCountryID('I', 'O'); - - // Other cases where there is no ISO country code; we assign countries that - // can serve as reasonable defaults. - case 0x154: // Rota Island - case 0x155: // Saipan - case 0x15A: // Tinian Island - return CountryCharsToCountryID('U', 'S'); - case 0x134: // Channel Islands - return CountryCharsToCountryID('G', 'B'); - case 0x143: // Guantanamo Bay - default: - return kCountryIDUnknown; - } -} - -#endif // defined(OS_WIN) - -int GetCountryIDFromPrefs(PrefService* prefs) { - if (!prefs) - return GetCurrentCountryID(); - - // Cache first run Country ID value in prefs, and use it afterwards. This - // ensures that just because the user moves around, we won't automatically - // make major changes to their available search providers, which would feel - // surprising. - if (!prefs->HasPrefPath(prefs::kCountryIDAtInstall)) { - prefs->SetInteger(prefs::kCountryIDAtInstall, GetCurrentCountryID()); - } - return prefs->GetInteger(prefs::kCountryIDAtInstall); -} - std::vector<std::unique_ptr<TemplateURLData>> GetPrepopulationSetFromCountryID( int country_id) { const PrepopulatedEngine* const* engines; @@ -1073,7 +941,7 @@ UNHANDLED_COUNTRY(V, U) // Vanuatu UNHANDLED_COUNTRY(W, S) // Samoa UNHANDLED_COUNTRY(Z, M) // Zambia - case kCountryIDUnknown: + case country_codes::kCountryIDUnknown: default: // Unhandled location END_UNHANDLED_COUNTRIES(def, ault) } @@ -1118,7 +986,7 @@ // Global functions ----------------------------------------------------------- void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { - registry->RegisterIntegerPref(prefs::kCountryIDAtInstall, kCountryIDUnknown); + country_codes::RegisterProfilePrefs(registry); registry->RegisterListPref(prefs::kSearchProviderOverrides); registry->RegisterIntegerPref(prefs::kSearchProviderOverridesVersion, -1); } @@ -1142,7 +1010,8 @@ if (!t_urls.empty()) return t_urls; - return GetPrepopulationSetFromCountryID(GetCountryIDFromPrefs(prefs)); + return GetPrepopulationSetFromCountryID( + country_codes::GetCountryIDFromPrefs(prefs)); } std::unique_ptr<TemplateURLData> GetPrepopulatedEngine(PrefService* prefs, @@ -1161,8 +1030,8 @@ std::vector<std::unique_ptr<TemplateURLData>> GetLocalPrepopulatedEngines( const std::string& locale) { - int country_id = CountryStringToCountryID(locale); - if (country_id == kCountryIDUnknown) { + int country_id = country_codes::CountryStringToCountryID(locale); + if (country_id == country_codes::kCountryIDUnknown) { LOG(ERROR) << "Unknown country code specified: " << locale; return std::vector<std::unique_ptr<TemplateURLData>>(); } @@ -1227,58 +1096,4 @@ return SEARCH_ENGINE_OTHER; } -#if defined(OS_WIN) - -int GetCurrentCountryID() { - return GeoIDToCountryID(GetUserGeoID(GEOCLASS_NATION)); -} - -#elif defined(OS_MACOSX) - -int GetCurrentCountryID() { - base::ScopedCFTypeRef<CFLocaleRef> locale(CFLocaleCopyCurrent()); - CFStringRef country = (CFStringRef)CFLocaleGetValue(locale.get(), - kCFLocaleCountryCode); - if (!country) - return kCountryIDUnknown; - - UniChar isobuf[2]; - CFRange char_range = CFRangeMake(0, 2); - CFStringGetCharacters(country, char_range, isobuf); - - return CountryCharsToCountryIDWithUpdate(static_cast<char>(isobuf[0]), - static_cast<char>(isobuf[1])); -} - -#elif defined(OS_ANDROID) - -int GetCurrentCountryID() { - return CountryStringToCountryID(base::android::GetDefaultCountryCode()); -} - -#elif defined(OS_POSIX) || defined(OS_FUCHSIA) - -int GetCurrentCountryID() { - const char* locale = setlocale(LC_MESSAGES, nullptr); - if (!locale) - return kCountryIDUnknown; - - // The format of a locale name is: - // language[_territory][.codeset][@modifier], where territory is an ISO 3166 - // country code, which is what we want. - - // First remove the language portion. - std::string locale_str(locale); - size_t territory_delim = locale_str.find('_'); - if (territory_delim == std::string::npos) - return kCountryIDUnknown; - locale_str.erase(0, territory_delim + 1); - - // Next remove any codeset/modifier portion and uppercase. - return CountryStringToCountryID( - base::ToUpperASCII(locale_str.substr(0, locale_str.find_first_of(".@")))); -} - -#endif // OS_* - } // namespace TemplateURLPrepopulateData
diff --git a/components/search_engines/template_url_prepopulate_data.h b/components/search_engines/template_url_prepopulate_data.h index 4e76dab..159263ac 100644 --- a/components/search_engines/template_url_prepopulate_data.h +++ b/components/search_engines/template_url_prepopulate_data.h
@@ -11,7 +11,6 @@ #include <string> #include <vector> -#include "base/strings/string16.h" #include "components/search_engines/search_engine_type.h" class GURL; @@ -70,14 +69,6 @@ // This may be called on any thread. SearchEngineType GetEngineType(const GURL& url); -// Returns the identifier for the user current country. Used to update the list -// of search engines when user switches device region settings. For use on iOS -// only. -// TODO(ios): Once user can customize search engines ( http://crbug.com/153047 ) -// this declaration should be removed and the definition in the .cc file be -// moved back to the anonymous namespace. -int GetCurrentCountryID(); - } // namespace TemplateURLPrepopulateData #endif // COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_PREPOPULATE_DATA_H_
diff --git a/components/search_engines/template_url_prepopulate_data_unittest.cc b/components/search_engines/template_url_prepopulate_data_unittest.cc index 0f50cf1..a9b50b8 100644 --- a/components/search_engines/template_url_prepopulate_data_unittest.cc +++ b/components/search_engines/template_url_prepopulate_data_unittest.cc
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" +#include "components/country_codes/country_codes.h" #include "components/google/core/common/google_switches.h" #include "components/search_engines/prepopulated_engines.h" #include "components/search_engines/search_engines_pref_names.h" @@ -106,7 +107,7 @@ 'Y'<<8|'T', 'Z'<<8|'A', 'Z'<<8|'M', 'Z'<<8|'W', -1 }; for (size_t i = 0; i < arraysize(kCountryIds); ++i) { - prefs_.SetInteger(prefs::kCountryIDAtInstall, kCountryIds[i]); + prefs_.SetInteger(country_codes::kCountryIDAtInstall, kCountryIds[i]); std::vector<std::unique_ptr<TemplateURLData>> urls = TemplateURLPrepopulateData::GetPrepopulatedEngines(&prefs_, nullptr); std::set<int> unique_ids; @@ -253,7 +254,7 @@ // Verifies that built-in search providers are processed correctly. TEST_F(TemplateURLPrepopulateDataTest, ProvidersFromPrepopulated) { // Use United States. - prefs_.SetInteger(prefs::kCountryIDAtInstall, 'U'<<8|'S'); + prefs_.SetInteger(country_codes::kCountryIDAtInstall, 'U' << 8 | 'S'); size_t default_index; std::vector<std::unique_ptr<TemplateURLData>> t_urls = TemplateURLPrepopulateData::GetPrepopulatedEngines(&prefs_,
diff --git a/components/security_interstitials/core/common/resources/interstitial_core.css b/components/security_interstitials/core/common/resources/interstitial_core.css index 8aa42e09a..c0d75f2 100644 --- a/components/security_interstitials/core/common/resources/interstitial_core.css +++ b/components/security_interstitials/core/common/resources/interstitial_core.css
@@ -13,7 +13,7 @@ --google-gray-300: rgb(218, 220, 224); --google-gray-500: rgb(154, 160, 166); --google-gray-600: rgb(128, 134, 139); - --google-gray-700: rgb(95, 99, 105); + --google-gray-700: rgb(95, 99, 104); background-color: #fff; color: var(--google-gray-700); word-wrap: break-word;
diff --git a/components/services/filesystem/BUILD.gn b/components/services/filesystem/BUILD.gn index 504758b..e6ecaff8 100644 --- a/components/services/filesystem/BUILD.gn +++ b/components/services/filesystem/BUILD.gn
@@ -5,7 +5,6 @@ import("//services/catalog/public/tools/catalog.gni") import("//services/service_manager/public/cpp/service.gni") import("//services/service_manager/public/service_manifest.gni") -import("//services/service_manager/public/tools/test/service_test.gni") import("//testing/test.gni") static_library("lib") { @@ -58,7 +57,7 @@ source = "manifest.json" } - service_test("filesystem_service_unittests") { + test("filesystem_service_unittests") { sources = [ "directory_impl_unittest.cc", "file_impl_unittest.cc", @@ -66,15 +65,17 @@ "files_test_base.h", ] - catalog = ":filesystem_service_unittests_catalog" - deps = [ + ":filesystem_service_unittests_catalog_source", "//base", + "//base/test:test_support", "//components/services/filesystem/public/interfaces", + "//mojo/core/test:run_all_unittests", "//mojo/public/cpp/bindings", "//mojo/public/cpp/system", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp:service_test_support", + "//services/service_manager/public/cpp/test:test_support", + "//testing/gtest", ] data_deps = [ @@ -91,4 +92,10 @@ embedded_services = [ ":test_manifest" ] standalone_services = [ ":manifest" ] } + + catalog_cpp_source("filesystem_service_unittests_catalog_source") { + testonly = true + catalog = ":filesystem_service_unittests_catalog" + generated_function_name = "filesystem::test::CreateTestCatalog" + } }
diff --git a/components/services/filesystem/file_system_app.cc b/components/services/filesystem/file_system_app.cc index 047645f..8775ba4 100644 --- a/components/services/filesystem/file_system_app.cc +++ b/components/services/filesystem/file_system_app.cc
@@ -11,7 +11,6 @@ #include "base/files/file_util.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "services/service_manager/public/cpp/connector.h" -#include "services/service_manager/public/cpp/service_context.h" #if defined(OS_WIN) #include "base/base_paths_win.h" @@ -36,14 +35,13 @@ } // namespace -FileSystemApp::FileSystemApp() : lock_table_(new LockTable) { +FileSystemApp::FileSystemApp(service_manager::mojom::ServiceRequest request) + : service_binding_(this, std::move(request)), lock_table_(new LockTable) { registry_.AddInterface<mojom::FileSystem>( base::Bind(&FileSystemApp::Create, base::Unretained(this))); } -FileSystemApp::~FileSystemApp() {} - -void FileSystemApp::OnStart() {} +FileSystemApp::~FileSystemApp() = default; void FileSystemApp::OnBindInterface( const service_manager::BindSourceInfo& source_info,
diff --git a/components/services/filesystem/file_system_app.h b/components/services/filesystem/file_system_app.h index 84d9d9bf..f4e0b7c1 100644 --- a/components/services/filesystem/file_system_app.h +++ b/components/services/filesystem/file_system_app.h
@@ -12,12 +12,13 @@ #include "components/services/filesystem/public/interfaces/file_system.mojom.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/cpp/service_binding.h" namespace filesystem { class FileSystemApp : public service_manager::Service { public: - FileSystemApp(); + explicit FileSystemApp(service_manager::mojom::ServiceRequest request); ~FileSystemApp() override; private: @@ -25,7 +26,6 @@ static base::FilePath GetUserDataDir(); // |service_manager::Service| override: - void OnStart() override; void OnBindInterface(const service_manager::BindSourceInfo& source_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; @@ -33,6 +33,7 @@ void Create(mojom::FileSystemRequest request, const service_manager::BindSourceInfo& source_info); + service_manager::ServiceBinding service_binding_; service_manager::BinderRegistryWithArgs< const service_manager::BindSourceInfo&> registry_;
diff --git a/components/services/filesystem/files_test_base.cc b/components/services/filesystem/files_test_base.cc index a8b0b0f..1429cfd5 100644 --- a/components/services/filesystem/files_test_base.cc +++ b/components/services/filesystem/files_test_base.cc
@@ -6,18 +6,21 @@ #include <utility> +#include "components/services/filesystem/filesystem_service_unittests_catalog_source.h" #include "components/services/filesystem/public/interfaces/directory.mojom.h" #include "components/services/filesystem/public/interfaces/types.mojom.h" #include "services/service_manager/public/cpp/connector.h" namespace filesystem { -FilesTestBase::FilesTestBase() : ServiceTest("filesystem_service_unittests") {} +FilesTestBase::FilesTestBase() + : test_service_manager_(test::CreateTestCatalog()), + test_service_(test_service_manager_.RegisterTestInstance( + "filesystem_service_unittests")) {} FilesTestBase::~FilesTestBase() {} void FilesTestBase::SetUp() { - ServiceTest::SetUp(); connector()->BindInterface("filesystem", &files_); }
diff --git a/components/services/filesystem/files_test_base.h b/components/services/filesystem/files_test_base.h index 1f896c5..75d0ce5c 100644 --- a/components/services/filesystem/files_test_base.h +++ b/components/services/filesystem/files_test_base.h
@@ -9,41 +9,21 @@ #include "base/bind.h" #include "base/macros.h" +#include "base/test/scoped_task_environment.h" #include "components/services/filesystem/public/interfaces/file_system.mojom.h" #include "mojo/public/cpp/bindings/binding.h" -#include "services/service_manager/public/cpp/service_test.h" +#include "services/service_manager/public/cpp/test/test_service.h" +#include "services/service_manager/public/cpp/test/test_service_manager.h" +#include "testing/gtest/include/gtest/gtest.h" namespace filesystem { -template <typename... Args> -void IgnoreAllArgs(Args&&... args) {} - -template <typename... Args> -void DoCaptures(Args*... out_args, Args... in_args) { - IgnoreAllArgs((*out_args = std::move(in_args))...); -} - -template <typename T1> -base::Callback<void(T1)> Capture(T1* t1) { - return base::Bind(&DoCaptures<T1>, t1); -} - -template <typename T1, typename T2> -base::Callback<void(T1, T2)> Capture(T1* t1, T2* t2) { - return base::Bind(&DoCaptures<T1, T2>, t1, t2); -} - -template <typename T1, typename T2, typename T3> -base::Callback<void(T1, T2, T3)> Capture(T1* t1, T2* t2, T3* t3) { - return base::Bind(&DoCaptures<T1, T2, T3>, t1, t2, t3); -} - -class FilesTestBase : public service_manager::test::ServiceTest { +class FilesTestBase : public testing::Test { public: FilesTestBase(); ~FilesTestBase() override; - // Overridden from service_manager::test::ServiceTest: + // testing::Test: void SetUp() override; protected: @@ -51,9 +31,13 @@ // since |ASSERT_...()| doesn't work with return values. void GetTemporaryRoot(mojom::DirectoryPtr* directory); + service_manager::Connector* connector() { return test_service_.connector(); } mojom::FileSystemPtr& files() { return files_; } private: + base::test::ScopedTaskEnvironment task_environment_; + service_manager::TestServiceManager test_service_manager_; + service_manager::TestService test_service_; mojom::FileSystemPtr files_; DISALLOW_COPY_AND_ASSIGN(FilesTestBase);
diff --git a/components/services/filesystem/main.cc b/components/services/filesystem/main.cc index 62359c0..59178b37 100644 --- a/components/services/filesystem/main.cc +++ b/components/services/filesystem/main.cc
@@ -1,13 +1,20 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. +// 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. #include "services/service_manager/public/c/main.h" -#include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" #include "components/services/filesystem/file_system_app.h" -#include "services/service_manager/public/cpp/service_runner.h" +#include "mojo/public/cpp/system/message_pipe.h" +#include "services/service_manager/public/mojom/service.mojom.h" -MojoResult ServiceMain(MojoHandle request) { - service_manager::ServiceRunner runner(new filesystem::FileSystemApp()); - return runner.Run(request); +MojoResult ServiceMain(MojoHandle service_request_handle) { + base::MessageLoop message_loop; + base::RunLoop run_loop; + filesystem::FileSystemApp service{service_manager::mojom::ServiceRequest( + mojo::MakeScopedHandle(mojo::MessagePipeHandle(service_request_handle)))}; + service.set_termination_closure(run_loop.QuitClosure()); + run_loop.Run(); + return MOJO_RESULT_OK; }
diff --git a/components/services/font/BUILD.gn b/components/services/font/BUILD.gn index 72419c9..96ceee2a 100644 --- a/components/services/font/BUILD.gn +++ b/components/services/font/BUILD.gn
@@ -3,12 +3,10 @@ # found in the LICENSE file. import("//build/config/features.gni") -import("//build/config/features.gni") import("//ppapi/buildflags/buildflags.gni") -import("//ppapi/buildflags/buildflags.gni") +import("//services/catalog/public/tools/catalog.gni") import("//services/service_manager/public/cpp/service.gni") import("//services/service_manager/public/service_manifest.gni") -import("//services/service_manager/public/tools/test/service_test.gni") import("//testing/test.gni") source_set("lib") { @@ -68,6 +66,7 @@ "//base", "//mojo/public/c/system", "//services/service_manager/public/cpp", + "//services/service_manager/public/mojom", ] } @@ -76,24 +75,25 @@ source = "manifest.json" } -service_test("font_service_unittests") { +test("font_service_unittests") { sources = [ - "font_loader_test.cc", - "font_loader_test.h", + "font_loader_unittest.cc", ] - catalog = ":font_service_unittests_catalog" - deps = [ + ":font_service_unittests_catalog_source", "//base", + "//base/test:test_support", "//components/services/font/public/cpp", "//components/services/font/public/interfaces", + "//mojo/core/test:run_all_unittests", "//mojo/public/cpp/bindings", "//mojo/public/cpp/system", "//ppapi/buildflags:buildflags", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp:service_test_support", + "//services/service_manager/public/cpp/test:test_support", "//skia", + "//testing/gtest", ] if (enable_plugins) { @@ -117,3 +117,9 @@ embedded_services = [ ":test_manifest" ] standalone_services = [ ":manifest" ] } + +catalog_cpp_source("font_service_unittests_catalog_source") { + testonly = true + catalog = ":font_service_unittests_catalog" + generated_function_name = "font_service::test::CreateTestCatalog" +}
diff --git a/components/services/font/font_loader_test.h b/components/services/font/font_loader_test.h deleted file mode 100644 index a0a44991..0000000 --- a/components/services/font/font_loader_test.h +++ /dev/null
@@ -1,38 +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 COMPONENTS_SERVICES_FONT_FONT_LOADER_TEST_H_ -#define COMPONENTS_SERVICES_FONT_FONT_LOADER_TEST_H_ - -#include <utility> - -#include "base/bind.h" -#include "base/macros.h" -#include "components/services/font/public/cpp/font_loader.h" -#include "components/services/font/public/interfaces/font_service.mojom.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "services/service_manager/public/cpp/service_test.h" - -namespace font_service { - -class FontLoaderTest : public service_manager::test::ServiceTest { - public: - FontLoaderTest(); - ~FontLoaderTest() override; - - // Overridden from service_manager::test::ServiceTest: - void SetUp() override; - - protected: - FontLoader* font_loader() { return font_loader_.get(); } - - private: - std::unique_ptr<FontLoader> font_loader_; - - DISALLOW_COPY_AND_ASSIGN(FontLoaderTest); -}; - -} // namespace font_service - -#endif // COMPONENTS_SERVICES_FONT_FONT_LOADER_TEST_H_
diff --git a/components/services/font/font_loader_test.cc b/components/services/font/font_loader_unittest.cc similarity index 93% rename from components/services/font/font_loader_test.cc rename to components/services/font/font_loader_unittest.cc index 512043aa..d7ec44d 100644 --- a/components/services/font/font_loader_test.cc +++ b/components/services/font/font_loader_unittest.cc
@@ -2,15 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/services/font/font_loader_test.h" - #include <utility> +#include "base/macros.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" +#include "components/services/font/font_service_unittests_catalog_source.h" +#include "components/services/font/public/cpp/font_loader.h" #include "components/services/font/public/interfaces/constants.mojom.h" #include "components/services/font/public/interfaces/font_service.mojom.h" #include "ppapi/buildflags/buildflags.h" #include "services/service_manager/public/cpp/connector.h" +#include "services/service_manager/public/cpp/test/test_service.h" +#include "services/service_manager/public/cpp/test/test_service_manager.h" +#include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkFontStyle.h" #if BUILDFLAG(ENABLE_PLUGINS) @@ -19,7 +24,9 @@ #include "ppapi/c/private/pp_private_font_charset.h" // nogncheck #endif +namespace font_service { namespace { + bool IsInTestFontDirectory(const char* path) { const char kTestFontsDir[] = "test_fonts"; return std::string(path).find(kTestFontsDir) != std::string::npos; @@ -49,19 +56,29 @@ } #endif +class FontLoaderTest : public testing::Test { + public: + FontLoaderTest() + : test_service_manager_(test::CreateTestCatalog()), + test_service_(test_service_manager_.RegisterTestInstance( + "font_service_unittests")), + font_loader_(test_service_.connector()) {} + ~FontLoaderTest() override = default; + + protected: + FontLoader* font_loader() { return &font_loader_; } + + private: + base::test::ScopedTaskEnvironment task_environment_; + service_manager::TestServiceManager test_service_manager_; + service_manager::TestService test_service_; + FontLoader font_loader_; + + DISALLOW_COPY_AND_ASSIGN(FontLoaderTest); +}; + } // namespace -namespace font_service { - -FontLoaderTest::FontLoaderTest() : ServiceTest("font_service_unittests") {} - -FontLoaderTest::~FontLoaderTest() {} - -void FontLoaderTest::SetUp() { - ServiceTest::SetUp(); - font_loader_ = std::make_unique<FontLoader>(connector()); -} - TEST_F(FontLoaderTest, BasicMatchingTest) { SkFontStyle styles[] = { SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width,
diff --git a/components/services/font/font_service_app.cc b/components/services/font/font_service_app.cc index 48378fd..61a04625 100644 --- a/components/services/font/font_service_app.cc +++ b/components/services/font/font_service_app.cc
@@ -13,7 +13,6 @@ #include "components/services/font/fontconfig_matching.h" #include "mojo/public/cpp/system/platform_handle.h" #include "ppapi/buildflags/buildflags.h" -#include "services/service_manager/public/cpp/service_context.h" #include "ui/gfx/font_fallback_linux.h" #include "ui/gfx/font_render_params.h" @@ -83,11 +82,8 @@ namespace font_service { -std::unique_ptr<service_manager::Service> FontServiceApp::CreateService() { - return std::make_unique<FontServiceApp>(); -} - -FontServiceApp::FontServiceApp() { +FontServiceApp::FontServiceApp(service_manager::mojom::ServiceRequest request) + : service_binding_(this, std::move(request)) { registry_.AddInterface( base::BindRepeating(&FontServiceApp::CreateSelf, base::Unretained(this))); }
diff --git a/components/services/font/font_service_app.h b/components/services/font/font_service_app.h index 6456a37f..886485b1 100644 --- a/components/services/font/font_service_app.h +++ b/components/services/font/font_service_app.h
@@ -13,6 +13,7 @@ #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/cpp/service_binding.h" #include "skia/ext/skia_utils_base.h" namespace font_service { @@ -20,11 +21,9 @@ class FontServiceApp : public service_manager::Service, public mojom::FontService { public: - FontServiceApp(); + explicit FontServiceApp(service_manager::mojom::ServiceRequest request); ~FontServiceApp() override; - static std::unique_ptr<service_manager::Service> CreateService(); - void CreateSelf(mojom::FontServiceRequest request); private: @@ -61,6 +60,7 @@ MatchFontWithFallbackCallback callback) override; int FindOrAddPath(const SkString& path); + service_manager::ServiceBinding service_binding_; service_manager::BinderRegistry registry_; mojo::BindingSet<mojom::FontService> bindings_;
diff --git a/components/services/font/main.cc b/components/services/font/main.cc index 6995dab..d355b48 100644 --- a/components/services/font/main.cc +++ b/components/services/font/main.cc
@@ -3,10 +3,18 @@ // found in the LICENSE file. #include "services/service_manager/public/c/main.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" #include "components/services/font/font_service_app.h" -#include "services/service_manager/public/cpp/service_runner.h" +#include "mojo/public/cpp/system/message_pipe.h" +#include "services/service_manager/public/mojom/service.mojom.h" MojoResult ServiceMain(MojoHandle service_request_handle) { - service_manager::ServiceRunner runner(new font_service::FontServiceApp); - return runner.Run(service_request_handle); + base::MessageLoop message_loop; + base::RunLoop run_loop; + font_service::FontServiceApp service{service_manager::mojom::ServiceRequest( + mojo::MakeScopedHandle(mojo::MessagePipeHandle(service_request_handle)))}; + service.set_termination_closure(run_loop.QuitClosure()); + run_loop.Run(); + return MOJO_RESULT_OK; }
diff --git a/components/services/leveldb/BUILD.gn b/components/services/leveldb/BUILD.gn index 96c8626..1d2e024 100644 --- a/components/services/leveldb/BUILD.gn +++ b/components/services/leveldb/BUILD.gn
@@ -5,7 +5,6 @@ import("//services/catalog/public/tools/catalog.gni") import("//services/service_manager/public/cpp/service.gni") import("//services/service_manager/public/service_manifest.gni") -import("//services/service_manager/public/tools/test/service_test.gni") import("//testing/test.gni") static_library("lib") { @@ -54,25 +53,26 @@ source = "manifest.json" } -service_test("leveldb_service_unittests") { +test("leveldb_service_unittests") { sources = [ "leveldb_mojo_unittest.cc", "leveldb_service_unittest.cc", "remote_iterator_unittest.cc", ] - catalog = ":leveldb_service_unittests_catalog" - deps = [ + ":leveldb_service_unittests_catalog_source", "//base", "//base/test:test_support", "//components/services/filesystem/public/interfaces", "//components/services/leveldb/public/cpp", "//components/services/leveldb/public/interfaces", + "//mojo/core/test:run_all_unittests", "//mojo/public/cpp/bindings", "//mojo/public/cpp/system", "//services/service_manager/public/cpp", - "//services/service_manager/public/cpp:service_test_support", + "//services/service_manager/public/cpp/test:test_support", + "//testing/gtest", "//third_party/leveldatabase", ] @@ -94,3 +94,9 @@ "//components/services/filesystem:manifest", ] } + +catalog_cpp_source("leveldb_service_unittests_catalog_source") { + testonly = true + catalog = ":leveldb_service_unittests_catalog" + generated_function_name = "leveldb::test::CreateTestCatalog" +}
diff --git a/components/services/leveldb/leveldb_app.cc b/components/services/leveldb/leveldb_app.cc index 7de8011..63c10fc 100644 --- a/components/services/leveldb/leveldb_app.cc +++ b/components/services/leveldb/leveldb_app.cc
@@ -10,8 +10,9 @@ namespace leveldb { -LevelDBApp::LevelDBApp() - : file_task_runner_(base::CreateSequencedTaskRunnerWithTraits( +LevelDBApp::LevelDBApp(service_manager::mojom::ServiceRequest request) + : service_binding_(this, std::move(request)), + file_task_runner_(base::CreateSequencedTaskRunnerWithTraits( {base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN})) { registry_.AddInterface<mojom::LevelDBService>( base::Bind(&LevelDBApp::Create, base::Unretained(this))); @@ -19,8 +20,6 @@ LevelDBApp::~LevelDBApp() {} -void LevelDBApp::OnStart() {} - void LevelDBApp::OnBindInterface( const service_manager::BindSourceInfo& source_info, const std::string& interface_name,
diff --git a/components/services/leveldb/leveldb_app.h b/components/services/leveldb/leveldb_app.h index 06c1b87..0190f38 100644 --- a/components/services/leveldb/leveldb_app.h +++ b/components/services/leveldb/leveldb_app.h
@@ -11,6 +11,7 @@ #include "mojo/public/cpp/bindings/binding_set.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/cpp/service_binding.h" namespace base { class SequencedTaskRunner; @@ -20,18 +21,18 @@ class LevelDBApp : public service_manager::Service { public: - LevelDBApp(); + explicit LevelDBApp(service_manager::mojom::ServiceRequest request); ~LevelDBApp() override; private: // |Service| override: - void OnStart() override; void OnBindInterface(const service_manager::BindSourceInfo& source_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; void Create(leveldb::mojom::LevelDBServiceRequest request); + service_manager::ServiceBinding service_binding_; std::unique_ptr<mojom::LevelDBService> service_; service_manager::BinderRegistry registry_; mojo::BindingSet<mojom::LevelDBService> bindings_;
diff --git a/components/services/leveldb/leveldb_service_unittest.cc b/components/services/leveldb/leveldb_service_unittest.cc index 11b95567..6fea47d1 100644 --- a/components/services/leveldb/leveldb_service_unittest.cc +++ b/components/services/leveldb/leveldb_service_unittest.cc
@@ -6,14 +6,17 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/test/scoped_feature_list.h" +#include "base/test/scoped_task_environment.h" #include "components/services/filesystem/public/interfaces/directory.mojom.h" #include "components/services/filesystem/public/interfaces/file_system.mojom.h" #include "components/services/filesystem/public/interfaces/types.mojom.h" +#include "components/services/leveldb/leveldb_service_unittests_catalog_source.h" #include "components/services/leveldb/public/cpp/util.h" #include "components/services/leveldb/public/interfaces/leveldb.mojom.h" #include "mojo/public/cpp/bindings/binding_set.h" -#include "services/service_manager/public/cpp/service_context.h" -#include "services/service_manager/public/cpp/service_test.h" +#include "services/service_manager/public/cpp/test/test_service.h" +#include "services/service_manager/public/cpp/test/test_service_manager.h" +#include "testing/gtest/include/gtest/gtest.h" #include "third_party/leveldatabase/leveldb_features.h" namespace leveldb { @@ -131,29 +134,26 @@ run_loop.Run(); } -class LevelDBServiceTest : public service_manager::test::ServiceTest { +class LevelDBServiceTest : public testing::Test { public: - LevelDBServiceTest() : ServiceTest("leveldb_service_unittests") {} - ~LevelDBServiceTest() override {} + LevelDBServiceTest() + : test_service_manager_(test::CreateTestCatalog()), + test_service_(test_service_manager_.RegisterTestInstance( + "leveldb_service_unittests")) {} + ~LevelDBServiceTest() override = default; protected: - // Overridden from mojo::test::ApplicationTestBase: + service_manager::Connector* connector() { return test_service_.connector(); } + void SetUp() override { // TODO(dullweber): This doesn't seem to work. The reason is probably that // the LevelDB service is a separate executable here. How should we set // features that affect a service? feature_list_.InitAndEnableFeature(leveldb::kLevelDBRewriteFeature); - ServiceTest::SetUp(); connector()->BindInterface("filesystem", &files_); connector()->BindInterface("leveldb", &leveldb_); } - void TearDown() override { - leveldb_.reset(); - files_.reset(); - ServiceTest::TearDown(); - } - // Note: This has an out parameter rather than returning the |DirectoryPtr|, // since |ASSERT_...()| doesn't work with return values. void GetTempDirectory(filesystem::mojom::DirectoryPtr* directory) { @@ -167,6 +167,10 @@ mojom::LevelDBServicePtr& leveldb() { return leveldb_; } private: + base::test::ScopedTaskEnvironment task_environment_; + service_manager::TestServiceManager test_service_manager_; + service_manager::TestService test_service_; + base::test::ScopedFeatureList feature_list_; filesystem::mojom::FileSystemPtr files_; mojom::LevelDBServicePtr leveldb_;
diff --git a/components/services/leveldb/main.cc b/components/services/leveldb/main.cc index 6733f1ae..51a0b2a 100644 --- a/components/services/leveldb/main.cc +++ b/components/services/leveldb/main.cc
@@ -3,11 +3,18 @@ // found in the LICENSE file. #include "services/service_manager/public/c/main.h" -#include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" #include "components/services/leveldb/leveldb_app.h" -#include "services/service_manager/public/cpp/service_runner.h" +#include "mojo/public/cpp/system/message_pipe.h" +#include "services/service_manager/public/mojom/service.mojom.h" -MojoResult ServiceMain(MojoHandle application_request) { - service_manager::ServiceRunner runner(new leveldb::LevelDBApp()); - return runner.Run(application_request); +MojoResult ServiceMain(MojoHandle service_request_handle) { + base::MessageLoop message_loop; + base::RunLoop run_loop; + leveldb::LevelDBApp service{service_manager::mojom::ServiceRequest( + mojo::MakeScopedHandle(mojo::MessagePipeHandle(service_request_handle)))}; + service.set_termination_closure(run_loop.QuitClosure()); + run_loop.Run(); + return MOJO_RESULT_OK; }
diff --git a/components/services/leveldb/remote_iterator_unittest.cc b/components/services/leveldb/remote_iterator_unittest.cc index 34e75b71..a209a46 100644 --- a/components/services/leveldb/remote_iterator_unittest.cc +++ b/components/services/leveldb/remote_iterator_unittest.cc
@@ -7,11 +7,14 @@ #include "base/bind.h" #include "base/macros.h" #include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" +#include "components/services/leveldb/leveldb_service_unittests_catalog_source.h" #include "components/services/leveldb/public/cpp/remote_iterator.h" #include "components/services/leveldb/public/cpp/util.h" #include "components/services/leveldb/public/interfaces/leveldb.mojom.h" -#include "services/service_manager/public/cpp/service_context.h" -#include "services/service_manager/public/cpp/service_test.h" +#include "services/service_manager/public/cpp/test/test_service.h" +#include "services/service_manager/public/cpp/test/test_service_manager.h" +#include "testing/gtest/include/gtest/gtest.h" namespace leveldb { namespace { @@ -39,15 +42,18 @@ quit_closure); } -class RemoteIteratorTest : public service_manager::test::ServiceTest { +class RemoteIteratorTest : public testing::Test { public: - RemoteIteratorTest() : ServiceTest("leveldb_service_unittests") {} - ~RemoteIteratorTest() override {} + RemoteIteratorTest() + : test_service_manager_(test::CreateTestCatalog()), + test_service_(test_service_manager_.RegisterTestInstance( + "leveldb_service_unittests")) {} + ~RemoteIteratorTest() override = default; protected: - // Overridden from mojo::test::ApplicationTestBase: + service_manager::Connector* connector() { return test_service_.connector(); } + void SetUp() override { - ServiceTest::SetUp(); connector()->BindInterface("leveldb", &leveldb_); mojom::DatabaseError error; @@ -73,15 +79,14 @@ } } - void TearDown() override { - leveldb_.reset(); - ServiceTest::TearDown(); - } - mojom::LevelDBServicePtr& leveldb() { return leveldb_; } mojom::LevelDBDatabaseAssociatedPtr& database() { return database_; } private: + base::test::ScopedTaskEnvironment task_environment_; + service_manager::TestServiceManager test_service_manager_; + service_manager::TestService test_service_; + mojom::LevelDBServicePtr leveldb_; mojom::LevelDBDatabaseAssociatedPtr database_;
diff --git a/components/signin/core/browser/about_signin_internals.cc b/components/signin/core/browser/about_signin_internals.cc index d5b387c..2139af7 100644 --- a/components/signin/core/browser/about_signin_internals.cc +++ b/components/signin/core/browser/about_signin_internals.cc
@@ -29,6 +29,7 @@ #include "components/signin/core/browser/signin_switches.h" #include "google_apis/gaia/oauth2_token_service_delegate.h" #include "net/base/backoff_entry.h" +#include "services/identity/public/cpp/identity_manager.h" namespace { @@ -188,12 +189,14 @@ AboutSigninInternals::AboutSigninInternals( ProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker, + identity::IdentityManager* identity_manager, SigninManagerBase* signin_manager, SigninErrorController* signin_error_controller, GaiaCookieManagerService* cookie_manager_service, signin::AccountConsistencyMethod account_consistency) : token_service_(token_service), account_tracker_(account_tracker), + identity_manager_(identity_manager), signin_manager_(signin_manager), client_(nullptr), signin_error_controller_(signin_error_controller), @@ -308,7 +311,8 @@ RefreshSigninPrefs(); signin_error_controller_->AddObserver(this); - signin_manager_->AddObserver(this); + identity_manager_->AddObserver(this); + identity_manager_->AddDiagnosticsObserver(this); signin_manager_->AddSigninDiagnosticsObserver(this); token_service_->AddObserver(this); token_service_->AddDiagnosticsObserver(this); @@ -317,7 +321,8 @@ void AboutSigninInternals::Shutdown() { signin_error_controller_->RemoveObserver(this); - signin_manager_->RemoveObserver(this); + identity_manager_->RemoveObserver(this); + identity_manager_->RemoveDiagnosticsObserver(this); signin_manager_->RemoveSigninDiagnosticsObserver(this); token_service_->RemoveObserver(this); token_service_->RemoveDiagnosticsObserver(this); @@ -329,7 +334,7 @@ return; std::unique_ptr<base::DictionaryValue> signin_status_value = - signin_status_.ToValue(account_tracker_, signin_manager_, + signin_status_.ToValue(account_tracker_, identity_manager_, signin_error_controller_, token_service_, cookie_manager_service_, client_, account_consistency_); @@ -340,14 +345,14 @@ std::unique_ptr<base::DictionaryValue> AboutSigninInternals::GetSigninStatus() { return signin_status_.ToValue( - account_tracker_, signin_manager_, signin_error_controller_, + account_tracker_, identity_manager_, signin_error_controller_, token_service_, cookie_manager_service_, client_, account_consistency_); } void AboutSigninInternals::OnAccessTokenRequested( const std::string& account_id, const std::string& consumer_id, - const OAuth2TokenService::ScopeSet& scopes) { + const identity::ScopeSet& scopes) { TokenInfo* token = signin_status_.FindToken(account_id, consumer_id, scopes); if (token) { *token = TokenInfo(consumer_id, scopes); @@ -440,18 +445,18 @@ NotifyObservers(); } -void AboutSigninInternals::GoogleSigninFailed( +void AboutSigninInternals::OnPrimaryAccountSigninFailed( const GoogleServiceAuthError& error) { NotifyObservers(); } -void AboutSigninInternals::GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) { +void AboutSigninInternals::OnPrimaryAccountSet( + const AccountInfo& primary_account_info) { NotifyObservers(); } -void AboutSigninInternals::GoogleSignedOut(const std::string& account_id, - const std::string& username) { +void AboutSigninInternals::OnPrimaryAccountCleared( + const AccountInfo& primary_account_info) { NotifyObservers(); } @@ -589,7 +594,7 @@ std::unique_ptr<base::DictionaryValue> AboutSigninInternals::SigninStatus::ToValue( AccountTrackerService* account_tracker, - SigninManagerBase* signin_manager, + identity::IdentityManager* identity_manager, SigninErrorController* signin_error_controller, ProfileOAuth2TokenService* token_service, GaiaCookieManagerService* cookie_manager_service, @@ -605,15 +610,16 @@ signin_client->GetProductVersion()); AddSectionEntry(basic_info, "Account Consistency", GetAccountConsistencyDescription(account_consistency)); - AddSectionEntry(basic_info, "Signin Status", - signin_manager->IsAuthenticated() ? "Signed In" : "Not Signed In"); + AddSectionEntry( + basic_info, "Signin Status", + identity_manager->HasPrimaryAccount() ? "Signed In" : "Not Signed In"); OAuth2TokenServiceDelegate::LoadCredentialsState load_tokens_state = token_service->GetDelegate()->load_credentials_state(); AddSectionEntry(basic_info, "TokenService Load Status", TokenServiceLoadCredentialsStateToLabel(load_tokens_state)); - if (signin_manager->IsAuthenticated()) { - std::string account_id = signin_manager->GetAuthenticatedAccountId(); + if (identity_manager->HasPrimaryAccount()) { + std::string account_id = identity_manager->GetPrimaryAccountId(); AddSectionEntry(basic_info, SigninStatusFieldToLabel(signin_internals_util::ACCOUNT_ID), account_id); @@ -622,7 +628,7 @@ account_tracker->GetAccountInfo(account_id).gaia); AddSectionEntry(basic_info, SigninStatusFieldToLabel(signin_internals_util::USERNAME), - signin_manager->GetAuthenticatedAccountInfo().email); + identity_manager->GetPrimaryAccountInfo().email); if (signin_error_controller->HasError()) { const std::string error_account_id = signin_error_controller->error_account_id();
diff --git a/components/signin/core/browser/about_signin_internals.h b/components/signin/core/browser/about_signin_internals.h index 7004249..23aa4fd 100644 --- a/components/signin/core/browser/about_signin_internals.h +++ b/components/signin/core/browser/about_signin_internals.h
@@ -20,6 +20,11 @@ #include "components/signin/core/browser/signin_internals_util.h" #include "components/signin/core/browser/signin_manager.h" #include "google_apis/gaia/oauth2_token_service.h" +#include "services/identity/public/cpp/identity_manager.h" + +namespace identity { +class IdentityManager; +} class AccountTrackerService; class PrefRegistrySimple; @@ -38,8 +43,9 @@ public OAuth2TokenService::Observer, public OAuth2TokenService::DiagnosticsObserver, public GaiaCookieManagerService::Observer, - SigninManagerBase::Observer, - SigninErrorController::Observer { + SigninErrorController::Observer, + identity::IdentityManager::Observer, + identity::IdentityManager::DiagnosticsObserver { public: class Observer { public: @@ -53,6 +59,7 @@ AboutSigninInternals(ProfileOAuth2TokenService* token_service, AccountTrackerService* account_tracker, + identity::IdentityManager* identity_manager, SigninManagerBase* signin_manager, SigninErrorController* signin_error_controller, GaiaCookieManagerService* cookie_manager_service, @@ -181,7 +188,7 @@ // } std::unique_ptr<base::DictionaryValue> ToValue( AccountTrackerService* account_tracker, - SigninManagerBase* signin_manager, + identity::IdentityManager* identity_manager, SigninErrorController* signin_error_controller, ProfileOAuth2TokenService* token_service, GaiaCookieManagerService* cookie_manager_service_, @@ -194,11 +201,12 @@ const signin_internals_util::TimedSigninStatusField& field, const std::string& value) override; + // IdentityMager::DiagnosticsObserver implementations. + void OnAccessTokenRequested(const std::string& account_id, + const std::string& consumer_id, + const identity::ScopeSet& scopes) override; + // OAuth2TokenService::DiagnosticsObserver implementations. - void OnAccessTokenRequested( - const std::string& account_id, - const std::string& consumer_id, - const OAuth2TokenService::ScopeSet& scopes) override; void OnFetchAccessTokenComplete(const std::string& account_id, const std::string& consumer_id, const OAuth2TokenService::ScopeSet& scopes, @@ -217,12 +225,12 @@ void OnRefreshTokensLoaded() override; void OnEndBatchChanges() override; - // SigninManagerBase::Observer implementations. - void GoogleSigninFailed(const GoogleServiceAuthError& error) override; - void GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) override; - void GoogleSignedOut(const std::string& account_id, - const std::string& username) override; + // IdentityManager::Observer implementations. + void OnPrimaryAccountSigninFailed( + const GoogleServiceAuthError& error) override; + void OnPrimaryAccountSet(const AccountInfo& primary_account_info) override; + void OnPrimaryAccountCleared( + const AccountInfo& primary_account_info) override; void NotifyObservers(); @@ -235,6 +243,9 @@ // Weak pointer to the account tracker. AccountTrackerService* account_tracker_; + // Weak pointer to the identity manager. + identity::IdentityManager* identity_manager_; + // Weak pointer to the signin manager. SigninManagerBase* signin_manager_;
diff --git a/components/strings/components_chromium_strings_te.xtb b/components/strings/components_chromium_strings_te.xtb index fb4d21f3..da5b7756 100644 --- a/components/strings/components_chromium_strings_te.xtb +++ b/components/strings/components_chromium_strings_te.xtb
@@ -33,7 +33,8 @@ ఆపై "<ph name="NO_PREFETCH_DESCRIPTION" />" ఎంపికను తీసివేయండి. దీని వల్ల సమస్య పరిష్కారం కాకుంటే, మెరుగైన పనితీరు కోసం మీరు ఈ ఎంపికను మళ్లీ ఎంచుకోవాలని మేము సిఫార్సు చేస్తున్నాము.</translation> -<translation id="8187289872471304532"> అనువర్తనాలు > సిస్టమ్ ప్రాధాన్యతలు > నెట్వర్క్ > అధునాతనం > ప్రాక్సీలకు వెళ్లండి - మరియు ఎంచుకోబడిన ప్రాక్సీల ఎంపికను తీసివేయండి.</translation> +<translation id="8187289872471304532">ఇలా వెళ్లండి + అప్లికేషన్లు > సిస్టమ్ ప్రాధాన్యతలు > నెట్వర్క్ > అధునాతనం > ప్రాక్సీలు + ఏవైనా ప్రాక్సీలను ఎంపిక చేసుకుని ఉంటే వాటిని తొలగించండి.</translation> <translation id="8684913864886094367">Chromium సరిగ్గా షట్ డౌన్ కాలేదు.</translation> </translationbundle> \ No newline at end of file
diff --git a/components/strings/components_google_chrome_strings_te.xtb b/components/strings/components_google_chrome_strings_te.xtb index 8277bf7..2d28a8f 100644 --- a/components/strings/components_google_chrome_strings_te.xtb +++ b/components/strings/components_google_chrome_strings_te.xtb
@@ -34,6 +34,7 @@ > LAN సెట్టింగ్లకు వెళ్లండి మరియు "మీ LAN కోసం ప్రాక్సీ సర్వర్ను ఉపయోగించండి" ఎంపికను తీసివేయండి.</translation> -<translation id="8187289872471304532"> అనువర్తనాలు > సిస్టమ్ ప్రాధాన్యతలు > నెట్వర్క్ > అధునాతనం > ప్రాక్సీలకు వెళ్లండి - మరియు ఎంచుకోబడిన ప్రాక్సీల ఎంపికను తీసివేయండి.</translation> +<translation id="8187289872471304532">ఇలా వెళ్లండి + అప్లికేషన్లు > సిస్టమ్ ప్రాధాన్యతలు > నెట్వర్క్ > అధునాతనం > ప్రాక్సీలు + ఏవైనా ప్రాక్సీలను ఎంపిక చేసుకుని ఉంటే వాటిని తొలగించండి.</translation> </translationbundle> \ No newline at end of file
diff --git a/components/strings/components_strings_am.xtb b/components/strings/components_strings_am.xtb index cbdeb3e..c900c566 100644 --- a/components/strings/components_strings_am.xtb +++ b/components/strings/components_strings_am.xtb
@@ -583,7 +583,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />፣ <ph name="TYPE_2" />፣, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{እና 1 ተጨማሪ ድረ-ገጽ}one{እና # ተጨማሪ ድረ-ገጾች}other{እና # ተጨማሪ ድረ-ገጾች}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">የ<ph name="CREDIT_CARD" /> CVC ያስገቡ። ካረጋገጡ በኋላ የGoogle Payments መለያዎ ካርድ ዝርዝሮች ለዚህ ጣቢያ ይጋራሉ።</translation> <translation id="4923417429809017348">ገጹ ከማይታወቅ ቋንቋ ወደ <ph name="LANGUAGE_LANGUAGE" /> ተተርጉሟል</translation> <translation id="4923459931733593730">ክፍያ</translation> <translation id="4926049483395192435">መገለጽ አለበት።</translation> @@ -615,7 +614,6 @@ <translation id="5095208057601539847">ጠቅላይ ግዛት</translation> <translation id="5098332213681597508">ይህ ስም የመጣው ከእርስዎ የGoogle መለያ ነው።</translation> <translation id="5115563688576182185">(64-ቢት)</translation> -<translation id="5121084798328133320">ካረጋገጡ በኋላ የGoogle Payments መለያዎ ካርድ ዝርዝሮች ለዚህ ጣቢያ ይጋራሉ።</translation> <translation id="5128122789703661928">ይህ ስም ያለው ክፍለ-ጊዜ ለስረዛ ልክ ያልሆነ ነው።</translation> <translation id="5135404736266831032">አድራሻዎችን ያቀናብሩ...</translation> <translation id="5141240743006678641">የተመሳሰሉ የይለፍ ቃላት ከGoogle ምስክርነቶችዎ ጋር ያመሳስሉ</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">የእርስዎ ሰዓት ወደ ኋላ ቀርቷል</translation> <translation id="893332455753468063">ስም ያክሉ</translation> <translation id="8938939909778640821">ተቀባይነት ያላቸው የክሬዲት እና የቅድመ-ክፍያ ካርዶች</translation> -<translation id="8952525071319348207">የካርድ ዝርዝሮችዎን ለማዘመን የ<ph name="CREDIT_CARD" /> ማብቂያ ቀን እና CVC ያስገቡ። ካረጋገጡ በኋላ የGoogle Payments ካርድ ዝርዝሮችዎ ለዚህ ጣቢያ ይጋራል።</translation> <translation id="8957210676456822347">የተያዥ መግቢያ ፈቀዳ</translation> <translation id="8971063699422889582">የአገልጋይ እውቅና ማረጋገጫ ጊዜው አልፎበታል።</translation> <translation id="8975012916872825179">እንደ ስልክ ቁጥሮች፣ ኢሜይል አድራሻዎች እና የመላኪያ አድራሻዎች ያሉ መረጃዎችን ያካትታል</translation>
diff --git a/components/strings/components_strings_ar.xtb b/components/strings/components_strings_ar.xtb index 8557dc8..1d62086d 100644 --- a/components/strings/components_strings_ar.xtb +++ b/components/strings/components_strings_ar.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />، <ph name="TYPE_2" />، <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{وصفحة ويب واحدة إضافية}zero{و# صفحة ويب إضافية}two{وصفحتا ويب (#) إضافيتان}few{و# صفحات ويب إضافية}many{و# صفحة ويب إضافية}other{و# صفحة ويب إضافية}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">أدخل رمز التحقق من البطاقة (CVC) لـ <ph name="CREDIT_CARD" />. وبعد التأكيد، ستتم مشاركة تفاصيل البطاقة من حساب دفعات Google مع هذا الموقع.</translation> <translation id="4923417429809017348">تمت ترجمة هذه الصفحة من لغة غير معروفة إلى اللغة <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">الدفع</translation> <translation id="4926049483395192435">يجب تحديدها.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">الإقليم</translation> <translation id="5098332213681597508">هذا الاسم من حسابك على Google.</translation> <translation id="5115563688576182185">(64 بت)</translation> -<translation id="5121084798328133320">بعد التأكيد، ستتم مشاركة تفاصيل البطاقة من حساب دفعات Google مع هذا الموقع.</translation> <translation id="5128122789703661928">الجلسة التي تحمل هذا الاسم غير صالحة للحذف.</translation> <translation id="5135404736266831032">إدارة العناوين...</translation> <translation id="5141240743006678641">تشفير كلمات المرور المتزامنة باستخدام بيانات اعتماد Google</translation> @@ -1148,7 +1146,6 @@ <translation id="8932102934695377596">توقيت ساعتك متأخر عن الوقت الحالي</translation> <translation id="893332455753468063">إضافة اسم</translation> <translation id="8938939909778640821">بطاقات الائتمان وبطاقات الدفع المسبق المقبولة</translation> -<translation id="8952525071319348207">أدخل تاريخ انتهاء الصلاحية ورمز التحقق من البطاقة (CVC) لـ <ph name="CREDIT_CARD" /> لتحديث تفاصيل بطاقتك. وبعد التأكيد، ستتم مشاركة تفاصيل البطاقة من حساب دفعات Google مع هذا الموقع.</translation> <translation id="8957210676456822347">تفويض المدخل المقيد</translation> <translation id="8971063699422889582">انتهت صلاحية شهادة الخادم.</translation> <translation id="8975012916872825179">يتضمن معلومات مثل أرقام الهواتف وعناوين البريد الإلكتروني وعناوين الشحن.</translation>
diff --git a/components/strings/components_strings_bg.xtb b/components/strings/components_strings_bg.xtb index cc1837e..e1e829a 100644 --- a/components/strings/components_strings_bg.xtb +++ b/components/strings/components_strings_bg.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" /> и <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{и още 1 уеб страница}other{и още # уеб страници}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Въведете кода за проверка за <ph name="CREDIT_CARD" />. След като потвърдите картата си, данните за нея от профила ви в Google Payments ще бъдат споделени с този сайт.</translation> <translation id="4923417429809017348">Тази страница е преведена от непознат език на <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Плащане</translation> <translation id="4926049483395192435">Трябва да се посочи.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Провинция</translation> <translation id="5098332213681597508">Това име е от профила ви в Google.</translation> <translation id="5115563688576182185">(64 бита)</translation> -<translation id="5121084798328133320">След като потвърдите картата си, данните за нея от профила ви в Google Payments ще бъдат споделени с този сайт.</translation> <translation id="5128122789703661928">Сесията с това име не е валидна за изтриване.</translation> <translation id="5135404736266831032">Управление на адресите...</translation> <translation id="5141240743006678641">Синхронизираните пароли да се шифроват с идентификационните ви данни за Google</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">Часовникът ви е назад</translation> <translation id="893332455753468063">Добавяне на име</translation> <translation id="8938939909778640821">Приемани кредитни и предплатени карти</translation> -<translation id="8952525071319348207">Въведете датата на валидност и кода за проверка за <ph name="CREDIT_CARD" />, за да актуализирате данните за картата си. След като я потвърдите, данните за нея от профила ви в Google Payments ще бъдат споделени с този сайт.</translation> <translation id="8957210676456822347">Упълномощаване в портал за удостоверяване</translation> <translation id="8971063699422889582">Сертификатът на сървъра е с изтекла валидност.</translation> <translation id="8975012916872825179">Включва информация като телефонни номера, имейл адреси и адреси за доставка</translation>
diff --git a/components/strings/components_strings_bn.xtb b/components/strings/components_strings_bn.xtb index 391ceb1..6c73365 100644 --- a/components/strings/components_strings_bn.xtb +++ b/components/strings/components_strings_bn.xtb
@@ -585,7 +585,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{এবং আরও ১টি ওয়েব পৃষ্ঠা}one{এবং আরও #টি ওয়েব পৃষ্ঠা}other{এবং আরও #টি ওয়েব পৃষ্ঠা}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947"><ph name="CREDIT_CARD" /> এর জন্য সিভিসি লিখুন। আপনি নিশ্চিত করার পর আপনার Google অর্থ প্রদান অ্যাকাউন্ট থেকে কার্ডের বিবরণ এই সাইটে শেয়ার করা হবে।</translation> <translation id="4923417429809017348">এই পৃষ্ঠাটি কোন অজানা ভাষা থেকে <ph name="LANGUAGE_LANGUAGE" />-এ অনুবাদ করা হয়েছে</translation> <translation id="4923459931733593730">অর্থপ্রদান</translation> <translation id="4926049483395192435">নির্দিষ্ট করা উচিত৷</translation> @@ -617,7 +616,6 @@ <translation id="5095208057601539847">প্রদেশ</translation> <translation id="5098332213681597508">এই নামটি আপনার Google অ্যাকাউন্ট থেকে।</translation> <translation id="5115563688576182185">(৬৪-বিট)</translation> -<translation id="5121084798328133320">আপনি নিশ্চিত করার পর আপনার Google অর্থ প্রদান অ্যাকাউন্ট থেকে কার্ডের বিবরণ এই সাইটে শেয়ার করা হবে।</translation> <translation id="5128122789703661928">এই নামের সেশনটি মুছে ফেলার জন্য সঠিক নয়।</translation> <translation id="5135404736266831032">ঠিকানাগুলি পরিচালনা করুন...</translation> <translation id="5141240743006678641">আপনার Google শংসাপত্রের সাথে সিঙ্ক করা পাসওয়ার্ডগুলি এনক্রিপ্ট করুন৷</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">আপনার ঘড়ির সময় পিছিয়ে রয়েছে</translation> <translation id="893332455753468063">নাম যোগ করুন</translation> <translation id="8938939909778640821">ক্রেডিট ও প্রিপেড কার্ড গ্রহণ করা হয়</translation> -<translation id="8952525071319348207">আপনার কার্ডের বিবরণ আপডেট করতে <ph name="CREDIT_CARD" /> এর জন্য মেয়াদ শেষের তারিখ এবং সিভিসি লিখুন। আপনি নিশ্চিত করার পর আপনার Google অর্থ প্রদান অ্যাকাউন্ট থেকে কার্ডের বিবরণ এই সাইটে শেয়ার করা হবে।</translation> <translation id="8957210676456822347">ক্যাপটিভ পোর্টাল অনুমোদন</translation> <translation id="8971063699422889582">সার্ভারের শংসাপত্রের মেয়াদ ফুরিয়েছে৷</translation> <translation id="8975012916872825179">ফোন নম্বর, ইমেল আইডি এবং শিপিং ঠিকানার মতো তথ্য এতে আছে</translation>
diff --git a/components/strings/components_strings_ca.xtb b/components/strings/components_strings_ca.xtb index d8e8694a..cbce2af 100644 --- a/components/strings/components_strings_ca.xtb +++ b/components/strings/components_strings_ca.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{i 1 pàgina web més}other{i # pàgines web més}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Introdueix el CVC de la targeta <ph name="CREDIT_CARD" />. Un cop confirmada, els detalls de la targeta del compte de pagaments de Google es compartirà amb aquest lloc web.</translation> <translation id="4923417429809017348">Aquesta pàgina s'ha traduït des d'un idioma desconegut a: <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Pagament</translation> <translation id="4926049483395192435">S'ha d'especificar.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Província</translation> <translation id="5098332213681597508">Aquest nom prové del teu Compte de Google.</translation> <translation id="5115563688576182185">(64 bits)</translation> -<translation id="5121084798328133320">Un cop confirmada, els detalls de la targeta del teu compte de pagaments de Google es compartiran amb aquest lloc web.</translation> <translation id="5128122789703661928">La sessió amb aquest nom no es pot suprimir.</translation> <translation id="5135404736266831032">Gestiona les adreces...</translation> <translation id="5141240743006678641">Encripta contrasenyes sincronitzades amb les vostres credencials de Google</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">El rellotge està endarrerit</translation> <translation id="893332455753468063">Afegeix un nom</translation> <translation id="8938939909778640821">Targetes de crèdit i de prepagament acceptades</translation> -<translation id="8952525071319348207">Introdueix la data de caducitat i el CVC de la targeta <ph name="CREDIT_CARD" /> per actualitzar-ne els detalls. Un cop confirmada, els detalls de la targeta del compte de pagaments de Google es compartiran amb aquest lloc web.</translation> <translation id="8957210676456822347">Autorització de portals captius</translation> <translation id="8971063699422889582">El certificat del servidor ha caducat.</translation> <translation id="8975012916872825179">Inclou informació com ara números de telèfon, adreces electròniques i adreces d'enviament</translation>
diff --git a/components/strings/components_strings_cs.xtb b/components/strings/components_strings_cs.xtb index 0620526..b81e5db 100644 --- a/components/strings/components_strings_cs.xtb +++ b/components/strings/components_strings_cs.xtb
@@ -75,6 +75,7 @@ <translation id="1339601241726513588">Doména registrace:</translation> <translation id="1340482604681802745">Adresa vyzvednutí</translation> <translation id="1348198688976932919">Web, na který se chystáte přejít, obsahuje nebezpečné aplikace</translation> +<translation id="1348779747280417563">Potvrdit jméno</translation> <translation id="1374468813861204354">návrhy</translation> <translation id="1375198122581997741">O verzi aplikace</translation> <translation id="1376836354785490390">Zobrazit méně</translation> @@ -452,6 +453,7 @@ <translation id="3949601375789751990">Zde se zobrazuje vaše historie prohlížení</translation> <translation id="3950820424414687140">Přihlaste se</translation> <translation id="3963721102035795474">Režim čtečky</translation> +<translation id="3963837677003247395">Pokračovat ručně?</translation> <translation id="3964661563329879394">{COUNT,plural, =0{Žádné}=1{Z 1 webu }few{Z # webů }many{Z # webu }other{Z # webů }}</translation> <translation id="397105322502079400">Probíhá výpočet…</translation> <translation id="3973234410852337861">Web <ph name="HOST_NAME" /> je blokován</translation> @@ -580,7 +582,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{a 1 další webová stránka}few{a # další webové stránky}many{a # další webové stránky}other{a # dalších webových stránek}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Zadejte kód CVC karty <ph name="CREDIT_CARD" />. Po ověření budou údaje o kartě z vašeho účtu Google Payments poskytnuty tomuto webu.</translation> <translation id="4923417429809017348">Tato stránka byla přeložena z neznámého jazyka do jazyka <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Platba</translation> <translation id="4926049483395192435">Musí být uvedeno</translation> @@ -612,7 +613,6 @@ <translation id="5095208057601539847">Provincie</translation> <translation id="5098332213681597508">Tento název pochází z vašeho účtu Google.</translation> <translation id="5115563688576182185">(64bitový)</translation> -<translation id="5121084798328133320">Po ověření budou údaje o kartě z vašeho účtu Google Payments poskytnuty tomuto webu.</translation> <translation id="5128122789703661928">Relace s tímto názvem není pro smazání platná.</translation> <translation id="5135404736266831032">Spravovat adresy...</translation> <translation id="5141240743006678641">Šifrovat synchronizovaná hesla pomocí hesla k účtu Google</translation> @@ -808,6 +808,7 @@ <translation id="6569060085658103619">Prohlížíte si stránku rozšíření</translation> <translation id="6596325263575161958">Možnosti šifrování</translation> <translation id="6604181099783169992">Senzory pohybu nebo světla</translation> +<translation id="6607617806003952240">Dále vám pomoci nemůžu, pokračujte ručně.</translation> <translation id="6624427990725312378">Kontaktní údaje</translation> <translation id="6626291197371920147">Přidání platného čísla karty</translation> <translation id="6628463337424475685">Vyhledávání <ph name="ENGINE" /></translation> @@ -851,6 +852,7 @@ <translation id="6950684638814147129">Při analýze hodnoty JSON došlo k chybě: <ph name="ERROR" /></translation> <translation id="6957624206566198865">Otevřete stránku na nové anonymní kartě</translation> <translation id="6957887021205513506">Zdá se, že certifikát serveru je podvrh.</translation> +<translation id="6964255747740675745">Konfiguraci sítě se nepodařilo analyzovat (neplatná data JSON).</translation> <translation id="6965382102122355670">OK</translation> <translation id="6965978654500191972">Zařízení</translation> <translation id="6970216967273061347">Obvod</translation> @@ -1142,13 +1144,14 @@ <translation id="8932102934695377596">Vaše hodiny se zpožďují</translation> <translation id="893332455753468063">Přidání jména</translation> <translation id="8938939909778640821">Přijímané kreditní a předplacené karty</translation> -<translation id="8952525071319348207">Chcete-li aktualizovat údaje o kartě, zadejte datum vypršení platnosti a kód CVC karty <ph name="CREDIT_CARD" />. Po ověření budou údaje o kartě z vašeho účtu Google Payments poskytnuty tomuto webu.</translation> <translation id="8957210676456822347">Autorizace captive portálu</translation> +<translation id="8968766641738584599">Uložit kartu</translation> <translation id="8971063699422889582">Platnost certifikátu serveru vypršela.</translation> <translation id="8975012916872825179">Zahrnuje informace jako telefonní čísla, e-mailové adresy a dodací adresy</translation> <translation id="8978053250194585037">Služba Bezpečné prohlížení Google nedávno na webu <ph name="SITE" /> <ph name="BEGIN_LINK" />zjistila phishing<ph name="END_LINK" />. Phishingové weby se vás snaží oklamat tím, že se vydávají za jiné weby.</translation> <translation id="8983003182662520383">Platební metody a adresy pomocí služby Google Pay</translation> <translation id="8987927404178983737">Měsíc</translation> +<translation id="8988408250700415532">Něco se pokazilo. Objednávku můžete dokončit na webu.</translation> <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation> <translation id="8996941253935762404">Web, na který se chystáte přejít, obsahuje škodlivé programy</translation> <translation id="8997023839087525404">Server předložil certifikát, který nebyl zveřejněn v souladu se zásadou Certificate Transparency. U některých certifikátů je to z důvodu kontroly důvěryhodnosti a ochrany před útočníky vyžadováno.</translation>
diff --git a/components/strings/components_strings_da.xtb b/components/strings/components_strings_da.xtb index 08e67c73..39c0e719 100644 --- a/components/strings/components_strings_da.xtb +++ b/components/strings/components_strings_da.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{og 1 anden webside}one{og # anden webside}other{og # andre websider}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Angiv kontrolkoden for <ph name="CREDIT_CARD" />. Når du bekræfter, deles kortoplysningerne på din konto i Google Payments med dette website.</translation> <translation id="4923417429809017348">Denne side er oversat fra et ukendt sprog til <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Betaling</translation> <translation id="4926049483395192435">Skal angives.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Provins</translation> <translation id="5098332213681597508">Dette navn er fra din Google-konto.</translation> <translation id="5115563688576182185">(64-bit)</translation> -<translation id="5121084798328133320">Når du bekræfter, deles kortoplysningerne på din konto i Google Payments med dette website.</translation> <translation id="5128122789703661928">Sessionen med dette navn kan ikke slettes.</translation> <translation id="5135404736266831032">Administrer adresser...</translation> <translation id="5141240743006678641">Krypter synkroniserede adgangskoder med dine Google-loginoplysninger</translation> @@ -1148,7 +1146,6 @@ <translation id="8932102934695377596">Dit ur er bagud</translation> <translation id="893332455753468063">Tilføj navn</translation> <translation id="8938939909778640821">Accepterede betalingskort</translation> -<translation id="8952525071319348207">Opdater dine kortoplysninger ved at indtaste udløbsdatoen og kontrolkoden for <ph name="CREDIT_CARD" />. Når du bekræfter, deles kortoplysningerne på din konto i Google Payments med dette website.</translation> <translation id="8957210676456822347">Godkendelse af captive portal</translation> <translation id="8971063699422889582">Serverens certifikat er udløbet.</translation> <translation id="8975012916872825179">Omfatter oplysninger såsom telefonnumre, mailadresser og leveringsadresser</translation>
diff --git a/components/strings/components_strings_de.xtb b/components/strings/components_strings_de.xtb index db92cd7..2a325f1 100644 --- a/components/strings/components_strings_de.xtb +++ b/components/strings/components_strings_de.xtb
@@ -583,7 +583,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{und 1 weitere Webseite}other{und # weitere Webseiten}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Geben Sie den CVC für <ph name="CREDIT_CARD" /> ein. Nach erfolgter Bestätigung werden die Kartendetails Ihres Google Payments-Kontos an diese Website weitergegeben.</translation> <translation id="4923417429809017348">Diese Seite wurde von einer unbekannten Sprache in <ph name="LANGUAGE_LANGUAGE" /> übersetzt.</translation> <translation id="4923459931733593730">Zahlung</translation> <translation id="4926049483395192435">Angabe erforderlich</translation> @@ -615,7 +614,6 @@ <translation id="5095208057601539847">Provinz</translation> <translation id="5098332213681597508">Dieser Name stammt aus Ihrem Google-Konto.</translation> <translation id="5115563688576182185">(64-Bit)</translation> -<translation id="5121084798328133320">Nach erfolgter Bestätigung werden die Kartendetails Ihres Google Payments-Kontos an diese Website weitergegeben.</translation> <translation id="5128122789703661928">Die Sitzung mit diesem Namen kann nicht gelöscht werden.</translation> <translation id="5135404736266831032">Adressen verwalten…</translation> <translation id="5141240743006678641">Synchronisierte Passwörter mit Ihren Google-Anmeldeinformationen verschlüsseln</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">Ihre Uhr geht nach.</translation> <translation id="893332455753468063">Namen hinzufügen</translation> <translation id="8938939909778640821">Akzeptierte Kredit- und Prepaidkarten</translation> -<translation id="8952525071319348207">Geben Sie das Ablaufdatum und den CVC für <ph name="CREDIT_CARD" /> ein, um Ihre Kartendetails zu aktualisieren. Nach erfolgter Bestätigung werden die Kartendetails Ihres Google Payments-Kontos an diese Website weitergegeben.</translation> <translation id="8957210676456822347">Erfassungsportal-Autorisierung</translation> <translation id="8971063699422889582">Das Serverzertifikat ist abgelaufen.</translation> <translation id="8975012916872825179">Enthält Informationen wie Telefonnummern, E-Mail-Adressen und Lieferadressen</translation>
diff --git a/components/strings/components_strings_el.xtb b/components/strings/components_strings_el.xtb index 9b7f99e7..a76e753 100644 --- a/components/strings/components_strings_el.xtb +++ b/components/strings/components_strings_el.xtb
@@ -75,6 +75,7 @@ <translation id="1339601241726513588">Τομέας εγγραφής:</translation> <translation id="1340482604681802745">Διεύθυνση παραλαβής</translation> <translation id="1348198688976932919">Ο ιστότοπος που πρόκειται να επισκεφτείτε περιέχει επικίνδυνες εφαρμογές</translation> +<translation id="1348779747280417563">Επιβεβαίωση ονόματος</translation> <translation id="1374468813861204354">προτάσεις</translation> <translation id="1375198122581997741">Σχετικά με την έκδοση</translation> <translation id="1376836354785490390">Εμφάνιση λιγότερων</translation> @@ -456,6 +457,7 @@ <translation id="3949601375789751990">Το ιστορικό περιήγησής σας εμφανίζεται εδώ</translation> <translation id="3950820424414687140">Σύνδεση</translation> <translation id="3963721102035795474">Λειτουργία αναγνώστη</translation> +<translation id="3963837677003247395">Συνέχεια με μη αυτόματο τρόπο;</translation> <translation id="3964661563329879394">{COUNT,plural, =0{Κανένα}=1{Από 1 ιστότοπο }other{Από # ιστοτόπους }}</translation> <translation id="397105322502079400">Υπολογισμός…</translation> <translation id="3973234410852337861">Ο κεντρικός υπολογιστής <ph name="HOST_NAME" /> είναι αποκλεισμένος</translation> @@ -585,7 +587,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{και 1 ακόμη ιστοσελίδα}other{και # ακόμη ιστοσελίδες}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Εισαγάγετε τον κωδικό CVC για την πιστωτική κάρτα <ph name="CREDIT_CARD" />. Μετά την επιβεβαίωση, τα στοιχεία της κάρτας από τον λογαριασμό πληρωμών Google θα κοινοποιηθούν σε αυτόν τον ιστότοπο.</translation> <translation id="4923417429809017348">Αυτή η σελίδα έχει μεταφραστεί από μια άγνωστη γλώσσας στα <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Πληρωμή</translation> <translation id="4926049483395192435">Πρέπει να καθοριστεί.</translation> @@ -617,7 +618,6 @@ <translation id="5095208057601539847">Επαρχία</translation> <translation id="5098332213681597508">Αυτό το όνομα προέρχεται από τον Λογαριασμό σας Google.</translation> <translation id="5115563688576182185">(64-bit)</translation> -<translation id="5121084798328133320">Μετά την επιβεβαίωση, τα στοιχεία της κάρτας από τον λογαριασμό πληρωμών Google θα κοινοποιηθούν σε αυτόν τον ιστότοπο.</translation> <translation id="5128122789703661928">Η περίοδος σύνδεσης με αυτό το όνομα δεν είναι έγκυρη για διαγραφή.</translation> <translation id="5135404736266831032">Διαχείριση διευθύνσεων…</translation> <translation id="5141240743006678641">Κρυπτογραφήστε συγχρονισμένους κωδικούς πρόσβασης με τα διαπιστευτήριά σας Google.</translation> @@ -814,6 +814,7 @@ <translation id="6569060085658103619">Βλέπετε μια σελίδα επέκτασης</translation> <translation id="6596325263575161958">Επιλογές κρυπτογράφησης</translation> <translation id="6604181099783169992">Αισθητήρες κίνησης ή φωτός</translation> +<translation id="6607617806003952240">Δεν μπορώ να σας προσφέρω περαιτέρω βοήθεια. Θα πρέπει να συνεχίσετε με μη αυτόματο τρόπο.</translation> <translation id="6624427990725312378">Στοιχεία επικοινωνίας</translation> <translation id="6626291197371920147">Προσθήκη έγκυρου αριθμού κάρτας</translation> <translation id="6628463337424475685">Αναζήτηση <ph name="ENGINE" /></translation> @@ -857,6 +858,7 @@ <translation id="6950684638814147129">Σφάλμα κατά την ανάλυση της τιμής JSON: <ph name="ERROR" /></translation> <translation id="6957624206566198865">Ανοίξτε τη σελίδα σε μια νέα καρτέλα ιδιωτικής περιήγησης</translation> <translation id="6957887021205513506">Το πιστοποιητικό του διακομιστή φαίνεται να είναι πλαστό.</translation> +<translation id="6964255747740675745">Απέτυχε η ανάλυση της διαμόρφωσης δικτύου (μη έγκυρο JSON).</translation> <translation id="6965382102122355670">OK</translation> <translation id="6965978654500191972">Συσκευή</translation> <translation id="6970216967273061347">Περιοχή</translation> @@ -1149,13 +1151,14 @@ <translation id="8932102934695377596">Το ρολόι σας πάει πίσω</translation> <translation id="893332455753468063">Προσθήκη ονόματος</translation> <translation id="8938939909778640821">Αποδεκτές πιστωτικές και προπληρωμένες κάρτες</translation> -<translation id="8952525071319348207">Καταχωρίστε την ημερομηνία λήξης και τον κωδικό CVC για την πιστωτική κάρτα <ph name="CREDIT_CARD" />, προκειμένου να ενημερώσετε τα στοιχεία της κάρτας σας. Μετά την επιβεβαίωση, τα στοιχεία της κάρτας από τον λογαριασμό πληρωμών Google θα κοινοποιηθούν σε αυτόν τον ιστότοπο.</translation> <translation id="8957210676456822347">Εξουσιοδότηση πύλης υποδοχής</translation> +<translation id="8968766641738584599">Αποθήκευση κάρτας</translation> <translation id="8971063699422889582">Το πιστοποιητικό του διακομιστή έχει λήξει.</translation> <translation id="8975012916872825179">Περιλαμβάνει πληροφορίες, όπως αριθμούς τηλεφώνου, διευθύνσεις ηλεκτρονικού ταχυδρομείου και διευθύνσεις αποστολής</translation> <translation id="8978053250194585037">Πρόσφατα, η Ασφαλής περιήγηση Google <ph name="BEGIN_LINK" />εντόπισε εκδηλώσεις ηλεκτρονικού ψαρέματος (phishing)<ph name="END_LINK" /> στον ιστότοπο <ph name="SITE" />. Οι ιστότοποι ηλεκτρονικού ψαρέματος (phishing) παρουσιάζονται ψευδώς σαν άλλου τύπου ιστότοποι, για να σας εξαπατήσουν.</translation> <translation id="8983003182662520383">Τρόποι πληρωμής και διευθύνσεις που χρησιμοποιούν το Google Pay</translation> <translation id="8987927404178983737">Μήνας</translation> +<translation id="8988408250700415532">Παρουσιάστηκε κάποιο πρόβλημα. Μπορείτε να ολοκληρώσετε την παραγγελία σας στον ιστότοπο.</translation> <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation> <translation id="8996941253935762404">Ο ιστότοπος που πρόκειται να επισκεφτείτε περιέχει κακόβουλα προγράμματα</translation> <translation id="8997023839087525404">Ο διακομιστής παρουσίασε ένα πιστοποιητικό το οποίο δεν αποκαλύφθηκε δημοσίως με χρήση της πολιτικής Διαφάνειας πιστοποιητικών. Αυτό απαιτείται για ορισμένα πιστοποιητικά, προκειμένου να διασφαλιστεί ότι είναι αξιόπιστα και παρέχουν προστασία ενάντια σε εισβολείς.</translation>
diff --git a/components/strings/components_strings_en-GB.xtb b/components/strings/components_strings_en-GB.xtb index 661d9aa..a10c671 100644 --- a/components/strings/components_strings_en-GB.xtb +++ b/components/strings/components_strings_en-GB.xtb
@@ -75,6 +75,7 @@ <translation id="1339601241726513588">Enrolment domain:</translation> <translation id="1340482604681802745">Pickup address</translation> <translation id="1348198688976932919">The site ahead contains dangerous apps</translation> +<translation id="1348779747280417563">Confirm name</translation> <translation id="1374468813861204354">suggestions</translation> <translation id="1375198122581997741">About Version</translation> <translation id="1376836354785490390">Show Less</translation> @@ -456,6 +457,7 @@ <translation id="3949601375789751990">Your browsing history appears here</translation> <translation id="3950820424414687140">Sign in</translation> <translation id="3963721102035795474">Reader Mode</translation> +<translation id="3963837677003247395">Continue manually?</translation> <translation id="3964661563329879394">{COUNT,plural, =0{None}=1{From 1 site }other{From # sites }}</translation> <translation id="397105322502079400">Calculating...</translation> <translation id="3973234410852337861"><ph name="HOST_NAME" /> is blocked</translation> @@ -584,7 +586,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{and 1 more web page}other{and # more web pages}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Enter the CVC for <ph name="CREDIT_CARD" />. After you confirm, card details from your Google Payments account will be shared with this site.</translation> <translation id="4923417429809017348">This page has been translated from an unknown language into <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Payment</translation> <translation id="4926049483395192435">Must be specified.</translation> @@ -616,7 +617,6 @@ <translation id="5095208057601539847">Province</translation> <translation id="5098332213681597508">This name is from your Google account.</translation> <translation id="5115563688576182185">(64-bit)</translation> -<translation id="5121084798328133320">After you confirm, card details from your Google Payments account will be shared with this site.</translation> <translation id="5128122789703661928">The session with this name is not valid for deletion.</translation> <translation id="5135404736266831032">Manage addresses...</translation> <translation id="5141240743006678641">Encrypt synced passwords with your Google credentials</translation> @@ -813,6 +813,7 @@ <translation id="6569060085658103619">You're viewing an extension page</translation> <translation id="6596325263575161958">Encryption options</translation> <translation id="6604181099783169992">Motion or light sensors</translation> +<translation id="6607617806003952240">I cannot help anymore, please continue manually.</translation> <translation id="6624427990725312378">Contact Info</translation> <translation id="6626291197371920147">Add valid card number</translation> <translation id="6628463337424475685"><ph name="ENGINE" /> Search</translation> @@ -856,6 +857,7 @@ <translation id="6950684638814147129">Error while parsing JSON value: <ph name="ERROR" /></translation> <translation id="6957624206566198865">Open page in a new Private tab</translation> <translation id="6957887021205513506">The server's certificate appears to be a forgery.</translation> +<translation id="6964255747740675745">Network configuration failed to be parsed (invalid JSON).</translation> <translation id="6965382102122355670">OK</translation> <translation id="6965978654500191972">Device</translation> <translation id="6970216967273061347">District</translation> @@ -1147,13 +1149,14 @@ <translation id="8932102934695377596">Your clock is behind</translation> <translation id="893332455753468063">Add Name</translation> <translation id="8938939909778640821">Accepted credit and prepaid cards</translation> -<translation id="8952525071319348207">Enter the expiry date and CVC for <ph name="CREDIT_CARD" /> to update your card details. After you confirm, card details from your Google Payments account will be shared with this site.</translation> <translation id="8957210676456822347">Captive Portal Authorisation</translation> +<translation id="8968766641738584599">Save card</translation> <translation id="8971063699422889582">Server's certificate has expired.</translation> <translation id="8975012916872825179">Includes information such as phone numbers, email addresses and delivery addresses</translation> <translation id="8978053250194585037">Google Safe Browsing recently <ph name="BEGIN_LINK" />detected phishing<ph name="END_LINK" /> on <ph name="SITE" />. Phishing sites pretend to be other websites to trick you.</translation> <translation id="8983003182662520383">Payment methods and addresses using Google Pay</translation> <translation id="8987927404178983737">Month</translation> +<translation id="8988408250700415532">Something went wrong. You can finish your order on the website.</translation> <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation> <translation id="8996941253935762404">The site ahead contains harmful programs</translation> <translation id="8997023839087525404">The server presented a certificate that was not publicly disclosed using the Certificate Transparency policy. This is a requirement for some certificates, to ensure that they are trustworthy and protect against attackers.</translation>
diff --git a/components/strings/components_strings_es-419.xtb b/components/strings/components_strings_es-419.xtb index 0f2bab9..882ff661 100644 --- a/components/strings/components_strings_es-419.xtb +++ b/components/strings/components_strings_es-419.xtb
@@ -585,7 +585,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{y 1 página web más}other{y # páginas web más}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Ingresa el CVC de la tarjeta <ph name="CREDIT_CARD" />. Después de confirmarla, los datos de tu cuenta en Google Payments se compartirán con este sitio.</translation> <translation id="4923417429809017348">Esta página ha sido traducida desde un idioma desconocido a <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Pago</translation> <translation id="4926049483395192435">Debe especificarse un valor.</translation> @@ -617,7 +616,6 @@ <translation id="5095208057601539847">Provincia</translation> <translation id="5098332213681597508">Este nombre es de tu cuenta de Google.</translation> <translation id="5115563688576182185">(64 bits)</translation> -<translation id="5121084798328133320">Después de que confirmes esta acción, los datos de tu cuenta de Google Payments se compartirán con este sitio.</translation> <translation id="5128122789703661928">La sesión con este nombre no se puede borrar.</translation> <translation id="5135404736266831032">Administrar direcciones…</translation> <translation id="5141240743006678641">Encriptar contraseñas sincronizadas con tus credenciales de Google</translation> @@ -1149,7 +1147,6 @@ <translation id="8932102934695377596">El reloj está atrasado</translation> <translation id="893332455753468063">Agregar nombre</translation> <translation id="8938939909778640821">Tarjetas de crédito y prepago aceptadas</translation> -<translation id="8952525071319348207">Ingresa la fecha de vencimiento y el CVC de la tarjeta <ph name="CREDIT_CARD" /> para actualizar los datos. Después de confirmar esta acción, esos datos se compartirán con este sitio.</translation> <translation id="8957210676456822347">Autorización de portal cautivo</translation> <translation id="8971063699422889582">El certificado del servidor ha caducado.</translation> <translation id="8975012916872825179">Incluye información, como números de teléfono, direcciones de correo electrónico y direcciones de envío</translation>
diff --git a/components/strings/components_strings_es.xtb b/components/strings/components_strings_es.xtb index d83afd7..a9468124 100644 --- a/components/strings/components_strings_es.xtb +++ b/components/strings/components_strings_es.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" /> y <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{ y 1 página web más}other{ y # páginas web más}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Introduce el CVC de <ph name="CREDIT_CARD" />. Una vez que confirmes esta acción, la información de la tarjeta de tu cuenta de pagos de Google se compartirá con este sitio web.</translation> <translation id="4923417429809017348">Esta página se ha traducido de un idioma desconocido al <ph name="LANGUAGE_LANGUAGE" />.</translation> <translation id="4923459931733593730">Pago</translation> <translation id="4926049483395192435">Se debe especificar un valor.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Provincia</translation> <translation id="5098332213681597508">Este nombre proviene de tu cuenta de Google.</translation> <translation id="5115563688576182185">(64 bits)</translation> -<translation id="5121084798328133320">Una vez que confirmes esta acción, la información de la tarjeta de tu cuenta de pagos de Google se compartirá con este sitio web.</translation> <translation id="5128122789703661928">No se puede eliminar la sesión con este nombre.</translation> <translation id="5135404736266831032">Gestiona tus direcciones...</translation> <translation id="5141240743006678641">Cifrar contraseñas sincronizadas con tus credenciales de Google</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">Tu reloj está atrasado</translation> <translation id="893332455753468063">Añade un nombre</translation> <translation id="8938939909778640821">Tarjetas prepago y de crédito aceptadas</translation> -<translation id="8952525071319348207">Introduce la fecha de vencimiento y el CVC de <ph name="CREDIT_CARD" /> para actualizar la información de tu tarjeta. Una vez que confirmes esta acción, la información de la tarjeta de tu cuenta de pagos de Google se compartirá con este sitio web.</translation> <translation id="8957210676456822347">Autorización de portal cautivo</translation> <translation id="8971063699422889582">El certificado del servidor ha caducado.</translation> <translation id="8975012916872825179">Incluye información como números de teléfono, direcciones de correo electrónico y direcciones de envío</translation>
diff --git a/components/strings/components_strings_et.xtb b/components/strings/components_strings_et.xtb index 9eb5631..685a853 100644 --- a/components/strings/components_strings_et.xtb +++ b/components/strings/components_strings_et.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{ja veel 1 veebileht}other{ja veel # veebilehte}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Sisestage krediitkaardi <ph name="CREDIT_CARD" /> CVC. Pärast kinnitamist jagatakse teie Google Paymentsi konto kaardi üksikasju selle saidiga.</translation> <translation id="4923417429809017348">Leht on tõlgitud teadmata keelest <ph name="LANGUAGE_LANGUAGE" /> keelde</translation> <translation id="4923459931733593730">Makse</translation> <translation id="4926049483395192435">Tuleb määrata.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Provints</translation> <translation id="5098332213681597508">Nimi pärineb teie Google'i kontolt.</translation> <translation id="5115563688576182185">(64-bitine)</translation> -<translation id="5121084798328133320">Pärast kinnitamist jagatakse teie Google Paymentsi konto kaardi üksikasju selle saidiga.</translation> <translation id="5128122789703661928">Selle nimega seanssi ei saa kustutada.</translation> <translation id="5135404736266831032">Halda aadresse …</translation> <translation id="5141240743006678641">Krüpteerige sünkroonitud paroolid oma Google'i mandaadiga</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">Teie kell on taga</translation> <translation id="893332455753468063">Nime lisamine</translation> <translation id="8938939909778640821">Aktsepteeritavad ettemakstud ja krediitkaardid</translation> -<translation id="8952525071319348207">Kaardi üksikasjade värskendamiseks sisestage krediitkaardi <ph name="CREDIT_CARD" /> aegumiskuupäev ja CVC. Kui selle kinnitate, jagatakse teie Google Paymentsi konto kaardi üksikasju selle saidiga.</translation> <translation id="8957210676456822347">Kontrollportaali volitamine</translation> <translation id="8971063699422889582">Serveri sertifikaat on aegunud.</translation> <translation id="8975012916872825179">Hõlmab näiteks telefoninumbreid, e-posti ja postiaadresse</translation>
diff --git a/components/strings/components_strings_fa.xtb b/components/strings/components_strings_fa.xtb index 1b187a09..fa01d081 100644 --- a/components/strings/components_strings_fa.xtb +++ b/components/strings/components_strings_fa.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />، <ph name="TYPE_2" />، <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{ و ۱ صفحه وب دیگر}one{ و # صفحه وب دیگر}other{ و # صفحه وب دیگر}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">CVC را برای <ph name="CREDIT_CARD" /> وارد کنید. بعد از تأیید، جزئیات کارت از حساب پرداختهای Google با این سایت همرسانی میشود.</translation> <translation id="4923417429809017348">این صفحه از یک زبان ناشناس به <ph name="LANGUAGE_LANGUAGE" /> ترجمه شده است.</translation> <translation id="4923459931733593730">پرداخت</translation> <translation id="4926049483395192435">باید مشخص شود.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">استان</translation> <translation id="5098332213681597508">این نام از حساب Google شما گرفته شده است.</translation> <translation id="5115563688576182185">(۶۴ بیت)</translation> -<translation id="5121084798328133320">بعد از تأیید، جزئیات کارت از حساب «پرداختهای Google» با این سایت همرسانی میشود.</translation> <translation id="5128122789703661928">جلسهای با این نام، برای حذف معتبر نیست.</translation> <translation id="5135404736266831032">مدیریت نشانیها…</translation> <translation id="5141240743006678641">رمزگذاری گذرواژههای همگامسازی شده با اطلاعات کاربری Google شما</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">ساعت شما عقب است</translation> <translation id="893332455753468063">افزودن نام</translation> <translation id="8938939909778640821">کارتهای اعتباری و پیشپرداخت قابلقبول</translation> -<translation id="8952525071319348207">برای بهروزرسانی جزئیات کارتتان، تاریخ انقضا و CVC کارت <ph name="CREDIT_CARD" /> را وارد کنید. بعد از تأیید، جزئیات کارت از حساب «پرداختهای Google» با این سایت همرسانی میشود.</translation> <translation id="8957210676456822347">مجوز پورتال محدود</translation> <translation id="8971063699422889582">گواهی سرور منقضی شده است.</translation> <translation id="8975012916872825179">شامل اطلاعاتی مانند شماره تلفن، نشانی ایمیل و نشانی تحویل کالا میشود</translation>
diff --git a/components/strings/components_strings_fi.xtb b/components/strings/components_strings_fi.xtb index f6e1a9f2..ba71835 100644 --- a/components/strings/components_strings_fi.xtb +++ b/components/strings/components_strings_fi.xtb
@@ -585,7 +585,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{ja 1 muu verkkosivu}other{ja # muuta verkkosivua}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Anna kortin <ph name="CREDIT_CARD" /> CVC. Vahvistamisen jälkeen Google-maksutilisi korttitiedot jaetaan tämän sivuston kanssa.</translation> <translation id="4923417429809017348">Tämä sivu on käännetty tuntemattomasta kielestä kielelle <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Maksu</translation> <translation id="4926049483395192435">On määritettävä.</translation> @@ -617,7 +616,6 @@ <translation id="5095208057601539847">Provinssi</translation> <translation id="5098332213681597508">Tämä on nimi Google-tililtäsi.</translation> <translation id="5115563688576182185">(64-bittinen)</translation> -<translation id="5121084798328133320">Vahvistamisen jälkeen Google-maksutilisi korttitiedot jaetaan tämän sivuston kanssa.</translation> <translation id="5128122789703661928">Tämännimistä käyttökertaa ei voi poistaa.</translation> <translation id="5135404736266831032">Hallinnoi osoitteita…</translation> <translation id="5141240743006678641">Salaa synkronoidut salasanat Google-kirjautumistietojesi avulla</translation> @@ -1149,7 +1147,6 @@ <translation id="8932102934695377596">Kellosi jätättää</translation> <translation id="893332455753468063">Lisää nimi</translation> <translation id="8938939909778640821">Hyväksytyt luotto- ja prepaid-kortit</translation> -<translation id="8952525071319348207">Päivitä kortin <ph name="CREDIT_CARD" /> tiedot antamalla sen vanhentumispäivä ja CVC. Vahvistamisen jälkeen Google-maksutilisi korttitiedot jaetaan tämän sivuston kanssa.</translation> <translation id="8957210676456822347">Captive portal -valtuutus</translation> <translation id="8971063699422889582">Palvelimen varmenne on vanhentunut.</translation> <translation id="8975012916872825179">Tallenna puhelinnumerot, sähköpostiosoitteet, toimitusosoitteet ja muita tietoja</translation>
diff --git a/components/strings/components_strings_fil.xtb b/components/strings/components_strings_fil.xtb index 0810307..74beb8aa 100644 --- a/components/strings/components_strings_fil.xtb +++ b/components/strings/components_strings_fil.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{at 1 pang web page}one{at # pang web page}other{at # pang web page}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Ilagay ang CVC para sa <ph name="CREDIT_CARD" />. Pagkatapos mong magkumpirma, ibabahagi sa site na ito ang mga detalye ng card mula sa iyong Google Payments account.</translation> <translation id="4923417429809017348">Na-translate ang pahinang ito mula sa hindi kilalang wika patungo sa <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Pagbabayad</translation> <translation id="4926049483395192435">Dapat na tukuyin.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Probinsya</translation> <translation id="5098332213681597508">Nagmula ang pangalang ito sa iyong Google Account.</translation> <translation id="5115563688576182185">(64-bit)</translation> -<translation id="5121084798328133320">Pagkatapos mong magkumpirma, ibabahagi sa site na ito ang mga detalye ng card mula sa iyong Google Payments account.</translation> <translation id="5128122789703661928">Hindi valid ang session na may ganitong pangalan upang ma-delete.</translation> <translation id="5135404736266831032">Pamahalaan ang mga address...</translation> <translation id="5141240743006678641">I-encrypt ang mga naka-sync na password gamit ang iyong mga kredensyal sa Google</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">Nahuhuli ang iyong orasan</translation> <translation id="893332455753468063">Magdagdag ng Pangalan</translation> <translation id="8938939909778640821">Mga tinatanggap na credit at prepaid card</translation> -<translation id="8952525071319348207">Ilagay ang petsa ng pag-expire at CVC para sa <ph name="CREDIT_CARD" /> upang i-update ang mga detalye ng iyong card. Pagkatapos mong magkumpirma, ibabahagi sa site na ito ang mga detalye ng card mula sa iyong Google Payments account.</translation> <translation id="8957210676456822347">Pagpapahintulot sa Captive Portal</translation> <translation id="8971063699422889582">Nag-expire na ang certificate ng server.</translation> <translation id="8975012916872825179">May kasamang impormasyon tulad ng mga numero ng telepono, email address, at address sa pagpapadala</translation>
diff --git a/components/strings/components_strings_fr.xtb b/components/strings/components_strings_fr.xtb index e84660d0..27b6ab5 100644 --- a/components/strings/components_strings_fr.xtb +++ b/components/strings/components_strings_fr.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{et 1 autre page Web}one{et # autre page Web}other{et # autres pages Web}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Saisissez le code CVC de la carte <ph name="CREDIT_CARD" />. Une fois la validation terminée, les informations relatives à la carte de votre compte Google Payments seront partagées avec ce site.</translation> <translation id="4923417429809017348">Cette page rédigée dans une langue non identifiée a été traduite en <ph name="LANGUAGE_LANGUAGE" />.</translation> <translation id="4923459931733593730">Paiement</translation> <translation id="4926049483395192435">Doit être spécifié.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Province</translation> <translation id="5098332213681597508">Ce nom provient de votre compte Google.</translation> <translation id="5115563688576182185">(64 bits)</translation> -<translation id="5121084798328133320">Une fois la validation terminée, les informations relatives à la carte de votre compte Google Payments seront partagées avec ce site.</translation> <translation id="5128122789703661928">Impossible de supprimer la session qui porte ce nom.</translation> <translation id="5135404736266831032">Gérer les adresses…</translation> <translation id="5141240743006678641">Chiffrer les mots de passe synchronisés avec vos informations de connexion Google</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">Votre horloge est en retard</translation> <translation id="893332455753468063">Ajouter un nom</translation> <translation id="8938939909778640821">Cartes de crédit et cartes prépayées acceptées</translation> -<translation id="8952525071319348207">Saisissez la date d'expiration et le code CVC de la carte <ph name="CREDIT_CARD" /> pour mettre à jour les informations relatives à celle-ci. Une fois la validation effectuée, les informations relatives à la carte de votre compte Google Payments seront partagées avec ce site.</translation> <translation id="8957210676456822347">Autorisation du portail captif</translation> <translation id="8971063699422889582">Le certificat du serveur a expiré.</translation> <translation id="8975012916872825179">Y compris les numéros de téléphone, les adresses e-mail et les adresses de livraison</translation>
diff --git a/components/strings/components_strings_gu.xtb b/components/strings/components_strings_gu.xtb index eec3bfd..347569c 100644 --- a/components/strings/components_strings_gu.xtb +++ b/components/strings/components_strings_gu.xtb
@@ -583,7 +583,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{અને 1 વધુ વેબ પૃષ્ઠ}one{અને # વધુ વેબ પૃષ્ઠ}other{અને # વધુ વેબ પૃષ્ઠ}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947"><ph name="CREDIT_CARD" /> માટે CVC દાખલ કરો. તમે પુષ્ટિ કરી લો પછી, આ સાઇટ સાથે તમારા Google Payments એકાઉન્ટમાંથી કાર્ડની વિગતો શેર કરવામાં આવશે.</translation> <translation id="4923417429809017348">આ પૃષ્ઠ કોઈ અજ્ઞાત ભાષામાંથી <ph name="LANGUAGE_LANGUAGE" /> માં અનુવાદિત કરવામાં આવ્યું છે</translation> <translation id="4923459931733593730">ચુકવણી</translation> <translation id="4926049483395192435">ઉલ્લેખિત હોવું આવશ્યક છે.</translation> @@ -615,7 +614,6 @@ <translation id="5095208057601539847">પ્રાંત</translation> <translation id="5098332213681597508">આ નામ તમારા Google એકાઉન્ટમાંથી લીધું છે.</translation> <translation id="5115563688576182185">(64-બિટ)</translation> -<translation id="5121084798328133320">તમે પુષ્ટિ કરી લો પછી, આ સાઇટ સાથે તમારા Google Payments એકાઉન્ટમાંથી કાર્ડની વિગતો શેર કરવામાં આવશે.</translation> <translation id="5128122789703661928">આ નામવાળું સત્ર ડિલીટ કરવા માટે માન્ય નથી.</translation> <translation id="5135404736266831032">સરનામા મેનેજ કરો…</translation> <translation id="5141240743006678641">તમારા Google લૉગ ઇન વિગત સાથે સિંક પાસવર્ડને એન્ક્રિપ્ટ કરો</translation> @@ -1146,7 +1144,6 @@ <translation id="8932102934695377596">તમારી ઘડિયાળ પાછળ છે</translation> <translation id="893332455753468063">નામ ઉમેરો</translation> <translation id="8938939909778640821">સ્વીકૃત ક્રેડિટ અને પ્રીપેઇડ કાર્ડ</translation> -<translation id="8952525071319348207">તમારા કાર્ડની વિગતોને અપડેટ કરવા માટે <ph name="CREDIT_CARD" />ની સમાપ્તિ તારીખ અને CVC દાખલ કરો. તમે પુષ્ટિ કરી લો પછી, આ સાઇટ સાથે તમારા Google Payments એકાઉન્ટમાંથી કાર્ડની વિગતો શેર કરવામાં આવશે.</translation> <translation id="8957210676456822347">કૅપ્ટિવ પોર્ટલ પ્રમાણિત</translation> <translation id="8971063699422889582">સર્વરના પ્રમાણપત્રની સમયસીમા સમાપ્ત થઈ છે.</translation> <translation id="8975012916872825179">ફોન નંબર, ઇમેઇલ ઍડ્રેસ અને શિપિંગ સરનામા જેવી માહિતીનો સમાવેશ છે</translation>
diff --git a/components/strings/components_strings_hi.xtb b/components/strings/components_strings_hi.xtb index 51dc7c58..b3b3e3e 100644 --- a/components/strings/components_strings_hi.xtb +++ b/components/strings/components_strings_hi.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{1 और वेब पेज}one{# और वेब पेज}other{# और वेब पेज}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947"><ph name="CREDIT_CARD" /> का कार्ड वेरीफ़िकेशन कोड (सीवीसी) डालें. आपकी ओर से पुष्टि होने के बाद, आपके Google Payments खाते में मौजूद कार्ड के विवरण इस साइट से शेयर किए जाएंगे.</translation> <translation id="4923417429809017348">इस पेज का एक अज्ञात भाषा से <ph name="LANGUAGE_LANGUAGE" /> में अनुवाद किया गया है</translation> <translation id="4923459931733593730">भुगतान</translation> <translation id="4926049483395192435">निर्दिष्ट किया जाना चाहिए.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">प्रांत</translation> <translation id="5098332213681597508">यह नाम आपके Google खाते से संबंधित है.</translation> <translation id="5115563688576182185">(64-बिट)</translation> -<translation id="5121084798328133320">आपकी ओर से पुष्टि होने के बाद, आपके Google Payments खाते में मौजूद कार्ड के विवरण इस साइट से शेयर किए जाएंगे.</translation> <translation id="5128122789703661928">इस नाम वाला सीज़न मिटाने के लिए मान्य नहीं है.</translation> <translation id="5135404736266831032">पते प्रबंधित करें...</translation> <translation id="5141240743006678641">समन्वयित पासवर्ड अपने Google प्रमाणिकता के साथ एन्क्रिप्ट करें</translation> @@ -1148,7 +1146,6 @@ <translation id="8932102934695377596">आपकी घड़ी पीछे है</translation> <translation id="893332455753468063">नाम जोड़ें</translation> <translation id="8938939909778640821">स्वीकृत क्रेडिट और प्रीपेड कार्ड</translation> -<translation id="8952525071319348207">अपने कार्ड के विवरण अपडेट करने के लिए <ph name="CREDIT_CARD" /> के खत्म होने की तारीख और कार्ड वेरीफ़िकेशन कोड (सीवीसी) डालें. आपकी ओर से पुष्टि होने के बाद, आपके Google Payments खाते में मौजूद कार्ड के विवरण इस साइट से शेयर किए जाएंगे.</translation> <translation id="8957210676456822347">कैप्टिव पोर्टल प्राधिकरण</translation> <translation id="8971063699422889582">सर्वर के प्रमाणपत्र की समय-सीमा समाप्त हो चुकी है.</translation> <translation id="8975012916872825179">फ़ोन नंबर, ईमेल पते और शिपिंग पते जैसी जानकारी शामिल है</translation>
diff --git a/components/strings/components_strings_hr.xtb b/components/strings/components_strings_hr.xtb index e73013e..26e342f2 100644 --- a/components/strings/components_strings_hr.xtb +++ b/components/strings/components_strings_hr.xtb
@@ -138,7 +138,7 @@ <translation id="1783075131180517613">Ažurirajte zaporku za sinkronizaciju.</translation> <translation id="1787142507584202372">Ovdje se prikazuju vaše otvorene kartice</translation> <translation id="1791429645902722292">Google Smart Lock</translation> -<translation id="1803264062614276815">Ime nositelja kartice</translation> +<translation id="1803264062614276815">Ime vlasnika kartice</translation> <translation id="1809549658008855907">Želite li spremiti kartice na svoj Google račun?</translation> <translation id="1821930232296380041">Nevažeći zahtjev ili parametri zahtjeva</translation> <translation id="1826516787628120939">Provjera</translation> @@ -583,7 +583,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{i još 1 web-stranica}one{i još # web-stranica}few{i još # web-stranice}other{i još # web-stranica}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Unesite CVC za karticu <ph name="CREDIT_CARD" />. Nakon što ih potvrdite, podaci o kartici s vašeg računa na usluzi Google Payments podijelit će se s ovom web-lokacijom.</translation> <translation id="4923417429809017348">Ova je stranica prevedena s nepoznatog jezika na <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Plaćanje</translation> <translation id="4926049483395192435">Mora biti određeno.</translation> @@ -615,7 +614,6 @@ <translation id="5095208057601539847">Provincija</translation> <translation id="5098332213681597508">To je ime s vašeg Google računa.</translation> <translation id="5115563688576182185">(64-bitni)</translation> -<translation id="5121084798328133320">Nakon što ih potvrdite, podaci o kartici s računa usluge Google podijelit će se s ovom web-lokacijom.</translation> <translation id="5128122789703661928">Brisanje sesije nije uspjelo jer naziv sesije nije važeći.</translation> <translation id="5135404736266831032">Upravljajte adresama...</translation> <translation id="5141240743006678641">Šifriranje sinkroniziranih zaporki s vjerodajnicama za Google</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">Sat kasni</translation> <translation id="893332455753468063">Dodajte ime</translation> <translation id="8938939909778640821">Prihvaćene kreditne i pretplatne kartice</translation> -<translation id="8952525071319348207">Unesite datum isteka i CVC za karticu <ph name="CREDIT_CARD" /> da biste ažurirali podatke o kartici. Nakon što ih potvrdite, podaci o kartici s vašeg računa na usluzi Google Payments podijelit će se s ovom web-lokacijom.</translation> <translation id="8957210676456822347">Autorizacija obaveznog portala za autentifikaciju</translation> <translation id="8971063699422889582">Istekao je certifikat poslužitelja.</translation> <translation id="8975012916872825179">Sadrži podatke kao što su telefonski brojevi, e-adrese i adrese za dostavu</translation>
diff --git a/components/strings/components_strings_hu.xtb b/components/strings/components_strings_hu.xtb index 2205d9a..71e5d9b 100644 --- a/components/strings/components_strings_hu.xtb +++ b/components/strings/components_strings_hu.xtb
@@ -582,7 +582,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" /> és <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{és egy további weboldal}other{és # további weboldal}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Adja meg a(z) <ph name="CREDIT_CARD" /> kártya CVC-kódját. A megerősítést követően a böngésző megosztja majd az Ön Google Payments-fiókjából származó kártyaadatokat ezzel a webhellyel.</translation> <translation id="4923417429809017348">Ezt az oldalt lefordították egy ismeretlen nyelvről <ph name="LANGUAGE_LANGUAGE" /> nyelvre</translation> <translation id="4923459931733593730">Fizetés</translation> <translation id="4926049483395192435">Meg kell határozni.</translation> @@ -614,7 +613,6 @@ <translation id="5095208057601539847">Tartomány</translation> <translation id="5098332213681597508">Ez a név a Google-fiókjából származik.</translation> <translation id="5115563688576182185">(64 bites)</translation> -<translation id="5121084798328133320">A megerősítést követően a böngésző megosztja az Ön Google Payments-fiókjából származó kártyaadatokat ezzel a webhellyel.</translation> <translation id="5128122789703661928">Ez a munkamenetnév nem érvényes, ezért nem törölhető.</translation> <translation id="5135404736266831032">Címek kezelése…</translation> <translation id="5141240743006678641">A szinkronizált jelszavak titkosítása a Google hitelesítési adataival</translation> @@ -1146,7 +1144,6 @@ <translation id="8932102934695377596">Késik az órája</translation> <translation id="893332455753468063">Név hozzáadása</translation> <translation id="8938939909778640821">Elfogadott hitel- és feltöltőkártyák</translation> -<translation id="8952525071319348207">A(z) <ph name="CREDIT_CARD" /> kártyához tartozó CVC-kód lejárati dátumának megadásával frissítheti a kártyaadatokat. A megerősítést követően a böngésző megosztja az Ön Google Payments-fiókjából származó kártyaadatokat ezzel a webbhellyel.</translation> <translation id="8957210676456822347">Hitelesítés hitelesítési portállal</translation> <translation id="8971063699422889582">A szerver tanúsítványa lejárt.</translation> <translation id="8975012916872825179">Olyan adatokat tartalmaz, mint a telefonszámok, az e-mail-címek és a szállítási címek</translation>
diff --git a/components/strings/components_strings_id.xtb b/components/strings/components_strings_id.xtb index 331baf1..46dcdbb5 100644 --- a/components/strings/components_strings_id.xtb +++ b/components/strings/components_strings_id.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{dan 1 halaman web lainnya}other{dan # halaman web lainnya}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Masukkan CVC untuk <ph name="CREDIT_CARD" />. Setelah mengonfirmasi, detail kartu dari akun Pembayaran Google Anda akan dibagikan dengan situs ini.</translation> <translation id="4923417429809017348">Halaman ini telah diterjemahkan dari bahasa yang tidak diketahui ke bahasa <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Pembayaran</translation> <translation id="4926049483395192435">Harus ditentukan.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Provinsi</translation> <translation id="5098332213681597508">Nama ini dari Akun Google Anda.</translation> <translation id="5115563688576182185">(64 bit)</translation> -<translation id="5121084798328133320">Setelah mengonfirmasi, detail kartu dari akun Pembayaran Google Anda akan dibagikan dengan situs ini.</translation> <translation id="5128122789703661928">Sesi dengan nama ini tidak valid untuk dihapus.</translation> <translation id="5135404736266831032">Kelola alamat...</translation> <translation id="5141240743006678641">Enkripsikan sandi yang disinkronkan dengan kredensial Google Anda</translation> @@ -1143,7 +1141,6 @@ <translation id="8932102934695377596">Setelan waktu Anda terlalu lambat</translation> <translation id="893332455753468063">Tambahkan Nama</translation> <translation id="8938939909778640821">Kartu kredit dan prabayar yang diterima</translation> -<translation id="8952525071319348207">Masukkan tanggal habis masa berlaku dan CVC untuk <ph name="CREDIT_CARD" /> guna mengupdate detail kartu. Setelah mengonfirmasi, detail kartu dari akun Pembayaran Google Anda akan dibagikan dengan situs ini.</translation> <translation id="8957210676456822347">Otorisasi Portal Tawanan</translation> <translation id="8971063699422889582">Sertifikat server telah kedaluwarsa.</translation> <translation id="8975012916872825179">Termasuk informasi seperti nomor telepon, alamat email, dan alamat pengiriman</translation>
diff --git a/components/strings/components_strings_it.xtb b/components/strings/components_strings_it.xtb index 937b500..2aebd033 100644 --- a/components/strings/components_strings_it.xtb +++ b/components/strings/components_strings_it.xtb
@@ -581,7 +581,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{e un'altra pagina web}other{e altre # pagine web}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Inserisci il codice CVC della carta <ph name="CREDIT_CARD" />. Dopo essere stati confermati, i dati della carta del tuo account Google Payments saranno condivisi con questo sito.</translation> <translation id="4923417429809017348">Questa pagina è stata tradotta da una lingua sconosciuta in <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Pagamento</translation> <translation id="4926049483395192435">Deve essere specificato.</translation> @@ -613,7 +612,6 @@ <translation id="5095208057601539847">Provincia</translation> <translation id="5098332213681597508">Questo nome proviene dal tuo account Google.</translation> <translation id="5115563688576182185">(a 64 bit)</translation> -<translation id="5121084798328133320">Dopo essere stati confermati, i dati della carta del tuo account Google Payments saranno condivisi con questo sito.</translation> <translation id="5128122789703661928">Impossibile eliminare la sessione perché il nome specificato non è valido.</translation> <translation id="5135404736266831032">Gestisci indirizzi…</translation> <translation id="5141240743006678641">Cripta le password sincronizzate con le tue credenziali Google</translation> @@ -1143,7 +1141,6 @@ <translation id="8932102934695377596">L'orologio è indietro</translation> <translation id="893332455753468063">Aggiungi nome</translation> <translation id="8938939909778640821">Carte di credito e prepagate accettate</translation> -<translation id="8952525071319348207">Inserisci la data di scadenza e il codice CVC della carta <ph name="CREDIT_CARD" /> per aggiornare i relativi dettagli. Dopo essere stati confermati, i dati della carta del tuo account Google Payments saranno condivisi con questo sito.</translation> <translation id="8957210676456822347">Autorizzazione Captive Portal</translation> <translation id="8971063699422889582">Il certificato del server è scaduto.</translation> <translation id="8975012916872825179">Include informazioni come numeri di telefono, indirizzi email e indirizzi di spedizione</translation>
diff --git a/components/strings/components_strings_iw.xtb b/components/strings/components_strings_iw.xtb index f87d58e8..8422e2ef 100644 --- a/components/strings/components_strings_iw.xtb +++ b/components/strings/components_strings_iw.xtb
@@ -588,7 +588,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{ועוד דף אינטרנט אחד}two{ועוד # דפי אינטרנט}many{ועוד # דפי אינטרנט}other{ועוד # דפי אינטרנט}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">צריך להזין את קוד האימות של <ph name="CREDIT_CARD" />. אחרי שנקבל ממך אישור, נשתף עם האתר הזה את פרטי הכרטיס מחשבון תשלומי Google.</translation> <translation id="4923417429809017348">דף זה תורגם משפה לא ידועה ל<ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">תשלום</translation> <translation id="4926049483395192435">יש לציין ערך זה.</translation> @@ -620,7 +619,6 @@ <translation id="5095208057601539847">פרובינציה</translation> <translation id="5098332213681597508">השם הזה הוא מחשבון Google שלך.</translation> <translation id="5115563688576182185">(64 סיביות)</translation> -<translation id="5121084798328133320">אחרי שנקבל ממך אישור, נשתף עם האתר הזה את פרטי הכרטיס מחשבון תשלומי Google.</translation> <translation id="5128122789703661928">שם ההפעלה למחיקה אינו חוקי.</translation> <translation id="5135404736266831032">ניהול כתובות...</translation> <translation id="5141240743006678641">הצפן סיסמאות מסונכרנות באמצעות פרטי הכניסה שלך ל-Google</translation> @@ -735,7 +733,7 @@ <translation id="5922853866070715753">עוד רגע מסיימים</translation> <translation id="5932224571077948991">באתר מוצגות מודעות מפריעות או מטעות</translation> <translation id="5939518447894949180">אפס</translation> -<translation id="5946937721014915347">פותח את <ph name="SITE_NAME" />…</translation> +<translation id="5946937721014915347">פתיחה של <ph name="SITE_NAME" />…</translation> <translation id="5951495562196540101">אי אפשר להירשם באמצעות חשבון פרטי (יש רישיון משויך זמין).</translation> <translation id="5966151627327109289">הפעולה מוציאה אותך מרוב האתרים. ייתכן שלא תהיה לך יותר גישה לתוכן מוגן מ-<ph name="SITE" /> ומאתרים אחרים.</translation> <translation id="5967592137238574583">עריכת הפרטים ליצירת קשר</translation> @@ -1153,7 +1151,6 @@ <translation id="8932102934695377596">השעון שלך מאחר</translation> <translation id="893332455753468063">הוספת שם</translation> <translation id="8938939909778640821">כרטיסי אשראי וכרטיסים משולמים מראש שהסוחר מקבל</translation> -<translation id="8952525071319348207">כדי לעדכן את פרטי הכרטיס שלך, צריך להזין את תאריך התפוגה וקוד האימות של <ph name="CREDIT_CARD" />. אחרי שנקבל ממך אישור, נשתף עם האתר הזה את פרטי הכרטיס מחשבון תשלומי Google.</translation> <translation id="8957210676456822347">הרשאת פורטל חובה</translation> <translation id="8971063699422889582">פג תוקפו של אישור השרת.</translation> <translation id="8975012916872825179">כולל מידע כמו מספרי טלפון, כתובות אימייל וכתובות למשלוח</translation>
diff --git a/components/strings/components_strings_ja.xtb b/components/strings/components_strings_ja.xtb index aba92f7..4c028e24 100644 --- a/components/strings/components_strings_ja.xtb +++ b/components/strings/components_strings_ja.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />、<ph name="TYPE_2" />、<ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{他 1 件のウェブページ}other{他 # 件のウェブページ}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947"><ph name="CREDIT_CARD" /> の CVC を入力します。確認後、Google Payments アカウントのカード情報がこのサイトと共有されます。</translation> <translation id="4923417429809017348">このページは、不明な言語から<ph name="LANGUAGE_LANGUAGE" />に翻訳されました。</translation> <translation id="4923459931733593730">お支払い</translation> <translation id="4926049483395192435">指定する必要があります。</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">地方</translation> <translation id="5098332213681597508">Google アカウントで設定されている名前です。</translation> <translation id="5115563688576182185">(64 ビット)</translation> -<translation id="5121084798328133320">確認後、Google Payments アカウントのカード情報がこのサイトと共有されます。</translation> <translation id="5128122789703661928">セッションの名前が有効でないため、削除できません。</translation> <translation id="5135404736266831032">住所を管理...</translation> <translation id="5141240743006678641">Google の認証情報で同期パスワードを暗号化する</translation> @@ -1148,7 +1146,6 @@ <translation id="8932102934695377596">時計が遅れています</translation> <translation id="893332455753468063">名前の追加</translation> <translation id="8938939909778640821">利用可能なクレジット カードとプリペイド カード</translation> -<translation id="8952525071319348207">カード情報を更新するには <ph name="CREDIT_CARD" /> の有効期限と CVC を入力します。確認後、Google Payments アカウントのカード情報がこのサイトと共有されます。</translation> <translation id="8957210676456822347">キャプティブ ポータル認証</translation> <translation id="8971063699422889582">サーバーの証明書の有効期限が切れています。</translation> <translation id="8975012916872825179">電話番号、メールアドレス、配送先住所などの情報が含まれます</translation>
diff --git a/components/strings/components_strings_kn.xtb b/components/strings/components_strings_kn.xtb index 9dac4083..6dd9f720 100644 --- a/components/strings/components_strings_kn.xtb +++ b/components/strings/components_strings_kn.xtb
@@ -580,7 +580,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{ಮತ್ತು 1 ಹೆಚ್ಚಿನ ವೆಬ್ ಪುಟ}one{ಮತ್ತು # ಹೆಚ್ಚಿನ ವೆಬ್ ಪುಟಗಳು}other{ಮತ್ತು # ಹೆಚ್ಚಿನ ವೆಬ್ ಪುಟಗಳು}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947"><ph name="CREDIT_CARD" /> ಗೆ CVC ಅನ್ನು ನಮೂದಿಸಿ. ನೀವು ಖಚಿತಪಡಿಸಿದ ನಂತರ, ನಿಮ್ಮ Google ಪಾವತಿಗಳ ಖಾತೆಯಿಂದ ಕಾರ್ಡ್ ವಿವರಗಳನ್ನು ಈ ಸೈಟ್ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.</translation> <translation id="4923417429809017348">ಗೊತ್ತಿಲ್ಲದ ಭಾಷೆಯಿಂದ <ph name="LANGUAGE_LANGUAGE" /> ಗೆ ಈ ಪುಟವನ್ನು ಭಾಷಾಂತರಿಸಲಾಗಿದೆ</translation> <translation id="4923459931733593730">ಪಾವತಿ</translation> <translation id="4926049483395192435">ನಿರ್ದಿಷ್ಟಪಡಿಸಬೇಕಾಗಿದೆ.</translation> @@ -612,7 +611,6 @@ <translation id="5095208057601539847">ಪ್ರಾಂತ್ಯ</translation> <translation id="5098332213681597508">ಈ ಹೆಸರು ನಿಮ್ಮ Google ಖಾತೆಯಿಂದ ಬಂದಿದೆ.</translation> <translation id="5115563688576182185">(64-ಬಿಟ್)</translation> -<translation id="5121084798328133320">ನೀವು ಖಚಿತಪಡಿಸಿದ ನಂತರ, ನಿಮ್ಮ Google ಪಾವತಿಗಳ ಖಾತೆಯಿಂದ ಕಾರ್ಡ್ ವಿವರಗಳನ್ನು ಈ ಸೈಟ್ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.</translation> <translation id="5128122789703661928">ಈ ಹೆಸರಿನ ಸೆಶನ್ ಅಳಿಸಲು ಮಾನ್ಯವಾಗಿಲ್ಲ.</translation> <translation id="5135404736266831032">ವಿಳಾಸಗಳನ್ನು ನಿರ್ವಹಿಸಿ...</translation> <translation id="5141240743006678641">ನಿಮ್ಮ Google ರುಜುವಾತುಗಳ ಜೊತೆಗೆ ಸಿಂಕ್ ಮಾಡಿದ ಪಾಸ್ವರ್ಡ್ಗಳನ್ನು ಎನ್ಕ್ರಿಫ್ಟ್ ಮಾಡಿ</translation> @@ -1142,7 +1140,6 @@ <translation id="8932102934695377596">ನಿಮ್ಮ ಗಡಿಯಾರ ಹಿಂದೆ ಇದೆ</translation> <translation id="893332455753468063">ಹೆಸರು ಸೇರಿಸಿ</translation> <translation id="8938939909778640821">ಸಮ್ಮತಿಸಲಾದ ಕ್ರೆಡಿಟ್ ಮತ್ತು ಪ್ರೀಪೇಯ್ಡ್ ಕಾರ್ಡ್ಗಳು</translation> -<translation id="8952525071319348207">ನಿಮ್ಮ ಕಾರ್ಡ್ ವಿವರಗಳನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲು <ph name="CREDIT_CARD" /> ಗೆ ಅವಧಿ ಮುಕ್ತಾಯದ ದಿನಾಂಕ ಮತ್ತು CVC ಅನ್ನು ನಮೂದಿಸಿ. ನೀವು ಖಚಿತಪಡಿಸಿದ ನಂತರ, ನಿಮ್ಮ Google ಪಾವತಿಗಳ ಖಾತೆಯಿಂದ ಕಾರ್ಡ್ ವಿವರಗಳನ್ನು ಈ ಸೈಟ್ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತದೆ.</translation> <translation id="8957210676456822347">ಕ್ಯಾಪ್ಟಿವ್ ಪೋರ್ಟಲ್ ದೃಢೀಕರಣ</translation> <translation id="8971063699422889582">ಸರ್ವರ್ನ ಪ್ರಕಮಾಣಪತ್ರದ ಅವಧಿ ಮುಕ್ತಾಯಗೊಂಡಿದೆ.</translation> <translation id="8975012916872825179">ಫೋನ್ ಸಂಖ್ಯೆಗಳು, ಇಮೇಲ್ ವಿಳಾಸಗಳು ಮತ್ತು ಶಿಪ್ಪಿಂಗ್ ವಿಳಾಸಗಳಂತಹ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ</translation>
diff --git a/components/strings/components_strings_ko.xtb b/components/strings/components_strings_ko.xtb index 401966e..737cf484 100644 --- a/components/strings/components_strings_ko.xtb +++ b/components/strings/components_strings_ko.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{외 웹페이지 1개}other{외 웹페이지 #개}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947"><ph name="CREDIT_CARD" /> 카드의 CVC를 입력하세요. 카드를 확인하면 Google Payments 계정의 카드 세부정보가 이 사이트와 공유됩니다.</translation> <translation id="4923417429809017348">페이지가 알 수 없는 언어에서 <ph name="LANGUAGE_LANGUAGE" />(으)로 번역되었습니다.</translation> <translation id="4923459931733593730">결제</translation> <translation id="4926049483395192435">지정해야 합니다.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">주/도</translation> <translation id="5098332213681597508">Google 계정에 등록된 이름입니다.</translation> <translation id="5115563688576182185">(64비트)</translation> -<translation id="5121084798328133320">카드를 확인하면 Google Payments 계정의 카드 세부정보가 이 사이트와 공유됩니다.</translation> <translation id="5128122789703661928">세션 이름이 잘못되어 삭제할 수 없습니다.</translation> <translation id="5135404736266831032">주소 관리...</translation> <translation id="5141240743006678641">동기화 비밀번호를 Google 자격증명으로 암호화</translation> @@ -1146,7 +1144,6 @@ <translation id="8932102934695377596">시간이 너무 먼 과거로 설정되어 있습니다.</translation> <translation id="893332455753468063">이름 추가</translation> <translation id="8938939909778640821">사용 가능한 신용카드 및 선불카드</translation> -<translation id="8952525071319348207">카드 세부정보를 업데이트하려면 <ph name="CREDIT_CARD" /> 카드의 만료일과 CVC를 입력하세요. 카드를 확인하면 Google Payments 계정의 카드 세부정보가 이 사이트와 공유됩니다.</translation> <translation id="8957210676456822347">캡티브 포털 승인</translation> <translation id="8971063699422889582">서버 인증서가 만료되었습니다.</translation> <translation id="8975012916872825179">전화번호, 이메일 주소, 배송지 주소 등의 정보를 포함합니다.</translation>
diff --git a/components/strings/components_strings_lt.xtb b/components/strings/components_strings_lt.xtb index 675c8e3..27b25aa 100644 --- a/components/strings/components_strings_lt.xtb +++ b/components/strings/components_strings_lt.xtb
@@ -585,7 +585,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{ir dar 1 tinklalapis}one{ir dar # tinklalapis}few{ir dar # tinklalapiai}many{ir dar # tinklalapio}other{ir dar # tinklalapių}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Įveskite „<ph name="CREDIT_CARD" />“ kortelės saugos kodą (CVC). Kai patvirtinsite, „Google“ mokamojoje paskyroje nurodyta išsami kortelės informacija bus bendrinama su šia svetaine.</translation> <translation id="4923417429809017348">Šis puslapis išverstas iš nežinomos kalbos į <ph name="LANGUAGE_LANGUAGE" /> k.</translation> <translation id="4923459931733593730">Mokėjimas</translation> <translation id="4926049483395192435">Turi būti nurodyta.</translation> @@ -617,7 +616,6 @@ <translation id="5095208057601539847">Provincija</translation> <translation id="5098332213681597508">Šis vardas yra iš jūsų „Google“ paskyros.</translation> <translation id="5115563688576182185">(64 bitų)</translation> -<translation id="5121084798328133320">Kai patvirtinsite, „Google“ mokamojoje paskyroje nurodyta išsami kortelės informacija bus bendrinama su šia svetaine.</translation> <translation id="5128122789703661928">Sesijos šiuo pavadinimu negalima ištrinti.</translation> <translation id="5135404736266831032">Tvarkyti adresus...</translation> <translation id="5141240743006678641">Šifruoti sinchronizuotus slaptažodžius naudojant „Google“ prisijungimo duomenis</translation> @@ -1149,7 +1147,6 @@ <translation id="8932102934695377596">Jūsų laikrodis atsilieka</translation> <translation id="893332455753468063">Vardo ir pavardės pridėjimas</translation> <translation id="8938939909778640821">Tinkamos kredito ir išankstinio mokėjimo kortelės</translation> -<translation id="8952525071319348207">Jei norite atnaujinti išsamią kortelės informaciją, įveskite „<ph name="CREDIT_CARD" />“ galiojimo pabaigos datą ir kortelės saugos kodą (CVC). Kai patvirtinsite, „Google“ mokamojoje paskyroje nurodyta išsami kortelės informacija bus bendrinama su šia svetaine.</translation> <translation id="8957210676456822347">Fiksuotojo portalo autorizavimas</translation> <translation id="8971063699422889582">Baigėsi serverio sertifikato galiojimo laikas.</translation> <translation id="8975012916872825179">Įtraukiama tokia informacija kaip telefono numeriai, el. pašto adresai ir pristatymo adresai</translation>
diff --git a/components/strings/components_strings_lv.xtb b/components/strings/components_strings_lv.xtb index ad8b02a..d68b322f 100644 --- a/components/strings/components_strings_lv.xtb +++ b/components/strings/components_strings_lv.xtb
@@ -583,7 +583,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{un vēl 1 tīmekļa lapa}zero{un vēl # tīmekļa lapas}one{un vēl # tīmekļa lapa}other{un vēl # tīmekļa lapas}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Ievadiet kredītkartes <ph name="CREDIT_CARD" /> CVC kodu. Pēc apstiprināšanas kartes informācija no Google maksājumu konta tiks kopīgota ar šo vietni.</translation> <translation id="4923417429809017348">Šī lapa ir tulkota no nezināmas valodas valodā: <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Maksājums</translation> <translation id="4926049483395192435">Jābūt norādītai.</translation> @@ -615,7 +614,6 @@ <translation id="5095208057601539847">Province</translation> <translation id="5098332213681597508">Šis vārds ir iegūts no jūsu Google konta.</translation> <translation id="5115563688576182185">(64 bitu)</translation> -<translation id="5121084798328133320">Pēc apstiprināšanas kartes informācija no Google maksājumu konta tiks kopīgota ar šo vietni.</translation> <translation id="5128122789703661928">Sesija ar šādu nosaukumu nav dzēšama.</translation> <translation id="5135404736266831032">Pārvaldīt adreses...</translation> <translation id="5141240743006678641">Šifrēt sinhronizētās paroles, izmantojot Google akreditācijas datus</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">Norādītais laiks ir pārāk tālu pagātnē</translation> <translation id="893332455753468063">Vārda pievienošana</translation> <translation id="8938939909778640821">Atbalstītās kredītkartes un priekšapmaksas kartes</translation> -<translation id="8952525071319348207">Lai atjauninātu kartes informāciju, ievadiet kredītkartes <ph name="CREDIT_CARD" /> derīguma termiņu un CVC kodu. Pēc apstiprināšanas kartes informācija no Google maksājumu konta tiks kopīgota ar šo vietni.</translation> <translation id="8957210676456822347">Caurlaides lapas autorizācija</translation> <translation id="8971063699422889582">Servera sertifikātam ir beidzies derīguma termiņš.</translation> <translation id="8975012916872825179">Iekļauta tāda informācija kā tālruņa numuri, e-pasta un piegādes adreses</translation>
diff --git a/components/strings/components_strings_ml.xtb b/components/strings/components_strings_ml.xtb index d4e43516..8b7689cf 100644 --- a/components/strings/components_strings_ml.xtb +++ b/components/strings/components_strings_ml.xtb
@@ -583,7 +583,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{ഒരു വെബ്പേജ് കൂടിയുണ്ട്}other{# വെബ്പേജുകൾ കൂടിയുണ്ട്}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947"><ph name="CREDIT_CARD" /> കാർഡിന്റെ CVC നൽകുക. സ്ഥിരീകരിച്ച് കഴിഞ്ഞാൽ, നിങ്ങളുടെ Google പേയ്മെന്റ് അക്കൗണ്ടിൽ നിന്നുള്ള കാർഡ് വിശദാംശങ്ങൾ ഈ സൈറ്റുമായി പങ്കിടും.</translation> <translation id="4923417429809017348">ഈ പേജിനെ അറിയപ്പെടാത്ത ഒരു ഭാഷയില് നിന്നും <ph name="LANGUAGE_LANGUAGE" /> എന്നതിലേക്ക് വിവര്ത്തനം ചെയ്തു</translation> <translation id="4923459931733593730">പേയ്മെന്റ് രീതി</translation> <translation id="4926049483395192435">വ്യക്തമാക്കേണ്ടതാണ്.</translation> @@ -615,7 +614,6 @@ <translation id="5095208057601539847">പ്രവിശ്യ</translation> <translation id="5098332213681597508">ഈ പേര് നിങ്ങളുടെ Google അക്കൗണ്ടിൽ നിന്നുള്ളതാണ്.</translation> <translation id="5115563688576182185">(64-ബിറ്റ്)</translation> -<translation id="5121084798328133320">സ്ഥിരീകരിച്ച് കഴിഞ്ഞാൽ, നിങ്ങളുടെ Google പേയ്മെന്റ് അക്കൗണ്ടിൽ നിന്നുള്ള കാർഡ് വിശദാംശങ്ങൾ ഈ സൈറ്റുമായി പങ്കിടും.</translation> <translation id="5128122789703661928">സെഷന്റെ പേര് തെറ്റായതിനാൽ ഇല്ലാതാക്കാനായില്ല.</translation> <translation id="5135404736266831032">വിലാസങ്ങൾ മാനേജ് ചെയ്യുക...</translation> <translation id="5141240743006678641">Google ക്രെഡൻഷ്യലുകൾ ഉപയോഗിച്ച് സമന്വിത പാസ്വേഡുകൾ എൻക്രിപ്റ്റുചെയ്യുക</translation> @@ -1143,7 +1141,6 @@ <translation id="8932102934695377596">നിങ്ങളുടെ ക്ലോക്ക് വളരെ പിന്നിലാണ്</translation> <translation id="893332455753468063">പേര് ചേർക്കുക</translation> <translation id="8938939909778640821">ക്രെഡിറ്റ് കാർഡുകളും പ്രീപെയ്ഡ് കാർഡുകളും സ്വീകരിക്കുന്നു</translation> -<translation id="8952525071319348207">നിങ്ങളുടെ കാർഡ് വിശദാംശങ്ങൾ അപ്ഡേറ്റ് ചെയ്യാൻ <ph name="CREDIT_CARD" /> കാർഡിന്റെ കാലാവധി തീരുന്ന തീയതിയും CVC-യും നൽകുക. സ്ഥിരീകരിച്ച് കഴിഞ്ഞാൽ, നിങ്ങളുടെ Google പേയ്മെന്റ് അക്കൗണ്ടിൽ നിന്നുള്ള കാർഡ് വിശദാംശങ്ങൾ ഈ സൈറ്റുമായി പങ്കിടും.</translation> <translation id="8957210676456822347">ക്യാപ്റ്റീവ് പോർട്ടൽ അംഗീകരിക്കൽ</translation> <translation id="8971063699422889582">സെര്വറിന്റെ സര്ട്ടിഫിക്കറ്റ് കാലഹരണപ്പെട്ടു.</translation> <translation id="8975012916872825179">ഫോൺ നമ്പറുകൾ, ഇമെയിൽ വിലാസങ്ങൾ, ഷിപ്പിംഗ് വിലാസങ്ങൾ എന്നിവ പോലുള്ള വിവരങ്ങൾ ഉൾപ്പെടുന്നു</translation>
diff --git a/components/strings/components_strings_mr.xtb b/components/strings/components_strings_mr.xtb index 7caf54e..483e8132 100644 --- a/components/strings/components_strings_mr.xtb +++ b/components/strings/components_strings_mr.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{आणि 1 आणखी वेब पृष्ठ}one{आणि # आणखी वेब पृष्ठ}other{आणि # आणखी वेब पेज}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947"><ph name="CREDIT_CARD" /> चा CVV टाका. तुम्ही निश्चित केल्यावर तुमच्या Google पेमेंट खात्यामधील कार्डाचे तपशील या साइटसोबत शेअर केले जातील.</translation> <translation id="4923417429809017348">हे पृष्ठ अज्ञात भाषेतून <ph name="LANGUAGE_LANGUAGE" /> मध्ये अनुवादित करण्यात आले</translation> <translation id="4923459931733593730">पेमेंट</translation> <translation id="4926049483395192435">निर्दिष्ट केले जाणे आवश्यक आहे.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">प्रांत</translation> <translation id="5098332213681597508">हे नाव तुमच्या Google खात्यावरून आहे.</translation> <translation id="5115563688576182185">(64-बिट)</translation> -<translation id="5121084798328133320">तुम्ही निश्चित केल्यानंतर, तुमच्या Google पेमेंट खात्यावरील कार्ड तपशील या साइटसोबत शेअर केले जातील.</translation> <translation id="5128122789703661928">हे नाव असलेले सेशन हटवण्यासाठी वैध नाही.</translation> <translation id="5135404736266831032">पत्ते व्यवस्थापित करा...</translation> <translation id="5141240743006678641">तुमच्या Google क्रेडेंशियलसह सिंक केलेले पासवर्ड एंक्रिप्ट करा</translation> @@ -1148,7 +1146,6 @@ <translation id="8932102934695377596">तुमचे घड्याळ मागे आहे</translation> <translation id="893332455753468063">नाव जोडा</translation> <translation id="8938939909778640821">स्वीकारलेली क्रेडिट आणि प्रीपेड कार्डे</translation> -<translation id="8952525071319348207">तुमच्या कार्डाचे तपशील अपडेट करण्यासाठी <ph name="CREDIT_CARD" /> कार्डची मुदत संपण्याची तारीख आणि CVC टाका. तुम्ही निश्चित केल्यावर, तुमच्या Google पेमेंट खात्यावरील कार्डाचे तपशील या साइटसोबत शेअर केले जातील.</translation> <translation id="8957210676456822347">बंद पोर्टल प्राधिकृतता</translation> <translation id="8971063699422889582">सर्व्हरचे सर्टिफिकेट एक्स्पायर झाले आहे.</translation> <translation id="8975012916872825179">फोन नंबर, ईमेल अॅड्रेस आणि शिपिंग पत्ते यांसारखी माहिती समाविष्ट आहे</translation>
diff --git a/components/strings/components_strings_ms.xtb b/components/strings/components_strings_ms.xtb index 6a0efe88..fbc4566 100644 --- a/components/strings/components_strings_ms.xtb +++ b/components/strings/components_strings_ms.xtb
@@ -585,7 +585,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{dan 1 lagi halaman web}other{dan # lagi halaman web}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Masukkan CVC untuk <ph name="CREDIT_CARD" />. Setelah anda mengesahkan, butiran kad daripada akaun Google Payments anda akan dikongsi dengan tapak ini.</translation> <translation id="4923417429809017348">Halaman ini diterjemahkan dari bahasa yang tidak diketahui ke <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Pembayaran</translation> <translation id="4926049483395192435">Mesti ditentukan.</translation> @@ -617,7 +616,6 @@ <translation id="5095208057601539847">Wilayah</translation> <translation id="5098332213681597508">Nama ini daripada Akaun Google anda.</translation> <translation id="5115563688576182185">(64-bit)</translation> -<translation id="5121084798328133320">Setelah anda mengesahkan, butiran kad daripada akaun Google Payments anda akan dikongsi dengan tapak ini.</translation> <translation id="5128122789703661928">Sesi dengan nama ini tidak sah untuk pemadaman.</translation> <translation id="5135404736266831032">Urus alamat...</translation> <translation id="5141240743006678641">Sulitkan kata laluan yang disegerakkan dengan bukti kelayakan Google anda</translation> @@ -1149,7 +1147,6 @@ <translation id="8932102934695377596">Jam anda di belakang</translation> <translation id="893332455753468063">Tambahkan Nama</translation> <translation id="8938939909778640821">Kad kredit dan prabayar yang diterima</translation> -<translation id="8952525071319348207">Masukkan tarikh tamat tempoh dan CVC untuk <ph name="CREDIT_CARD" /> bagi mengemas kini butiran kad anda. Setelah anda mengesahkan, butiran kad daripada akaun Google Payments anda akan dikongsi dengan tapak ini.</translation> <translation id="8957210676456822347">Keizinan Portal Tawanan</translation> <translation id="8971063699422889582">Sijil pelayan telah tamat tempoh.</translation> <translation id="8975012916872825179">Merangkumi maklumat seperti nombor telefon, alamat e-mel dan alamat penghantaran</translation>
diff --git a/components/strings/components_strings_nl.xtb b/components/strings/components_strings_nl.xtb index 8e58899..30990c8 100644 --- a/components/strings/components_strings_nl.xtb +++ b/components/strings/components_strings_nl.xtb
@@ -580,7 +580,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{en nog 1 webpagina}other{en nog # webpagina's}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Geef de CVC-code voor <ph name="CREDIT_CARD" /> op. Nadat je hebt bevestigd, worden je kaartgegevens gedeeld met deze site.</translation> <translation id="4923417429809017348">Deze pagina is vertaald uit een onbekende taal naar het <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Betaling</translation> <translation id="4926049483395192435">Moet worden opgegeven.</translation> @@ -612,7 +611,6 @@ <translation id="5095208057601539847">Provincie</translation> <translation id="5098332213681597508">Dit is de naam die in je Google-account staat.</translation> <translation id="5115563688576182185">(64-bits)</translation> -<translation id="5121084798328133320">Nadat je hebt bevestigd, worden de kaartgegevens van je Google-betalingsaccount gedeeld met deze site.</translation> <translation id="5128122789703661928">De naam van deze sessie die je wilt verwijderen, is ongeldig.</translation> <translation id="5135404736266831032">Adressen beheren...</translation> <translation id="5141240743006678641">Gesynchroniseerde wachtwoorden versleutelen met je Google-aanmeldingsgegevens</translation> @@ -1142,7 +1140,6 @@ <translation id="8932102934695377596">Je klok loopt achter</translation> <translation id="893332455753468063">Naam toevoegen</translation> <translation id="8938939909778640821">Geaccepteerde creditcards en prepaidkaarten</translation> -<translation id="8952525071319348207">Geef de vervaldatum en CVC-code voor <ph name="CREDIT_CARD" /> op om je creditcardgegevens te updaten. Nadat je hebt bevestigd, worden je creditcardgegevens gedeeld met deze site.</translation> <translation id="8957210676456822347">Autorisatie van captive portal</translation> <translation id="8971063699422889582">Het servercertificaat is verlopen.</translation> <translation id="8975012916872825179">Inclusief informatie als telefoonnummers, e-mailadressen en verzendadressen</translation>
diff --git a/components/strings/components_strings_no.xtb b/components/strings/components_strings_no.xtb index 70cc232..2ecdea4 100644 --- a/components/strings/components_strings_no.xtb +++ b/components/strings/components_strings_no.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{og 1 nettside til}other{og # nettsider til}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Skriv inn CVC-koden for <ph name="CREDIT_CARD" />. Etter at du har bekreftet, deles kortopplysningene fra Google Payments-kontoen med dette nettstedet.</translation> <translation id="4923417429809017348">Denne siden er oversatt til <ph name="LANGUAGE_LANGUAGE" /> fra et ukjent språk</translation> <translation id="4923459931733593730">Betaling</translation> <translation id="4926049483395192435">Må angis.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Provins</translation> <translation id="5098332213681597508">Dette navnet er fra Google-kontoen din.</translation> <translation id="5115563688576182185">(64-bit)</translation> -<translation id="5121084798328133320">Etter at du har bekreftet, deles kortopplysningene fra Google Payments-kontoen med dette nettstedet.</translation> <translation id="5128122789703661928">Økten med dette navnet er ikke gyldig for sletting.</translation> <translation id="5135404736266831032">Adminstrer adresser…</translation> <translation id="5141240743006678641">Kryptér synkroniserte passord med Google-legitimasjonen din</translation> @@ -1146,7 +1144,6 @@ <translation id="8932102934695377596">Klokken går for sent</translation> <translation id="893332455753468063">Legg til navn</translation> <translation id="8938939909778640821">Godkjente kredittkort og forhåndsbetalte kort</translation> -<translation id="8952525071319348207">Skriv inn utløpsdatoen og CVC-koden for <ph name="CREDIT_CARD" /> for å oppdatere kortinformasjonen din. Når du bekrefter, deles kortopplysningene fra Google Payments-kontoen med dette nettstedet.</translation> <translation id="8957210676456822347">Captive Portal-autorisasjon</translation> <translation id="8971063699422889582">Tjenerens sertifikat er utløpt.</translation> <translation id="8975012916872825179">Inkluderer informasjon som telefonnumre, e-postadresser og leveringsadresser</translation>
diff --git a/components/strings/components_strings_pl.xtb b/components/strings/components_strings_pl.xtb index c60bae7..7ee7bca 100644 --- a/components/strings/components_strings_pl.xtb +++ b/components/strings/components_strings_pl.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{i jeszcze 1 strona}few{i jeszcze # strony}many{i jeszcze # stron}other{i jeszcze # strony}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Wpisz kod CVC karty <ph name="CREDIT_CARD" />. Po potwierdzeniu szczegółowe dane karty z Twojego konta Google Payments zostaną udostępnione tej stronie.</translation> <translation id="4923417429809017348">Ta strona została przetłumaczona z nieznanego języka na język <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Płatność</translation> <translation id="4926049483395192435">Musi być określona.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Prowincja</translation> <translation id="5098332213681597508">Ta nazwa pochodzi z Twojego konta Google.</translation> <translation id="5115563688576182185">(64-bitowa)</translation> -<translation id="5121084798328133320">Po potwierdzeniu szczegółowe dane karty z Twojego konta Google Payments zostaną udostępnione tej stronie.</translation> <translation id="5128122789703661928">Nie możesz usunąć tej sesji, bo jej nazwa jest nieprawidłowa.</translation> <translation id="5135404736266831032">Zarządzaj adresami…</translation> <translation id="5141240743006678641">Szyfruj synchronizowane hasła za pomocą danych logowania Google</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">Twój zegar się spóźnia</translation> <translation id="893332455753468063">Dodaj imię i nazwisko lub nazwę firmy</translation> <translation id="8938939909778640821">Akceptowane karty kredytowe i przedpłacone</translation> -<translation id="8952525071319348207">Wpisz datę ważności i kod CVC karty <ph name="CREDIT_CARD" />, by zaktualizować jej szczegółowe dane. Po potwierdzeniu dane karty z konta Google Payments zostaną udostępnione tej stronie.</translation> <translation id="8957210676456822347">Autoryzacja portalu przechwytującego</translation> <translation id="8971063699422889582">Ważność certyfikatu serwera wygasła.</translation> <translation id="8975012916872825179">Obejmuje numery telefonów, adresy e-mail i adresy dostawy</translation>
diff --git a/components/strings/components_strings_pt-BR.xtb b/components/strings/components_strings_pt-BR.xtb index 0c7918b..ce321c3 100644 --- a/components/strings/components_strings_pt-BR.xtb +++ b/components/strings/components_strings_pt-BR.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{e mais 1 página da Web}one{e mais # página da Web}other{e mais # páginas da Web}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Informe o CVC do <ph name="CREDIT_CARD" />. Depois da confirmação, os detalhes do cartão da sua conta do Google Payments serão compartilhados com esse site.</translation> <translation id="4923417429809017348">Esta página foi traduzida de um idioma desconhecido para o <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Pagamento</translation> <translation id="4926049483395192435">Deve ser especificado.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Província</translation> <translation id="5098332213681597508">Este nome é da sua Conta do Google.</translation> <translation id="5115563688576182185">64 bits</translation> -<translation id="5121084798328133320">Depois da confirmação, os detalhes do cartão da sua conta do Google Payments serão compartilhados com esse site.</translation> <translation id="5128122789703661928">A sessão com este nome não é válida para exclusão.</translation> <translation id="5135404736266831032">Gerenciar endereços…</translation> <translation id="5141240743006678641">Criptografar senhas sincronizadas com suas credenciais do Google</translation> @@ -1148,7 +1146,6 @@ <translation id="8932102934695377596">Seu relógio está atrasado</translation> <translation id="893332455753468063">Adicione um Nome</translation> <translation id="8938939909778640821">Cartões de crédito e pré-pagos aceitos</translation> -<translation id="8952525071319348207">Informe a data de validade e o CVC do <ph name="CREDIT_CARD" /> para atualizar os detalhes do cartão. Depois da confirmação, os detalhes do cartão da sua conta do Google Payments serão compartilhados com esse site.</translation> <translation id="8957210676456822347">Autorização de portal cativo</translation> <translation id="8971063699422889582">O certificado do servidor expirou.</translation> <translation id="8975012916872825179">Inclui informações como números de telefone, endereços de e-mail e endereços de entrega</translation>
diff --git a/components/strings/components_strings_pt-PT.xtb b/components/strings/components_strings_pt-PT.xtb index f90dda9..7bf569f9 100644 --- a/components/strings/components_strings_pt-PT.xtb +++ b/components/strings/components_strings_pt-PT.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{e mais 1 página Web}other{e mais # páginas Web}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Introduza o Código de Segurança/CVC de <ph name="CREDIT_CARD" />. Depois de confirmar, os detalhes do cartão da conta do Google Payments são partilhados com este site.</translation> <translation id="4923417429809017348">Esta página foi traduzida de um idioma desconhecido para <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Pagamento</translation> <translation id="4926049483395192435">Tem de ser especificado.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Província</translation> <translation id="5098332213681597508">Este nome é proveniente da sua Conta Google.</translation> <translation id="5115563688576182185">(64 bits)</translation> -<translation id="5121084798328133320">Depois de confirmar, os detalhes do cartão da conta do Google Payments são partilhados com este site.</translation> <translation id="5128122789703661928">A sessão com este nome não é válida para eliminação.</translation> <translation id="5135404736266831032">Gerir endereços…</translation> <translation id="5141240743006678641">Encriptar palavras-passe sincronizadas com as credenciais Google</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">O seu relógio está atrasado</translation> <translation id="893332455753468063">Adicionar nome</translation> <translation id="8938939909778640821">Cartões de crédito e pré-pagos admitidos</translation> -<translation id="8952525071319348207">Introduza a data de validade e o Código de Segurança/CVC de <ph name="CREDIT_CARD" /> para atualizar os detalhes do cartão. Depois de confirmar, os detalhes do cartão da conta do Google Payments são partilhados com este site.</translation> <translation id="8957210676456822347">Autorização de portal cativo</translation> <translation id="8971063699422889582">O certificado do servidor expirou.</translation> <translation id="8975012916872825179">Inclui informações como números de telefone, endereços de email e moradas para envio</translation>
diff --git a/components/strings/components_strings_ro.xtb b/components/strings/components_strings_ro.xtb index adec62a..5bf6cf06 100644 --- a/components/strings/components_strings_ro.xtb +++ b/components/strings/components_strings_ro.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{și încă 1 pagină web}few{și încă # pagini web}other{și încă # de pagini web}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Introdu codul CVC pentru <ph name="CREDIT_CARD" />. După ce confirmi, acest site va avea acces la detaliile cardului tău din contul Google Payments.</translation> <translation id="4923417429809017348">Această pagină a fost tradusă dintr-o limbă necunoscută în <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Plată</translation> <translation id="4926049483395192435">Valoarea trebuie specificată.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Provincie</translation> <translation id="5098332213681597508">Acest nume provine din Contul tău Google.</translation> <translation id="5115563688576182185">(64 de biți)</translation> -<translation id="5121084798328133320">După ce confirmi, acest site va avea acces la detaliile cardului tău din contul Google Payments.</translation> <translation id="5128122789703661928">Sesiunea cu acest nume nu este validă pentru ștergere.</translation> <translation id="5135404736266831032">Gestionează adresele...</translation> <translation id="5141240743006678641">Criptează parolele sincronizate cu datele de conectare Google</translation> @@ -1148,7 +1146,6 @@ <translation id="8932102934695377596">Ora este setată în trecut</translation> <translation id="893332455753468063">Adaugă un nume</translation> <translation id="8938939909778640821">Carduri de credit și preplătite acceptate</translation> -<translation id="8952525071319348207">Introdu data de expirare și codul CVC pentru <ph name="CREDIT_CARD" />, pentru a actualiza detaliile cardului. După ce confirmi, acest site va avea acces la detaliile cardului tău din contul Google Payments.</translation> <translation id="8957210676456822347">Autorizarea prin portalul captiv</translation> <translation id="8971063699422889582">Certificatul serverului a expirat.</translation> <translation id="8975012916872825179">Include informații precum numerele de telefon, adresele de e-mail și adresele de expediere</translation>
diff --git a/components/strings/components_strings_ru.xtb b/components/strings/components_strings_ru.xtb index 6deb641d1..df4b040 100644 --- a/components/strings/components_strings_ru.xtb +++ b/components/strings/components_strings_ru.xtb
@@ -583,7 +583,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" /> и <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{и ещё 1 веб-страница}one{и ещё # веб-страница}few{и ещё # веб-страницы}many{и ещё # веб-страниц}other{и ещё # веб-страницы}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Введите CVC-код карты <ph name="CREDIT_CARD" />. После этого ее реквизиты из платежного аккаунта Google будут переданы сайту.</translation> <translation id="4923417429809017348">Эта страница была автоматически переведена с неизвестного языка на <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Платеж</translation> <translation id="4926049483395192435">Укажите значение.</translation> @@ -615,7 +614,6 @@ <translation id="5095208057601539847">Провинция</translation> <translation id="5098332213681597508">Имя из вашего аккаунта Google.</translation> <translation id="5115563688576182185">(64 бит)</translation> -<translation id="5121084798328133320">После подтверждения реквизиты карты из платежного аккаунта Google будут переданы этому сайту.</translation> <translation id="5128122789703661928">Невозможно удалить сеанс с таким названием.</translation> <translation id="5135404736266831032">Управление адресами…</translation> <translation id="5141240743006678641">Шифровать синхронизированные пароли с помощью учетных данных Google</translation> @@ -1146,7 +1144,6 @@ <translation id="8932102934695377596">Часы отстают</translation> <translation id="893332455753468063">Добавьте имя</translation> <translation id="8938939909778640821">Кредитные карты и карты предоплаты, которые принимаются к оплате</translation> -<translation id="8952525071319348207">Введите срок окончания действия и CVC-код карты <ph name="CREDIT_CARD" />. После этого ее реквизиты из платежного аккаунта Google будут переданы сайту.</translation> <translation id="8957210676456822347">Авторизация через адаптивный портал</translation> <translation id="8971063699422889582">Сертификат сервера устарел.</translation> <translation id="8975012916872825179">В том числе телефонные номера, адреса электронной почты и адреса доставки.</translation>
diff --git a/components/strings/components_strings_sk.xtb b/components/strings/components_strings_sk.xtb index 7f88d38..f4836d1 100644 --- a/components/strings/components_strings_sk.xtb +++ b/components/strings/components_strings_sk.xtb
@@ -580,7 +580,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{a 1 ďalšia webová stránka}few{a # ďalšie webové stránky}many{a # ďalšej webovej stránky}other{a # ďalších webových stránok}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Zadajte kód CVC karty <ph name="CREDIT_CARD" />. Po potvrdení sa budú podrobnosti z účtu Google Payments zdieľať s týmto webom.</translation> <translation id="4923417429809017348">Táto stránka bola preložená z neznámeho jazyka do jazyka <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Platba</translation> <translation id="4926049483395192435">Musí byť určená.</translation> @@ -612,7 +611,6 @@ <translation id="5095208057601539847">Provincia</translation> <translation id="5098332213681597508">Tento názov pochádza z vášho účtu Google.</translation> <translation id="5115563688576182185">(64-bitová verzia)</translation> -<translation id="5121084798328133320">Po potvrdení sa budú podrobnosti z účtu Google Payments zdieľať s týmto webom.</translation> <translation id="5128122789703661928">Relácia s týmto názvom je neplatná a nedá sa odstrániť.</translation> <translation id="5135404736266831032">Spravovať adresy…</translation> <translation id="5141240743006678641">Šifrovať synchronizované heslá pomocou poverení Google</translation> @@ -1143,7 +1141,6 @@ <translation id="8932102934695377596">Vaše hodiny idú pozadu</translation> <translation id="893332455753468063">Pridanie mena</translation> <translation id="8938939909778640821">Akceptované kreditné a predplatené karty</translation> -<translation id="8952525071319348207">Ak chcete aktualizovať podrobnosti o karte <ph name="CREDIT_CARD" />, zadajte dátum vypršania platnosti a kód CVC. Po potvrdení sa budú podrobnosti z účtu Google Payments zdieľať s týmto webom.</translation> <translation id="8957210676456822347">Autorizácia portálu na prihlásenie do siete</translation> <translation id="8971063699422889582">Platnosť certifikátu servera vypršala.</translation> <translation id="8975012916872825179">Zahŕňa informácie, ako sú napríklad telefónne čísla, e‑maily a dodacie adresy</translation>
diff --git a/components/strings/components_strings_sl.xtb b/components/strings/components_strings_sl.xtb index fa86c4b..649e239 100644 --- a/components/strings/components_strings_sl.xtb +++ b/components/strings/components_strings_sl.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{in še 1 spletna stran}one{in še # spletna stran}two{in še # spletni strani}few{in še # spletne strani}other{in še # spletnih strani}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Vnesite CVC za <ph name="CREDIT_CARD" />. Ko potrdite, bodo temu spletnemu mestu razkriti podatki o kreditni kartici iz računa za Google Payments.</translation> <translation id="4923417429809017348">Stran je bila iz neznanega jezika prevedena v jezik »<ph name="LANGUAGE_LANGUAGE" />«</translation> <translation id="4923459931733593730">Plačilo</translation> <translation id="4926049483395192435">Vrednost mora biti določena.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Provinca</translation> <translation id="5098332213681597508">To ime je iz vašega Google Računa.</translation> <translation id="5115563688576182185">(64-bitno)</translation> -<translation id="5121084798328133320">Ko potrdite, bodo temu spletnemu mestu razkriti podatki o kreditni kartici iz računa za Google Payments.</translation> <translation id="5128122789703661928">Seja s tem imenom ni veljavna za izbris.</translation> <translation id="5135404736266831032">Upravljanje naslovov ...</translation> <translation id="5141240743006678641">Šifrirajte sinhronizirana gesla s poverilnicami za Google</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">Ura zaostaja</translation> <translation id="893332455753468063">Dodajanje imena</translation> <translation id="8938939909778640821">Sprejete kreditne in predplačniške kartice</translation> -<translation id="8952525071319348207">Vnesite datum poteka in CVC za <ph name="CREDIT_CARD" />, da posodobite podatke o kartici. Ko potrdite, bodo temu spletnemu mestu razkriti podatki o kreditni kartici iz računa za Google Payments.</translation> <translation id="8957210676456822347">Odobritev prestreznega portala</translation> <translation id="8971063699422889582">Potrdilo strežnika je poteklo.</translation> <translation id="8975012916872825179">Vključuje podatke, kot so telefonske številke, e-poštni naslovi in naslovi za pošiljanje</translation>
diff --git a/components/strings/components_strings_sr.xtb b/components/strings/components_strings_sr.xtb index 3c94668..3b0142b 100644 --- a/components/strings/components_strings_sr.xtb +++ b/components/strings/components_strings_sr.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{и јој 1 веб-страница}one{и још # веб-страница}few{и још # веб-странице}other{и још # веб-страница}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Унесите CVC за картицу <ph name="CREDIT_CARD" />. Када будете потврдили, подаци о картици са налога за Google плаћања ће бити послати овом сајту.</translation> <translation id="4923417429809017348">Ова страница је преведена са непознатог језика на <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Плаћање</translation> <translation id="4926049483395192435">Мора да буде наведено.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Провинција</translation> <translation id="5098332213681597508">То је име са вашег Google налога.</translation> <translation id="5115563688576182185">(64-битни)</translation> -<translation id="5121084798328133320">Када будете потврдили, подаци о картици са налога за Google плаћања ће бити послати овом сајту.</translation> <translation id="5128122789703661928">Сесија са овим називом није доступна за брисање.</translation> <translation id="5135404736266831032">Управљајте адресама...</translation> <translation id="5141240743006678641">Шифруј синхронизоване лозинке помоћу Google акредитива</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">Сат вам касни</translation> <translation id="893332455753468063">Додајте име</translation> <translation id="8938939909778640821">Прихватају се кредитне и припејд картице</translation> -<translation id="8952525071319348207">Унесите рок трајања и CVC за картицу <ph name="CREDIT_CARD" /> да бисте ажурирали податке о картици. Када будете потврдили, подаци о картици са налога за Google плаћања ће бити послати овом сајту.</translation> <translation id="8957210676456822347">Овлашћење на улазном порталу</translation> <translation id="8971063699422889582">Сертификат сервера је истекао.</translation> <translation id="8975012916872825179">Обухвата информације попут бројева телефона, имејл адреса и адреса за испоруку</translation>
diff --git a/components/strings/components_strings_sv.xtb b/components/strings/components_strings_sv.xtb index 09aa3cb..db0595b 100644 --- a/components/strings/components_strings_sv.xtb +++ b/components/strings/components_strings_sv.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{och en till webbsida}other{och # till webbsidor}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Ange CVC-koden för <ph name="CREDIT_CARD" />. När du bekräftar delas kortuppgifter från Google Paymens-betalningskonto med webbplatsen.</translation> <translation id="4923417429809017348">Sidan har översatts från ett okänt språk till <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Betalning</translation> <translation id="4926049483395192435">Värdet måste anges.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Provins</translation> <translation id="5098332213681597508">Det här namnet har hämtats från Google-kontot.</translation> <translation id="5115563688576182185">(64 bitar)</translation> -<translation id="5121084798328133320">När du bekräftar delas kortuppgifter från Google Payments-konto med webbplatsen.</translation> <translation id="5128122789703661928">Sessionen med det här namnet går inte att radera.</translation> <translation id="5135404736266831032">Hantera adresser …</translation> <translation id="5141240743006678641">Kryptera synkroniserade lösenord med dina inloggningsuppgifter för Google</translation> @@ -1148,7 +1146,6 @@ <translation id="8932102934695377596">Klockan går efter</translation> <translation id="893332455753468063">Lägg till namn</translation> <translation id="8938939909778640821">Godkända kreditkort och förbetalda kort</translation> -<translation id="8952525071319348207">Uppdatera kortinformationen genom att ange utgångsdatumet och CVC-koden för <ph name="CREDIT_CARD" />. När du bekräftar delas kortuppgifter från Google Payments-konto med webbplatsen.</translation> <translation id="8957210676456822347">Auktorisering av infångstportal</translation> <translation id="8971063699422889582">Servercertifikatet har gått ut.</translation> <translation id="8975012916872825179">Gäller uppgifter som telefonnummer, e-postadresser och leveransadresser</translation>
diff --git a/components/strings/components_strings_sw.xtb b/components/strings/components_strings_sw.xtb index 1e3b769..88665cc 100644 --- a/components/strings/components_strings_sw.xtb +++ b/components/strings/components_strings_sw.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{na ukurasa 1 zaidi wa wavuti}other{na kurasa # zaidi za wavuti}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Weka CVC ya <ph name="CREDIT_CARD" />. Baada ya kuthibitisha, maelezo ya kadi kutoka akaunti yako ya malipo ya Google yatashirikiwa na tovuti hii.</translation> <translation id="4923417429809017348">Ukurasa huu umetafsiriwa kutoka katika lugha ambayo haijulikani hadi <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Malipo</translation> <translation id="4926049483395192435">Sharti ibainishwe.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Mkoa</translation> <translation id="5098332213681597508">Jina hili linatoka kwenye Akaunti yako ya Google.</translation> <translation id="5115563688576182185">(biti 64)</translation> -<translation id="5121084798328133320">Baada ya kuthibitisha, maelezo ya kadi kutoka akaunti yako ya malipo ya Google yatashirikiwa na tovuti hii.</translation> <translation id="5128122789703661928">Huruhusiwi kufuta kipindi kilicho na jina hili.</translation> <translation id="5135404736266831032">Dhibiti anwani...</translation> <translation id="5141240743006678641">Simba kwa njia fiche manenosiri yaliyosawazishwa ukitumia stakabadhi zako za Google</translation> @@ -1144,7 +1142,6 @@ <translation id="8932102934695377596">Saa yako iko nyuma</translation> <translation id="893332455753468063">Ongeza Jina</translation> <translation id="8938939909778640821">Kadi za mikopo na za kulipia awali zinazokubaliwa</translation> -<translation id="8952525071319348207">Ili usasishe maelezo ya kadi yako, weka tarehe ya mwisho wa matumizi na CVC ya <ph name="CREDIT_CARD" />. Baada ya kuthibitisha, maelezo ya kadi kutoka akaunti yako ya malipo ya Google yatashirikiwa na tovuti hii.</translation> <translation id="8957210676456822347">Uidhinishaji wa Ukurasa wa Wavuti</translation> <translation id="8971063699422889582">Cheti cha seva kimechina.</translation> <translation id="8975012916872825179">Hujumuisha maelezo kama nambari za simu, anwani za barua pepe na anwani za mahali bidhaa zitakapopelekwa</translation>
diff --git a/components/strings/components_strings_ta.xtb b/components/strings/components_strings_ta.xtb index c2241ec..ded11e9a8 100644 --- a/components/strings/components_strings_ta.xtb +++ b/components/strings/components_strings_ta.xtb
@@ -581,7 +581,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{மேலும் ஒரு இணையப் பக்கம்}other{மேலும் # இணையப் பக்கங்கள்}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947"><ph name="CREDIT_CARD" /> இன் CVC எண்ணை உள்ளிடவும். உறுதிசெய்த பின்னர், உங்கள் Google Payments கணக்கிலிருக்கும் கார்டு விவரங்கள் இந்தத் தளத்துடன் பகிரப்படும்.</translation> <translation id="4923417429809017348">ஒரு அறியப்படாத மொழியிலிருந்து <ph name="LANGUAGE_LANGUAGE" /> -க்கு இந்தப் பக்கம் மொழிபெயர்க்கப்பட்டுள்ளது</translation> <translation id="4923459931733593730">கட்டண முறை</translation> <translation id="4926049483395192435">கட்டாயம் குறிப்பிட வேண்டும்.</translation> @@ -613,7 +612,6 @@ <translation id="5095208057601539847">பிராந்தியம்</translation> <translation id="5098332213681597508">இந்தப் பெயர் உங்கள் Google கணக்கிலிருந்து பெறப்பட்டது.</translation> <translation id="5115563688576182185">(64-பிட்)</translation> -<translation id="5121084798328133320">உறுதிசெய்த பின்னர், உங்கள் Google Payments கணக்கிலிருக்கும் கார்டு விவரங்கள் இந்தத் தளத்துடன் பகிரப்படும்.</translation> <translation id="5128122789703661928">இந்தப் பெயரைக் கொண்ட அமர்வானது நீக்குவதற்குத் தகுதியானதல்ல.</translation> <translation id="5135404736266831032">முகவரிகளை நிர்வகி...</translation> <translation id="5141240743006678641">ஒத்திசைக்கப்பட்ட கடவுச்சொற்களை உங்கள் Google அனுமதிச் சான்றுகள் மூலம் என்க்ரிப்ட் செய்யும்</translation> @@ -1143,7 +1141,6 @@ <translation id="8932102934695377596">உங்கள் கடிகாரம் மிகவும் பின்தங்கி இருக்கிறது</translation> <translation id="893332455753468063">பெயரைச் சேர்க்கவும்</translation> <translation id="8938939909778640821">ஏற்கப்படும் கிரெடிட் மற்றும் ப்ரீபெய்டு கார்டுகள்</translation> -<translation id="8952525071319348207">கார்டு விவரங்களைப் புதுப்பிக்க, <ph name="CREDIT_CARD" /> இன் காலாவதித் தேதியையும் CVC எண்ணையும் உள்ளிடவும். உறுதிசெய்த பின்னர், உங்கள் Google Payments கணக்கிலிருக்கும் கார்டு விவரங்கள் இந்தத் தளத்துடன் பகிரப்படும்.</translation> <translation id="8957210676456822347">கேப்டிவ் போர்டல் அங்கீகாரம்</translation> <translation id="8971063699422889582">சேவையகச் சான்றிதழ் காலாவதியானது.</translation> <translation id="8975012916872825179">இதில் ஃபோன் எண்கள், மின்னஞ்சல் முகவரிகள், ஷிப்பிங் முகவரிகள் போன்ற தகவல்கள் உள்ளடங்கும்</translation>
diff --git a/components/strings/components_strings_te.xtb b/components/strings/components_strings_te.xtb index e78596d5..98fd46b 100644 --- a/components/strings/components_strings_te.xtb +++ b/components/strings/components_strings_te.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{మరియు మరో 1 వెబ్ పేజీ}other{మరియు మరో # వెబ్ పేజీలు}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947"><ph name="CREDIT_CARD" /> కార్డ్ CVCని నమోదు చేయండి. మీరు నిర్ధారించిన తర్వాత, మీ Google చెల్లింపుల ఖాతా నుండి కార్డ్ వివరాలు ఈ సైట్తో షేర్ చేయబడతాయి.</translation> <translation id="4923417429809017348">ఈ పేజీ తెలియని భాష నుండి <ph name="LANGUAGE_LANGUAGE" />కు అనువదించబడింది</translation> <translation id="4923459931733593730">చెల్లింపు</translation> <translation id="4926049483395192435">ఖచ్చితంగా పేర్కొనాలి.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">ప్రావిన్స్</translation> <translation id="5098332213681597508">ఇది మీ Google ఖాతాలో ఉన్న పేరు</translation> <translation id="5115563688576182185">(64-బిట్)</translation> -<translation id="5121084798328133320">మీరు నిర్ధారించిన తర్వాత, మీ Google చెల్లింపుల ఖాతా నుండి కార్డ్ వివరాలు ఈ సైట్తో షేర్ చేయబడతాయి.</translation> <translation id="5128122789703661928">ఈ పేరు కలిగిన సెషన్ని తొలగించలేరు.</translation> <translation id="5135404736266831032">చిరునామాలను నిర్వహించండి...</translation> <translation id="5141240743006678641">మీ Google ఆధారాలతో సమకాలీకరించబడిన పాస్వర్డ్లను ఎన్క్రిప్ట్ చేయండి</translation> @@ -988,7 +986,7 @@ <translation id="7758069387465995638">ఫైర్వాల్ లేదా యాంటీవైరస్ సాఫ్ట్వేర్ కనెక్షన్ను బ్లాక్ చేసి ఉండవచ్చు.</translation> <translation id="7759163816903619567">ప్రదర్శన డొమైన్:</translation> <translation id="7761701407923456692">సర్వర్ సర్టిఫికెట్ URLతో సరిపోలలేదు.</translation> -<translation id="7763386264682878361">చెల్లింపు మానిఫెస్ట్ అన్వయ నియమం</translation> +<translation id="7763386264682878361">చెల్లింపు మానిఫెస్ట్ పార్సర్</translation> <translation id="7764225426217299476">చిరునామాను జోడించు</translation> <translation id="777702478322588152">అధికారిక నివాసం</translation> <translation id="7791543448312431591">జోడించు</translation> @@ -1063,7 +1061,7 @@ <translation id="8267698848189296333"><ph name="USERNAME" />గా సైన్ ఇన్ చేస్తోంది</translation> <translation id="8286036467436129157">సైన్ ఇన్ చేయండి</translation> <translation id="8288807391153049143">సర్టిఫికేట్ని చూపు</translation> -<translation id="8289355894181816810">మీకు దీని గురించి ఖచ్చితంగా తెలియకుంటే మీ నెట్వర్క్ నిర్వాహకుని సంప్రదించండి.</translation> +<translation id="8289355894181816810">మీకు దీని గురించి ఖచ్చితంగా తెలియకుంటే మీ నెట్వర్క్ నిర్వాహకుడిని సంప్రదించండి.</translation> <translation id="8293206222192510085">బుక్మార్క్ను జోడించండి</translation> <translation id="8294431847097064396">మూలం</translation> <translation id="8298115750975731693">మీరు ఉపయోగిస్తున్న Wi-Fi (<ph name="WIFI_NAME" />)కి మీరు <ph name="BEGIN_BOLD" /><ph name="LOGIN_URL" /><ph name="END_BOLD" />ని సందర్శించడం అవసరం.</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">మీ గడియారం సమయం గతంలో ఉంది</translation> <translation id="893332455753468063">పేరుని జోడించండి</translation> <translation id="8938939909778640821">ఆమోదించబడిన క్రెడిట్ మరియు ప్రీపెయిడ్ కార్డ్లు</translation> -<translation id="8952525071319348207">మీ కార్డ్ వివరాలను అప్డేట్ చేయడానికి <ph name="CREDIT_CARD" /> కార్డ్ గడువు ముగింపు తేదీ మరియు CVCని నమోదు చేయండి. మీరు నిర్ధారించిన తర్వాత, మీ Google చెల్లింపుల ఖాతా నుండి కార్డ్ వివరాలు ఈ సైట్తో షేర్ చేయబడతాయి.</translation> <translation id="8957210676456822347">క్యాప్టివ్ పోర్టల్ ప్రామాణీకరణ</translation> <translation id="8971063699422889582">సర్వర్ యొక్క ప్రమాణపత్రం గడువు ముగిసింది.</translation> <translation id="8975012916872825179">ఫోన్ నంబర్లు, ఇమెయిల్ చిరునామాలు మరియు బట్వాడా చిరునామాలు లాంటి సమాచారం ఉంటుంది</translation>
diff --git a/components/strings/components_strings_th.xtb b/components/strings/components_strings_th.xtb index bf9373a9c..372fbfca9 100644 --- a/components/strings/components_strings_th.xtb +++ b/components/strings/components_strings_th.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" /> และ <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{และหน้าเว็บอีก 1 หน้า}other{และหน้าเว็บอีก # หน้า}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">ป้อน CVC สำหรับ <ph name="CREDIT_CARD" /> เมื่อยืนยันแล้ว ระบบจะแชร์รายละเอียดของบัตรจากบัญชี Google Payments กับเว็บไซต์นี้</translation> <translation id="4923417429809017348">หน้านี้แปลจากภาษาที่ไม่รู้จักเป็นภาษา <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">การชำระเงิน</translation> <translation id="4926049483395192435">ต้องระบุ</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">จังหวัด</translation> <translation id="5098332213681597508">ชื่อนี้มาจากบัญชี Google ของคุณ</translation> <translation id="5115563688576182185">(64 บิต)</translation> -<translation id="5121084798328133320">เมื่อยืนยันแล้ว ระบบจะแชร์รายละเอียดของบัตรจากบัญชี Google Payments กับเว็บไซต์นี้</translation> <translation id="5128122789703661928">ลบเซสชันที่ใช้ชื่อนี้ไม่ได้</translation> <translation id="5135404736266831032">จัดการที่อยู่...</translation> <translation id="5141240743006678641">เข้ารหัสผ่านที่ซิงค์ด้วยข้อมูลรับรอง Google ของคุณ</translation> @@ -1148,7 +1146,6 @@ <translation id="8932102934695377596">นาฬิกาช้าเกินไป</translation> <translation id="893332455753468063">เพิ่มชื่อ</translation> <translation id="8938939909778640821">บัตรเครดิตและบัตรเติมเงินที่ยอมรับ</translation> -<translation id="8952525071319348207">ป้อนวันที่หมดอายุและ CVC สำหรับ <ph name="CREDIT_CARD" /> เพื่ออัปเดตรายละเอียดของบัตร เมื่อยืนยันแล้ว ระบบจะแชร์รายละเอียดของบัตรจากบัญชี Google Payments กับเว็บไซต์นี้</translation> <translation id="8957210676456822347">การให้สิทธิ์แคปทีฟพอร์ทัล</translation> <translation id="8971063699422889582">ใบรับรองของเซิร์ฟเวอร์หมดอายุแล้ว</translation> <translation id="8975012916872825179">รวมข้อมูล เช่น หมายเลขโทรศัพท์ ที่อยู่อีเมล และที่อยู่สำหรับจัดส่ง</translation>
diff --git a/components/strings/components_strings_tr.xtb b/components/strings/components_strings_tr.xtb index 2ba0017..a003b58d 100644 --- a/components/strings/components_strings_tr.xtb +++ b/components/strings/components_strings_tr.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{ve 1 web sayfası daha}other{ve # web sayfası daha}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947"><ph name="CREDIT_CARD" /> numaralı kartın CVC kodunu girin. Onayladığınızda Google Payments hesabınızdaki kart bilgileriniz bu siteyle paylaşılır.</translation> <translation id="4923417429809017348">Bu sayfa, bilinmeyen bir dilden <ph name="LANGUAGE_LANGUAGE" /> diline çevrildi</translation> <translation id="4923459931733593730">Ödeme</translation> <translation id="4926049483395192435">Belirtilmelidir.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Bölge</translation> <translation id="5098332213681597508">Bu ad Google Hesabınızdan gelmektedir.</translation> <translation id="5115563688576182185">(64 bit)</translation> -<translation id="5121084798328133320">Onayladığınızda Google Payments hesabınızdaki kart bilgileriniz bu siteyle paylaşılır.</translation> <translation id="5128122789703661928">Silmek üzere gönderilen bu oturum adı geçerli değil.</translation> <translation id="5135404736266831032">Adresleri yönet...</translation> <translation id="5141240743006678641">Senkronize edilen şifreleri Google kimlik bilgilerinizle şifreleyin</translation> @@ -1148,7 +1146,6 @@ <translation id="8932102934695377596">Saatiniz geri</translation> <translation id="893332455753468063">Ad Ekleyin</translation> <translation id="8938939909778640821">Kabul edilen kredi kartları ve ön ödemeli kartlar</translation> -<translation id="8952525071319348207">Kart bilgilerinizi güncellemek için <ph name="CREDIT_CARD" /> numaralı karta ilişkin son kullanma tarihini ve CVC kodunu girin. Onayladığınızda Googe Payments hesabınızdaki kart bilgileriniz bu siteyle paylaşılır.</translation> <translation id="8957210676456822347">Giriş Portalı Yetkilendirmesi</translation> <translation id="8971063699422889582">Sunucu sertifikasının süresi doldu.</translation> <translation id="8975012916872825179">Telefon numaraları, e-posta adresleri ve gönderim adresleri gibi bilgileri içerir</translation>
diff --git a/components/strings/components_strings_uk.xtb b/components/strings/components_strings_uk.xtb index 57e7e5de..0766e222 100644 --- a/components/strings/components_strings_uk.xtb +++ b/components/strings/components_strings_uk.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{і ще 1 веб-сторінка}one{і ще # веб-сторінка}few{і ще # веб-сторінки}many{і ще # веб-сторінок}other{і ще # веб-сторінки}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Введіть код CVC картки <ph name="CREDIT_CARD" />. Щойно ви підтвердите дані картки з облікового запису Google Payments, цей сайт отримає доступ до них.</translation> <translation id="4923417429809017348">Цю сторінку перекладено з невідомої мови оригіналу такою мовою: <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Оплата</translation> <translation id="4926049483395192435">Потрібно вказати.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Провінція чи область</translation> <translation id="5098332213681597508">Це ім’я з вашого облікового запису Google.</translation> <translation id="5115563688576182185">(64-розрядна версія)</translation> -<translation id="5121084798328133320">Щойно ви підтвердите дані картки з облікового запису Google Payments, цей сайт отримає доступ до них.</translation> <translation id="5128122789703661928">Сеанс із цією назвою не можна видалити.</translation> <translation id="5135404736266831032">Керувати адресами…</translation> <translation id="5141240743006678641">Шифрувати синхронізовані паролі за допомогою облікових даних Google</translation> @@ -1148,7 +1146,6 @@ <translation id="8932102934695377596">Ваш годинник запізнюється</translation> <translation id="893332455753468063">Додайте ім’я</translation> <translation id="8938939909778640821">Прийнятні кредитні та передплачені картки</translation> -<translation id="8952525071319348207">Введіть термін дії та код CVC картки <ph name="CREDIT_CARD" />, щоб оновити її дані. Щойно ви підтвердите дані картки з облікового запису Google Payments, цей сайт отримає доступ до них.</translation> <translation id="8957210676456822347">Авторизація приєднаного порталу</translation> <translation id="8971063699422889582">Термін дії сертифіката сервера завершився.</translation> <translation id="8975012916872825179">Номери телефонів, електронні адреси, адреси доставки тощо</translation>
diff --git a/components/strings/components_strings_vi.xtb b/components/strings/components_strings_vi.xtb index 7656ef55..0d5fbdd4 100644 --- a/components/strings/components_strings_vi.xtb +++ b/components/strings/components_strings_vi.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{và thêm 1 trang web}other{và thêm # trang web}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">Hãy nhập CVC cho <ph name="CREDIT_CARD" />. Sau khi bạn xác nhận, thông tin chi tiết thẻ từ tài khoản thanh toán Google của bạn sẽ được chia sẻ với trang web này.</translation> <translation id="4923417429809017348">Trang này đã được dịch từ một ngôn ngữ không xác định sang <ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">Thanh toán</translation> <translation id="4926049483395192435">Phải được chỉ định.</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">Tỉnh/thành phố</translation> <translation id="5098332213681597508">Tên này lấy từ Tài khoản Google của bạn.</translation> <translation id="5115563688576182185">(64 bit)</translation> -<translation id="5121084798328133320">Sau khi bạn xác nhận, thông tin chi tiết thẻ từ tài khoản thanh toán Google của bạn sẽ được chia sẻ với trang web này.</translation> <translation id="5128122789703661928">Không thể xóa phiên do tên phiên không hợp lệ.</translation> <translation id="5135404736266831032">Quản lý địa chỉ...</translation> <translation id="5141240743006678641">Mã hóa mật khẩu đã đồng bộ hóa với thông tin đăng nhập Google của bạn</translation> @@ -1148,7 +1146,6 @@ <translation id="8932102934695377596">Đồng hồ của bạn chạy chậm</translation> <translation id="893332455753468063">Thêm tên</translation> <translation id="8938939909778640821">Thẻ tín dụng và thẻ trả trước được chấp nhận</translation> -<translation id="8952525071319348207">Hãy nhập ngày hết hạn và CVC cho <ph name="CREDIT_CARD" /> để cập nhật thông tin chi tiết thẻ của bạn. Sau khi bạn xác nhận, thông tin chi tiết thẻ từ tài khoản thanh toán Google sẽ được chia sẻ với trang web này.</translation> <translation id="8957210676456822347">Ủy quyền cổng bị khóa</translation> <translation id="8971063699422889582">Chứng chỉ của máy chủ đã hết hạn.</translation> <translation id="8975012916872825179">Bao gồm các thông tin như số điện thoại, địa chỉ email và địa chỉ giao hàng</translation>
diff --git a/components/strings/components_strings_zh-CN.xtb b/components/strings/components_strings_zh-CN.xtb index 7fd695e..46c6767e 100644 --- a/components/strings/components_strings_zh-CN.xtb +++ b/components/strings/components_strings_zh-CN.xtb
@@ -581,7 +581,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />、<ph name="TYPE_2" />、<ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{和另外 1 个网页}other{和另外 # 个网页}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">请输入 <ph name="CREDIT_CARD" /> 的银行卡验证码 (CVC)。在您确认之后,您的 Google Payments 帐号中的信用卡详细信息将会共享给该网站。</translation> <translation id="4923417429809017348">翻译服务器已将此网页从某种未知语言翻译成了<ph name="LANGUAGE_LANGUAGE" />。</translation> <translation id="4923459931733593730">付款</translation> <translation id="4926049483395192435">必须指定。</translation> @@ -613,7 +612,6 @@ <translation id="5095208057601539847">省</translation> <translation id="5098332213681597508">此名称来自您的 Google 帐号。</translation> <translation id="5115563688576182185">(64 位)</translation> -<translation id="5121084798328133320">在您确认之后,您的 Google Payments 帐号中的信用卡详细信息将会共享给该网站。</translation> <translation id="5128122789703661928">无法删除此会话,因为它的名称无效。</translation> <translation id="5135404736266831032">管理地址…</translation> <translation id="5141240743006678641">使用您的 Google 凭据加密已同步的密码</translation> @@ -1144,7 +1142,6 @@ <translation id="8932102934695377596">您的时钟慢了</translation> <translation id="893332455753468063">添加名称</translation> <translation id="8938939909778640821">接受的信用卡和预付卡</translation> -<translation id="8952525071319348207">请输入 <ph name="CREDIT_CARD" /> 的失效日期和银行卡验证码 (CVC),以更新您的信用卡详细信息。在您确认之后,您的 Google Payments 帐号中的信用卡详细信息将会共享给该网站。</translation> <translation id="8957210676456822347">强制门户授权</translation> <translation id="8971063699422889582">服务器的证书已过期。</translation> <translation id="8975012916872825179">包括电话号码、电子邮件地址和送货地址等信息</translation>
diff --git a/components/strings/components_strings_zh-TW.xtb b/components/strings/components_strings_zh-TW.xtb index ded10b1..d7584dd 100644 --- a/components/strings/components_strings_zh-TW.xtb +++ b/components/strings/components_strings_zh-TW.xtb
@@ -584,7 +584,6 @@ <translation id="4895877746940133817"><ph name="TYPE_1" />、<ph name="TYPE_2" />,<ph name="TYPE_3" /></translation> <translation id="4914479371620770914">{URL_count,plural, =1{還有另外 1 個網頁}other{還有另外 # 個網頁}}</translation> <translation id="4916962322362512664"><ph name="DEVICE_NAME" /></translation> -<translation id="4919958102839282947">請輸入 <ph name="CREDIT_CARD" /> 的信用卡安全碼。完成驗證後,這個網站就會取得你 Google 付款帳戶中的信用卡詳細資料。</translation> <translation id="4923417429809017348">系統已將此網頁從不明語言翻譯成<ph name="LANGUAGE_LANGUAGE" /></translation> <translation id="4923459931733593730">付款</translation> <translation id="4926049483395192435">必須指定。</translation> @@ -616,7 +615,6 @@ <translation id="5095208057601539847">省</translation> <translation id="5098332213681597508">這是你在 Google 帳戶中設定的名稱。</translation> <translation id="5115563688576182185">(64 位元)</translation> -<translation id="5121084798328133320">完成驗證後,這個網站就會取得你 Google 付款帳戶中的信用卡詳細資料。</translation> <translation id="5128122789703661928">無法將使用這個名稱的工作階段刪除。</translation> <translation id="5135404736266831032">管理地址...</translation> <translation id="5141240743006678641">使用你的 Google 憑證對已同步處理的密碼進行加密</translation> @@ -1147,7 +1145,6 @@ <translation id="8932102934695377596">你的時鐘時間過慢</translation> <translation id="893332455753468063">新增名稱</translation> <translation id="8938939909778640821">接受的信用卡和預付卡</translation> -<translation id="8952525071319348207">請輸入 <ph name="CREDIT_CARD" /> 的到期日和信用卡安全碼,以更新你的信用卡詳細資料。完成驗證後,這個網站就會取得你 Google 付款帳戶中的信用卡詳細資料。</translation> <translation id="8957210676456822347">監控式入口網站授權</translation> <translation id="8971063699422889582">伺服器憑證已過期。</translation> <translation id="8975012916872825179">包括電話號碼、電子郵件地址和運送地址等資訊</translation>
diff --git a/components/sync/driver/generic_change_processor.cc b/components/sync/driver/generic_change_processor.cc index 65022e1..44b7a1d 100644 --- a/components/sync/driver/generic_change_processor.cc +++ b/components/sync/driver/generic_change_processor.cc
@@ -53,8 +53,7 @@ password_holder.mutable_password() ->mutable_client_only_encrypted_data() ->CopyFrom(read_node.GetPasswordSpecifics()); - return SyncData::CreateRemoteData(sync_id, password_holder, - read_node.GetModificationTime()); + return SyncData::CreateRemoteData(sync_id, password_holder); } case SESSIONS: // Include tag hashes for sessions data type to allow discarding during @@ -66,12 +65,11 @@ // another copy of this string around. return SyncData::CreateRemoteData( sync_id, read_node.GetEntitySpecifics(), - read_node.GetModificationTime(), read_node.GetEntry()->GetUniqueClientTag()); default: // Use the specifics directly, encryption has already been handled. - return SyncData::CreateRemoteData(sync_id, read_node.GetEntitySpecifics(), - read_node.GetModificationTime()); + return SyncData::CreateRemoteData(sync_id, + read_node.GetEntitySpecifics()); } } @@ -114,10 +112,10 @@ ->mutable_client_only_encrypted_data() ->CopyFrom(it->extra->unencrypted()); } - syncer_changes_.push_back(SyncChange( - FROM_HERE, SyncChange::ACTION_DELETE, - SyncData::CreateRemoteData( - it->id, specifics ? *specifics : it->specifics, base::Time()))); + syncer_changes_.push_back( + SyncChange(FROM_HERE, SyncChange::ACTION_DELETE, + SyncData::CreateRemoteData( + it->id, specifics ? *specifics : it->specifics))); } else { SyncChange::SyncChangeType action = (it->action == ChangeRecord::ACTION_ADD) ? SyncChange::ACTION_ADD
diff --git a/components/sync/model/sync_change_unittest.cc b/components/sync/model/sync_change_unittest.cc index 909b7e1..c4a7aa3c 100644 --- a/components/sync/model/sync_change_unittest.cc +++ b/components/sync/model/sync_change_unittest.cc
@@ -84,9 +84,9 @@ sync_pb::PreferenceSpecifics* pref_specifics = update_specifics.mutable_preference(); pref_specifics->set_name("update"); - change_list.push_back(SyncChange( - FROM_HERE, SyncChange::ACTION_UPDATE, - SyncData::CreateRemoteData(1, update_specifics, base::Time()))); + change_list.push_back( + SyncChange(FROM_HERE, SyncChange::ACTION_UPDATE, + SyncData::CreateRemoteData(1, update_specifics))); // Create an add. sync_pb::EntitySpecifics add_specifics; @@ -94,15 +94,15 @@ pref_specifics->set_name("add"); change_list.push_back( SyncChange(FROM_HERE, SyncChange::ACTION_ADD, - SyncData::CreateRemoteData(2, add_specifics, base::Time()))); + SyncData::CreateRemoteData(2, add_specifics))); // Create a delete. sync_pb::EntitySpecifics delete_specifics; pref_specifics = delete_specifics.mutable_preference(); pref_specifics->set_name("add"); - change_list.push_back(SyncChange( - FROM_HERE, SyncChange::ACTION_DELETE, - SyncData::CreateRemoteData(3, delete_specifics, base::Time()))); + change_list.push_back( + SyncChange(FROM_HERE, SyncChange::ACTION_DELETE, + SyncData::CreateRemoteData(3, delete_specifics))); ASSERT_EQ(3U, change_list.size());
diff --git a/components/sync/model/sync_data.cc b/components/sync/model/sync_data.cc index 140d1fab..3dadfaf1 100644 --- a/components/sync/model/sync_data.cc +++ b/components/sync/model/sync_data.cc
@@ -42,12 +42,8 @@ SyncData::SyncData() : id_(kInvalidId), is_local_(false), is_valid_(false) {} -SyncData::SyncData(bool is_local, - int64_t id, - sync_pb::SyncEntity* entity, - const base::Time& remote_modification_time) +SyncData::SyncData(bool is_local, int64_t id, sync_pb::SyncEntity* entity) : id_(id), - remote_modification_time_(remote_modification_time), immutable_entity_(entity), is_local_(is_local), is_valid_(true) {} @@ -72,18 +68,17 @@ entity.set_client_defined_unique_tag(sync_tag); entity.set_non_unique_name(non_unique_title); entity.mutable_specifics()->CopyFrom(specifics); - return SyncData(/*is_local=*/true, kInvalidId, &entity, base::Time()); + return SyncData(/*is_local=*/true, kInvalidId, &entity); } // Static. SyncData SyncData::CreateRemoteData(int64_t id, sync_pb::EntitySpecifics specifics, - base::Time modification_time, std::string client_tag_hash) { sync_pb::SyncEntity entity; *entity.mutable_specifics() = std::move(specifics); entity.set_client_defined_unique_tag(std::move(client_tag_hash)); - return SyncData(/*is_local=*/false, id, &entity, modification_time); + return SyncData(/*is_local=*/false, id, &entity); } bool SyncData::IsValid() const { @@ -152,10 +147,6 @@ SyncDataRemote::~SyncDataRemote() {} -const base::Time& SyncDataRemote::GetModifiedTime() const { - return remote_modification_time_; -} - int64_t SyncDataRemote::GetId() const { DCHECK(!IsLocal()); DCHECK_NE(id_, kInvalidId);
diff --git a/components/sync/model/sync_data.h b/components/sync/model/sync_data.h index 35742f00..e0b5d4c4 100644 --- a/components/sync/model/sync_data.h +++ b/components/sync/model/sync_data.h
@@ -61,7 +61,6 @@ // Helper method for creating SyncData objects originating from the syncer. static SyncData CreateRemoteData(int64_t id, sync_pb::EntitySpecifics specifics, - base::Time last_modified_time, std::string client_tag_hash = std::string()); // Whether this SyncData holds valid data. The only way to have a SyncData @@ -111,11 +110,6 @@ int64_t id_; - // This may be null if the SyncData represents a deleted item. - // TODO(crbug.com/895455): Remove when directory-based sessions sync is - // removed, the only remaining reader. - base::Time remote_modification_time_; - // The actual shared sync entity being held. ImmutableSyncEntity immutable_entity_; @@ -127,10 +121,7 @@ bool is_valid_; // Clears |entity|. - SyncData(bool is_local_, - int64_t id, - sync_pb::SyncEntity* entity, - const base::Time& remote_modification_time); + SyncData(bool is_local_, int64_t id, sync_pb::SyncEntity* entity); }; // A SyncData going to the syncer. @@ -156,12 +147,6 @@ explicit SyncDataRemote(const SyncData& sync_data); ~SyncDataRemote(); - // Return the last motification time according to the server. This may be null - // if the SyncData represents a deleted item. - // TODO(crbug.com/895455): Remove when directory-based sessions sync is - // removed, the only remaining reader. - const base::Time& GetModifiedTime() const; - // Returns the tag hash value. May not always be present, in which case an // empty string will be returned. const std::string& GetClientTagHash() const;
diff --git a/components/sync/model/sync_data_unittest.cc b/components/sync/model/sync_data_unittest.cc index 6dc5d8d7..001ca7ad 100644 --- a/components/sync/model/sync_data_unittest.cc +++ b/components/sync/model/sync_data_unittest.cc
@@ -23,7 +23,6 @@ const ModelType kDatatype = PREFERENCES; const char kNonUniqueTitle[] = "my preference"; const int64_t kId = 439829; -const base::Time kLastModifiedTime = base::Time(); class SyncDataTest : public testing::Test { protected: @@ -59,21 +58,18 @@ TEST_F(SyncDataTest, CreateRemoteData) { specifics.mutable_preference(); - SyncData data = SyncData::CreateRemoteData(kId, specifics, kLastModifiedTime); + SyncData data = SyncData::CreateRemoteData(kId, specifics); EXPECT_TRUE(data.IsValid()); EXPECT_FALSE(data.IsLocal()); EXPECT_EQ(kId, SyncDataRemote(data).GetId()); - EXPECT_EQ(kLastModifiedTime, SyncDataRemote(data).GetModifiedTime()); EXPECT_TRUE(data.GetSpecifics().has_preference()); } TEST_F(SyncDataTest, CreateRemoteDataWithInvalidId) { specifics.mutable_preference(); - SyncData data = - SyncData::CreateRemoteData(kInvalidId, specifics, kLastModifiedTime); + SyncData data = SyncData::CreateRemoteData(kInvalidId, specifics); EXPECT_TRUE(data.IsValid()); EXPECT_FALSE(data.IsLocal()); - EXPECT_EQ(kLastModifiedTime, SyncDataRemote(data).GetModifiedTime()); EXPECT_TRUE(data.GetSpecifics().has_preference()); }
diff --git a/components/sync/model_impl/syncable_service_based_bridge.cc b/components/sync/model_impl/syncable_service_based_bridge.cc index 39eed5d..3083205f 100644 --- a/components/sync/model_impl/syncable_service_based_bridge.cc +++ b/components/sync/model_impl/syncable_service_based_bridge.cc
@@ -612,7 +612,6 @@ initial_sync_data.push_back(SyncData::CreateRemoteData( /*id=*/kInvalidNodeId, std::move(specifics), - /*last_modified_time=*/base::Time(), // Used by legacy sessions only. /*client_tag_hash=*/record.first)); } @@ -674,7 +673,6 @@ FROM_HERE, SyncChange::ACTION_DELETE, SyncData::CreateRemoteData( /*id=*/kInvalidNodeId, std::move(specifics), - change.data().modification_time, change.data().client_tag_hash)); // For tombstones, there is no actual data, which means no client tag @@ -723,7 +721,6 @@ SyncData::CreateRemoteData( /*id=*/kInvalidNodeId, std::move(*persisted_entity.mutable_specifics()), - change.data().modification_time, change.data().client_tag_hash)); break;
diff --git a/components/sync/model_impl/syncable_service_based_bridge_unittest.cc b/components/sync/model_impl/syncable_service_based_bridge_unittest.cc index 5b9643f..d151888 100644 --- a/components/sync/model_impl/syncable_service_based_bridge_unittest.cc +++ b/components/sync/model_impl/syncable_service_based_bridge_unittest.cc
@@ -719,7 +719,6 @@ change_list.push_back(SyncChange( FROM_HERE, SyncChange::ACTION_DELETE, SyncData::CreateRemoteData(/*id=*/1, specifics, - /*last_modified_time=*/base::Time::Now(), /*client_tag_hash=*/kClientTagHash))); sync_change_processor->ProcessSyncChanges(FROM_HERE, change_list); @@ -755,7 +754,6 @@ change_list.push_back(SyncChange( FROM_HERE, SyncChange::ACTION_DELETE, SyncData::CreateRemoteData(/*id=*/1, specifics, - /*last_modified_time=*/base::Time::Now(), /*client_tag_hash=*/kClientTagHash))); sync_change_processor->ProcessSyncChanges(FROM_HERE, change_list);
diff --git a/components/sync_preferences/OWNERS b/components/sync_preferences/OWNERS index 17dc7671..2142ec0 100644 --- a/components/sync_preferences/OWNERS +++ b/components/sync_preferences/OWNERS
@@ -1,3 +1,4 @@ +file://components/sync/OWNERS battre@chromium.org gab@chromium.org
diff --git a/components/sync_preferences/pref_service_syncable_unittest.cc b/components/sync_preferences/pref_service_syncable_unittest.cc index a8f25533..c96501f 100644 --- a/components/sync_preferences/pref_service_syncable_unittest.cc +++ b/components/sync_preferences/pref_service_syncable_unittest.cc
@@ -124,9 +124,8 @@ sync_pb::PreferenceSpecifics* pref_one = entity.mutable_preference(); pref_one->set_name(name); pref_one->set_value(serialized); - return syncer::SyncChange( - FROM_HERE, type, - syncer::SyncData::CreateRemoteData(id, entity, base::Time())); + return syncer::SyncChange(FROM_HERE, type, + syncer::SyncData::CreateRemoteData(id, entity)); } void AddToRemoteDataList(const std::string& name, @@ -139,8 +138,8 @@ sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference(); pref_one->set_name(name); pref_one->set_value(serialized); - out->push_back(SyncData::CreateRemoteData(++next_pref_remote_sync_node_id_, - one, base::Time())); + out->push_back( + SyncData::CreateRemoteData(++next_pref_remote_sync_node_id_, one)); } void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data, @@ -372,9 +371,8 @@ sync_pb::PreferenceSpecifics* pref_one = entity.mutable_preference(); pref_one->set_name(name); pref_one->set_value(serialized); - return syncer::SyncChange( - FROM_HERE, type, - syncer::SyncData::CreateRemoteData(id, entity, base::Time())); + return syncer::SyncChange(FROM_HERE, type, + syncer::SyncData::CreateRemoteData(id, entity)); } void AddToRemoteDataList(const std::string& name, @@ -387,8 +385,8 @@ sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference(); pref_one->set_name(name); pref_one->set_value(serialized); - out->push_back(SyncData::CreateRemoteData(++next_pref_remote_sync_node_id_, - one, base::Time())); + out->push_back( + SyncData::CreateRemoteData(++next_pref_remote_sync_node_id_, one)); } void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data,
diff --git a/components/sync_sessions/favicon_cache_unittest.cc b/components/sync_sessions/favicon_cache_unittest.cc index 9357e63..8fd9be4 100644 --- a/components/sync_sessions/favicon_cache_unittest.cc +++ b/components/sync_sessions/favicon_cache_unittest.cc
@@ -648,11 +648,11 @@ FillImageSpecifics(BuildFaviconData(i), image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); } syncer::SyncMergeResult merge_result = @@ -717,11 +717,11 @@ image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); FillTrackingSpecifics(test_data, tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); } syncer::SyncMergeResult merge_result = @@ -792,11 +792,11 @@ image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); FillTrackingSpecifics(test_data, tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); } syncer::SyncMergeResult merge_result = @@ -849,16 +849,16 @@ FillImageSpecifics(BuildFaviconData(i), image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); expected_change_types.push_back(syncer::SyncChange::ACTION_UPDATE); image_specifics.mutable_favicon_image()->clear_favicon_web(); stale_changes.push_back(syncer::SyncChange( FROM_HERE, syncer::SyncChange::ACTION_UPDATE, - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()))); + syncer::SyncData::CreateRemoteData(1, image_specifics))); FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); } SetUpInitialSync(initial_image_data, initial_tracking_data); @@ -888,17 +888,17 @@ image_specifics.mutable_favicon_image()); new_changes.push_back(syncer::SyncChange( FROM_HERE, syncer::SyncChange::ACTION_UPDATE, - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()))); + syncer::SyncData::CreateRemoteData(1, image_specifics))); image_specifics.mutable_favicon_image() ->mutable_favicon_web() ->mutable_favicon() ->append("old"); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); } SetUpInitialSync(initial_image_data, initial_tracking_data); @@ -922,13 +922,13 @@ image_specifics.mutable_favicon_image()); same_changes.push_back(syncer::SyncChange( FROM_HERE, syncer::SyncChange::ACTION_UPDATE, - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()))); + syncer::SyncData::CreateRemoteData(1, image_specifics))); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); } SetUpInitialSync(initial_image_data, initial_tracking_data); @@ -952,17 +952,16 @@ FillImageSpecifics(BuildFaviconData(i), image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); expected_change_types.push_back(syncer::SyncChange::ACTION_UPDATE); FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms(-1); - stale_changes.push_back( - syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE, - syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time()))); + stale_changes.push_back(syncer::SyncChange( + FROM_HERE, syncer::SyncChange::ACTION_UPDATE, + syncer::SyncData::CreateRemoteData(1, tracking_specifics))); } SetUpInitialSync(initial_image_data, initial_tracking_data); @@ -991,16 +990,15 @@ FillImageSpecifics(BuildFaviconData(i), image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); - new_changes.push_back( - syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE, - syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time()))); + new_changes.push_back(syncer::SyncChange( + FROM_HERE, syncer::SyncChange::ACTION_UPDATE, + syncer::SyncData::CreateRemoteData(1, tracking_specifics))); tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms(i-1); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); } SetUpInitialSync(initial_image_data, initial_tracking_data); @@ -1023,15 +1021,14 @@ FillImageSpecifics(BuildFaviconData(i), image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); - same_changes.push_back( - syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE, - syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time()))); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); + same_changes.push_back(syncer::SyncChange( + FROM_HERE, syncer::SyncChange::ACTION_UPDATE, + syncer::SyncData::CreateRemoteData(1, tracking_specifics))); } SetUpInitialSync(initial_image_data, initial_tracking_data); @@ -1051,18 +1048,17 @@ FillImageSpecifics(BuildFaviconData(i), image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); - tracking_deletions.push_back( - syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_DELETE, - syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time()))); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); + tracking_deletions.push_back(syncer::SyncChange( + FROM_HERE, syncer::SyncChange::ACTION_DELETE, + syncer::SyncData::CreateRemoteData(1, tracking_specifics))); image_deletions.push_back(syncer::SyncChange( FROM_HERE, syncer::SyncChange::ACTION_DELETE, - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()))); + syncer::SyncData::CreateRemoteData(1, image_specifics))); } SetUpInitialSync(initial_image_data, initial_tracking_data); @@ -1093,11 +1089,11 @@ FillImageSpecifics(BuildFaviconData(i), image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); expected_icons.push_back(i); TestFaviconData favicon = BuildFaviconData(i+kMaxSyncFavicons); @@ -1155,24 +1151,23 @@ FillImageSpecifics(BuildFaviconData(i), image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); // Set up new tracking specifics for the icons received at change time. expected_icons.push_back(i + kMaxSyncFavicons); FillImageSpecifics(BuildFaviconData(i + kMaxSyncFavicons), image_specifics.mutable_favicon_image()); image_changes.push_back(syncer::SyncChange( FROM_HERE, syncer::SyncChange::ACTION_ADD, - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()))); + syncer::SyncData::CreateRemoteData(1, image_specifics))); FillTrackingSpecifics(BuildFaviconData(i + kMaxSyncFavicons), tracking_specifics.mutable_favicon_tracking()); - tracking_changes.push_back( - syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, - syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time()))); + tracking_changes.push_back(syncer::SyncChange( + FROM_HERE, syncer::SyncChange::ACTION_ADD, + syncer::SyncData::CreateRemoteData(1, tracking_specifics))); } SetUpInitialSync(initial_image_data, initial_tracking_data); @@ -1342,11 +1337,11 @@ FillImageSpecifics(test_data, image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); } SetUpInitialSync(initial_image_data, initial_tracking_data); @@ -1391,11 +1386,11 @@ FillImageSpecifics(test_data, image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); } SetUpInitialSync(initial_image_data, initial_tracking_data); @@ -1505,18 +1500,16 @@ sync_pb::EntitySpecifics image_specifics; FillImageSpecifics(BuildFaviconData(i), image_specifics.mutable_favicon_image()); - initial_image_changes.push_back( - syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, - syncer::SyncData::CreateRemoteData( - 1, image_specifics, base::Time()))); + initial_image_changes.push_back(syncer::SyncChange( + FROM_HERE, syncer::SyncChange::ACTION_ADD, + syncer::SyncData::CreateRemoteData(1, image_specifics))); } else { sync_pb::EntitySpecifics tracking_specifics; FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); - initial_tracking_changes.push_back( - syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, - syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time()))); + initial_tracking_changes.push_back(syncer::SyncChange( + FROM_HERE, syncer::SyncChange::ACTION_ADD, + syncer::SyncData::CreateRemoteData(1, tracking_specifics))); } } @@ -1579,7 +1572,7 @@ FillImageSpecifics(BuildFaviconData(i), image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); image_specifics.mutable_favicon_image()->clear_favicon_web(); } @@ -1602,13 +1595,13 @@ FillImageSpecifics(BuildFaviconData(i), image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms( syncer::TimeToProtoTime(base::Time())); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); } cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES, @@ -1665,11 +1658,11 @@ FillImageSpecifics(test_data, image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); FillTrackingSpecifics(test_data, tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); } SetUpInitialSync(initial_image_data, initial_tracking_data); @@ -1722,13 +1715,13 @@ FillImageSpecifics(BuildFaviconData(i + 5), image_specifics.mutable_favicon_image()); initial_image_data.push_back( - syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())); + syncer::SyncData::CreateRemoteData(1, image_specifics)); sync_pb::EntitySpecifics tracking_specifics; FillTrackingSpecifics(BuildFaviconData(i), tracking_specifics.mutable_favicon_tracking()); - initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData( - 1, tracking_specifics, base::Time())); + initial_tracking_data.push_back( + syncer::SyncData::CreateRemoteData(1, tracking_specifics)); } SetUpInitialSync(initial_image_data, initial_tracking_data);
diff --git a/components/sync_wifi/wifi_credential_syncable_service_unittest.cc b/components/sync_wifi/wifi_credential_syncable_service_unittest.cc index f3b71761..d982edfd 100644 --- a/components/sync_wifi/wifi_credential_syncable_service_unittest.cc +++ b/components/sync_wifi/wifi_credential_syncable_service_unittest.cc
@@ -132,8 +132,7 @@ FROM_HERE, syncer::SyncChange::ACTION_ADD, syncer::SyncData::CreateRemoteData( sync_item_id, - MakeWifiCredentialSpecifics(ssid, security_class, passphrase), - base::Time())); + MakeWifiCredentialSpecifics(ssid, security_class, passphrase))); } void StartSyncing() {
diff --git a/components/test/data/autofill_assistant/autofill_assistant_target_website.html b/components/test/data/autofill_assistant/autofill_assistant_target_website.html index 5b2dc8bd..668221de 100644 --- a/components/test/data/autofill_assistant/autofill_assistant_target_website.html +++ b/components/test/data/autofill_assistant/autofill_assistant_target_website.html
@@ -22,14 +22,22 @@ touch_area.parentNode.removeChild(touch_area); } - var moveTouchAreaTwo = function() { - var touch_area = document.getElementById("touch_area_two"); - setTimeout(function(){touch_area.style.left = "100px";}, 100); - setTimeout(function(){touch_area.style.left = "200px";}, 200); - setTimeout(function(){touch_area.style.left = "300px";}, 300); - setTimeout(function(){touch_area.style.left = "100px";}, 400); - setTimeout(function(){touch_area.style.left = "200px";}, 500); - setTimeout(function(){touch_area.style.left = "300px";}, 600); + var moveTouchAreaTwoAndThree = function() { + var touch_area_two = document.getElementById("touch_area_two"); + setTimeout(function(){touch_area_two.style.left = "100px";}, 100); + setTimeout(function(){touch_area_two.style.left = "200px";}, 200); + setTimeout(function(){touch_area_two.style.left = "300px";}, 300); + setTimeout(function(){touch_area_two.style.left = "100px";}, 400); + setTimeout(function(){touch_area_two.style.left = "200px";}, 500); + setTimeout(function(){touch_area_two.style.left = "300px";}, 600); + + var touch_area_three = document.getElementById("touch_area_three"); + setTimeout(function(){touch_area_three.style.top += "100px";}, 100); + setTimeout(function(){touch_area_three.style.top += "200px";}, 200); + setTimeout(function(){touch_area_three.style.top += "300px";}, 300); + setTimeout(function(){touch_area_three.style.top += "400px";}, 400); + setTimeout(function(){touch_area_three.style.top += "500px";}, 500); + setTimeout(function(){touch_area_three.style.top += "600px";}, 600); } </script> @@ -37,10 +45,14 @@ #full_height_section { height: 100vh; } + + #touch_area_three { + position: absolute; + } </style> </head> - <body onload="moveTouchAreaTwo()"> + <body onload="moveTouchAreaTwoAndThree()"> <!-- Touch area can be accessed without needing scroll.--> <div> <p id="touch_area_one" ontouchend="removeTouchArea('touch_area_one')"> @@ -64,6 +76,12 @@ </div> <div> + <p id="touch_area_three" ontouchend="removeTouchArea('touch_area_three')"> + Touchable Area Three</p> + <br> + </div> + + <div> <button id="button" type="button" onclick= "removeButton()">Test Button</button> <br>
diff --git a/components/test/data/autofill_assistant/autofill_assistant_target_website_iframe_one.html b/components/test/data/autofill_assistant/autofill_assistant_target_website_iframe_one.html index 977e08c..d9f33c5 100644 --- a/components/test/data/autofill_assistant/autofill_assistant_target_website_iframe_one.html +++ b/components/test/data/autofill_assistant/autofill_assistant_target_website_iframe_one.html
@@ -12,6 +12,11 @@ <title>Autofill Assistant Test</title> <script> + var load = function() { + createShadowDom(); + moveTouchArea(); + } + var createShadowDom = function() { var shadowSection = document.getElementById("shadowsection"); var shadowRoot = shadowSection.attachShadow({mode: 'open'}); @@ -29,16 +34,30 @@ var touch_area = document.getElementById("touch_area"); touch_area.parentNode.removeChild(touch_area); } + + var moveTouchArea = function() { + var touch_area = document.getElementById("touch_area"); + setTimeout(function(){touch_area.style.top += "100px";}, 100); + setTimeout(function(){touch_area.style.top += "200px";}, 200); + setTimeout(function(){touch_area.style.top += "300px";}, 300); + setTimeout(function(){touch_area.style.top += "400px";}, 400); + setTimeout(function(){touch_area.style.top += "500px";}, 500); + setTimeout(function(){touch_area.style.top += "600px";}, 600); + } </script> <style> #full_height_section { height: 100vh; } + + #touch_area { + position: absolute; + } </style> </head> - <body onload="createShadowDom()"> + <body onload="load()"> <div> <form name="address" id="address_section"> <div id='billing'>
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png index 6429a062..d429686 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png Binary files differ
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png index 044427b4..edb3dd2 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png Binary files differ
diff --git a/components/translate/core/browser/translate_manager.cc b/components/translate/core/browser/translate_manager.cc index ace3c04..b07c0ea1 100644 --- a/components/translate/core/browser/translate_manager.cc +++ b/components/translate/core/browser/translate_manager.cc
@@ -321,23 +321,33 @@ } bool TranslateManager::CanManuallyTranslate() { + if (!base::FeatureList::IsEnabled(translate::kTranslateUI) || + net::NetworkChangeNotifier::IsOffline() || + (!ignore_missing_key_for_testing_ && + !::google_apis::HasAPIKeyConfigured())) + return false; + + // MHTML pages currently cannot be translated (crbug.com/217945). + if (translate_driver_->GetContentsMimeType() == "multipart/related" || + !translate_client_->IsTranslatableURL( + translate_driver_->GetVisibleURL()) || + !language_state_.page_needs_translation()) + return false; + + const std::string source_language = language_state_.original_language(); + if (source_language.empty() || + source_language == translate::kUnknownLanguageCode) + return false; + std::unique_ptr<TranslatePrefs> translate_prefs( translate_client_->GetTranslatePrefs()); - const std::string source_code = TranslateDownloadManager::GetLanguageCode( - language_state_.original_language()); const std::string target_lang = GetManualTargetLanguage( - source_code, language_state_, translate_prefs.get(), language_model_); + TranslateDownloadManager::GetLanguageCode(source_language), + language_state_, translate_prefs.get(), language_model_); + if (target_lang.empty()) + return false; - return language_state_.page_needs_translation() && - base::FeatureList::IsEnabled(translate::kTranslateUI) && - !net::NetworkChangeNotifier::IsOffline() && - (ignore_missing_key_for_testing_ || - ::google_apis::HasAPIKeyConfigured()) && - // MHTML pages currently cannot be translated (crbug.com/217945). - translate_driver_->GetContentsMimeType() != "multipart/related" && - translate_client_->IsTranslatableURL( - translate_driver_->GetVisibleURL()) && - !target_lang.empty(); + return true; } void TranslateManager::InitiateManualTranslation() {
diff --git a/components/translate/core/browser/translate_manager_unittest.cc b/components/translate/core/browser/translate_manager_unittest.cc index def9e95..b5227a8 100644 --- a/components/translate/core/browser/translate_manager_unittest.cc +++ b/components/translate/core/browser/translate_manager_unittest.cc
@@ -26,6 +26,7 @@ #include "components/translate/core/browser/translate_download_manager.h" #include "components/translate/core/browser/translate_pref_names.h" #include "components/translate/core/browser/translate_prefs.h" +#include "components/translate/core/common/translate_constants.h" #include "components/variations/variations_associated_data.h" #include "net/base/network_change_notifier.h" #include "testing/gmock/include/gmock/gmock.h" @@ -920,6 +921,37 @@ EXPECT_TRUE(translate_manager_->CanManuallyTranslate()); } +TEST_F(TranslateManagerTest, CanManuallyTranslate_EmptySourceLanguage) { + TranslateManager::SetIgnoreMissingKeyForTesting(true); + translate_manager_.reset(new translate::TranslateManager( + &mock_translate_client_, &mock_translate_ranker_, &mock_language_model_)); + + prefs_.SetBoolean(prefs::kOfferTranslateEnabled, true); + network_notifier_.SimulateOnline(); + ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) + .WillByDefault(Return(true)); + + translate_manager_->GetLanguageState().LanguageDetermined("", true); + + EXPECT_FALSE(translate_manager_->CanManuallyTranslate()); +} + +TEST_F(TranslateManagerTest, CanManuallyTranslate_UndefinedSourceLanguage) { + TranslateManager::SetIgnoreMissingKeyForTesting(true); + translate_manager_.reset(new translate::TranslateManager( + &mock_translate_client_, &mock_translate_ranker_, &mock_language_model_)); + + prefs_.SetBoolean(prefs::kOfferTranslateEnabled, true); + network_notifier_.SimulateOnline(); + ON_CALL(mock_translate_client_, IsTranslatableURL(GURL::EmptyGURL())) + .WillByDefault(Return(true)); + + translate_manager_->GetLanguageState().LanguageDetermined( + translate::kUnknownLanguageCode, true); + + EXPECT_FALSE(translate_manager_->CanManuallyTranslate()); +} + } // namespace testing } // namespace translate
diff --git a/components/unified_consent/pref_names.cc b/components/unified_consent/pref_names.cc index c2a7a30..d9e25e9 100644 --- a/components/unified_consent/pref_names.cc +++ b/components/unified_consent/pref_names.cc
@@ -13,11 +13,6 @@ const char kAllUnifiedConsentServicesWereEnabled[] = "unified_consent.all_services_were_enabled"; -// Boolean indicating whether the user had everything synced before migrating to -// unified consent. -const char kHadEverythingSyncedBeforeMigration[] = - "unified_consent.had_everything_synced_before_migration"; - // Boolean indicating whether all criteria is met for the consent bump to be // shown. const char kShouldShowUnifiedConsentBump[] =
diff --git a/components/unified_consent/pref_names.h b/components/unified_consent/pref_names.h index 7d16f569..7d58a89 100644 --- a/components/unified_consent/pref_names.h +++ b/components/unified_consent/pref_names.h
@@ -9,7 +9,6 @@ namespace prefs { extern const char kAllUnifiedConsentServicesWereEnabled[]; -extern const char kHadEverythingSyncedBeforeMigration[]; extern const char kShouldShowUnifiedConsentBump[]; extern const char kUnifiedConsentGiven[]; extern const char kUnifiedConsentMigrationState[];
diff --git a/components/unified_consent/unified_consent_service.cc b/components/unified_consent/unified_consent_service.cc index 6e961b8..80a0278 100644 --- a/components/unified_consent/unified_consent_service.cc +++ b/components/unified_consent/unified_consent_service.cc
@@ -22,64 +22,6 @@ namespace unified_consent { -namespace { - -// Used for observing the sync service and finishing the rollback once the sync -// engine is initialized. -// Note: This object is suicidal - it will kill itself after it finishes the -// rollback. -class RollbackHelper : public syncer::SyncServiceObserver { - public: - explicit RollbackHelper(syncer::SyncService* sync_service); - ~RollbackHelper() override = default; - - private: - // syncer::SyncServiceObserver: - void OnStateChanged(syncer::SyncService* sync_service) override; - - void DoRollbackIfPossibleAndDie(syncer::SyncService* sync_service); - - ScopedObserver<syncer::SyncService, RollbackHelper> scoped_sync_observer_; -}; - -RollbackHelper::RollbackHelper(syncer::SyncService* sync_service) - : scoped_sync_observer_(this) { - if (sync_service->IsEngineInitialized()) - DoRollbackIfPossibleAndDie(sync_service); - else - scoped_sync_observer_.Add(sync_service); -} - -void RollbackHelper::OnStateChanged(syncer::SyncService* sync_service) { - if (!sync_service->IsEngineInitialized()) - return; - - scoped_sync_observer_.RemoveAll(); - - base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&RollbackHelper::DoRollbackIfPossibleAndDie, - base::Unretained(this), sync_service)); -} - -void RollbackHelper::DoRollbackIfPossibleAndDie( - syncer::SyncService* sync_service) { - DCHECK(!scoped_sync_observer_.IsObservingSources()); - - if (sync_service->GetUserSettings()->GetChosenDataTypes().HasAll( - syncer::UserSelectableTypes())) { - // As part of the migration of a profile to Unified Consent, sync everything - // is disabled. Therefore it is desired to restore sync everything when - // rolling back unified consent to leave sync in the same state as the one - // before migration. - sync_service->GetUserSettings()->SetChosenDataTypes( - /*sync_everything=*/true, syncer::UserSelectableTypes()); - } - - base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); -} - -} // namespace - UnifiedConsentService::UnifiedConsentService( std::unique_ptr<UnifiedConsentServiceClient> service_client, PrefService* pref_service, @@ -88,8 +30,7 @@ : service_client_(std::move(service_client)), pref_service_(pref_service), identity_manager_(identity_manager), - sync_service_(sync_service), - weak_ptr_factory_(this) { + sync_service_(sync_service) { DCHECK(service_client_); DCHECK(pref_service_); DCHECK(identity_manager_); @@ -142,8 +83,6 @@ prefs::kUnifiedConsentMigrationState, static_cast<int>(MigrationState::kNotInitialized)); registry->RegisterBooleanPref(prefs::kShouldShowUnifiedConsentBump, false); - registry->RegisterBooleanPref(prefs::kHadEverythingSyncedBeforeMigration, - false); registry->RegisterBooleanPref(prefs::kAllUnifiedConsentServicesWereEnabled, false); } @@ -161,18 +100,6 @@ // If there was no migration yet, nothing has to be rolled back. return; } - bool had_everything_synced = - user_pref_service->GetBoolean( - prefs::kHadEverythingSyncedBeforeMigration) || - user_pref_service->GetBoolean(prefs::kShouldShowUnifiedConsentBump); - - if (had_everything_synced && sync_service && - sync_service->GetDisableReasons() == - syncer::SyncService::DISABLE_REASON_NONE) { - // This will wait until the sync engine is initialized and then enables the - // sync-everything pref in case the user is syncing all data types. - new RollbackHelper(sync_service); - } // Turn off all off-by-default services if services were enabled due to // unified consent. @@ -190,7 +117,6 @@ user_pref_service->ClearPref(prefs::kUnifiedConsentGiven); user_pref_service->ClearPref(prefs::kUnifiedConsentMigrationState); user_pref_service->ClearPref(prefs::kShouldShowUnifiedConsentBump); - user_pref_service->ClearPref(prefs::kHadEverythingSyncedBeforeMigration); user_pref_service->ClearPref(prefs::kAllUnifiedConsentServicesWereEnabled); } @@ -243,7 +169,6 @@ } void UnifiedConsentService::Shutdown() { - weak_ptr_factory_.InvalidateWeakPtrs(); service_client_->RemoveObserver(this); identity_manager_->RemoveObserver(this); sync_service_->RemoveObserver(this); @@ -314,62 +239,13 @@ metrics::UnifiedConsentRevokeReason::kCustomPassphrase); } } - - if (IsUnifiedConsentGiven() != - sync_service_->GetUserSettings()->IsSyncEverythingEnabled()) { - // Make sync-everything consistent with the |kUnifiedConsentGiven| pref. - PostTaskToUpdateSyncSettings(/*sync_everything=*/IsUnifiedConsentGiven()); - } -} - -void UnifiedConsentService::UpdateSyncSettingsIfPossible( - bool sync_everything, - syncer::ModelTypeSet enable_data_types, - syncer::ModelTypeSet disable_data_types) { - DCHECK(Intersection(enable_data_types, disable_data_types).Empty()); - - if (sync_service_->GetDisableReasons() != - syncer::SyncService::DISABLE_REASON_NONE || - !sync_service_->IsEngineInitialized()) { - return; - } - - if (sync_everything) { - sync_service_->GetUserSettings()->SetChosenDataTypes( - /*sync_everything=*/true, syncer::UserSelectableTypes()); - return; - } - - syncer::ModelTypeSet data_types = - sync_service_->GetUserSettings()->GetChosenDataTypes(); - data_types.PutAll(enable_data_types); - data_types.RemoveAll(disable_data_types); - data_types.RetainAll(syncer::UserSelectableTypes()); - sync_service_->GetUserSettings()->SetChosenDataTypes( - /*sync_everything=*/false, data_types); -} - -void UnifiedConsentService::PostTaskToUpdateSyncSettings( - bool sync_everything, - syncer::ModelTypeSet enable_data_types, - syncer::ModelTypeSet disable_data_types) { - base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(&UnifiedConsentService::UpdateSyncSettingsIfPossible, - weak_ptr_factory_.GetWeakPtr(), sync_everything, - enable_data_types, disable_data_types)); } void UnifiedConsentService::OnUnifiedConsentGivenPrefChanged() { bool enabled = pref_service_->GetBoolean(prefs::kUnifiedConsentGiven); - if (!enabled) { - if (identity_manager_->HasPrimaryAccount() && - sync_service_->GetUserSettings()->IsSyncEverythingEnabled()) { - UpdateSyncSettingsIfPossible(/*sync_everything=*/false); - } + if (!enabled) return; - } DCHECK(!sync_service_->HasDisableReason( syncer::SyncService::DISABLE_REASON_PLATFORM_OVERRIDE)); @@ -387,11 +263,6 @@ RecordConsentBumpSuppressReason( metrics::ConsentBumpSuppressReason::kSettingsOptIn); - // Enable all sync data types if possible, otherwise they will be enabled with - // |OnStateChanged| once sync is active; - autofill::prefs::SetPaymentsIntegrationEnabled(pref_service_, true); - UpdateSyncSettingsIfPossible(/*sync_everything=*/true); - // Enable all non-personalized services. pref_service_->SetBoolean(prefs::kUrlKeyedAnonymizedDataCollectionEnabled, true); @@ -435,8 +306,6 @@ } bool is_syncing_everything = sync_service_->GetUserSettings()->IsSyncEverythingEnabled(); - pref_service_->SetBoolean(prefs::kHadEverythingSyncedBeforeMigration, - is_syncing_everything); if (!is_syncing_everything) { RecordConsentBumpSuppressReason( @@ -476,11 +345,6 @@ pref_service_->SetBoolean(prefs::kUrlKeyedAnonymizedDataCollectionEnabled, url_keyed_metrics_enabled); - // Set sync-everything to false, so it matches unified consent given. - PostTaskToUpdateSyncSettings( - /*sync_everything=*/false, /*enable_data_types=*/syncer::ModelTypeSet(), - /*disable_data_types=*/syncer::ModelTypeSet()); - SetMigrationState(MigrationState::kCompleted); }
diff --git a/components/unified_consent/unified_consent_service.h b/components/unified_consent/unified_consent_service.h index b64f5973..aefb09d 100644 --- a/components/unified_consent/unified_consent_service.h +++ b/components/unified_consent/unified_consent_service.h
@@ -94,25 +94,6 @@ // syncer::SyncServiceObserver: void OnStateChanged(syncer::SyncService* sync) override; - // Updates the sync settings if sync isn't disabled and the sync engine is - // initialized. - // When |sync_everything| is false: - // - All sync data types in |enable_data_types| will be enabled. - // - All sync data types in |disable_data_types| will be disabled. - // - All data types in neither of the two sets will remain in the same state. - // When |sync_everything| is true, |enable_data_types| and - // |disable_data_types| will be ignored. - void UpdateSyncSettingsIfPossible( - bool sync_everything, - syncer::ModelTypeSet enable_data_types = syncer::ModelTypeSet(), - syncer::ModelTypeSet disable_data_types = syncer::ModelTypeSet()); - - // Posts a task to call |UpdateSyncSettingsIfPossible|. - void PostTaskToUpdateSyncSettings( - bool sync_everything, - syncer::ModelTypeSet enable_data_types = syncer::ModelTypeSet(), - syncer::ModelTypeSet disable_data_types = syncer::ModelTypeSet()); - // Called when |prefs::kUnifiedConsentGiven| pref value changes. // When set to true, it enables syncing of all data types and it enables all // non-personalized services. Otherwise it does nothing. @@ -153,8 +134,6 @@ std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; - base::WeakPtrFactory<UnifiedConsentService> weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(UnifiedConsentService); };
diff --git a/components/unified_consent/unified_consent_service_unittest.cc b/components/unified_consent/unified_consent_service_unittest.cc index a0ebca0..4b398f0 100644 --- a/components/unified_consent/unified_consent_service_unittest.cc +++ b/components/unified_consent/unified_consent_service_unittest.cc
@@ -35,8 +35,6 @@ } void OnUserChoseDatatypes(bool sync_everything, syncer::ModelTypeSet chosen_types) override { - // Add this for the Migration_UpdateSettings test. - chosen_types.Put(syncer::HISTORY_DELETE_DIRECTIVES); SetPreferredDataTypes(chosen_types); } @@ -249,39 +247,6 @@ EXPECT_TRUE(AreAllNonPersonalizedServicesEnabled()); } -TEST_F(UnifiedConsentServiceTest, EnableUnfiedConsent_SyncNotActive) { - CreateConsentService(); - identity_test_environment_.SetPrimaryAccount("testaccount"); - EXPECT_FALSE(pref_service_.GetBoolean(prefs::kUnifiedConsentGiven)); - sync_service_.GetUserSettings()->SetChosenDataTypes( - false, syncer::UserSelectableTypes()); - syncer::SyncPrefs sync_prefs(&pref_service_); - EXPECT_FALSE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); - EXPECT_FALSE(consent_service_->IsUnifiedConsentGiven()); - - // Make sure sync is not active. - sync_service_.SetTransportState( - syncer::SyncService::TransportState::INITIALIZING); - EXPECT_FALSE(sync_service_.IsEngineInitialized()); - EXPECT_NE(sync_service_.GetTransportState(), - syncer::SyncService::TransportState::ACTIVE); - - // Opt into unified consent. - consent_service_->SetUnifiedConsentGiven(true); - EXPECT_TRUE(consent_service_->IsUnifiedConsentGiven()); - - // Couldn't sync everything because sync is not active. - EXPECT_FALSE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); - - // Initalize sync engine and therefore activate sync. - sync_service_.SetTransportState(syncer::SyncService::TransportState::ACTIVE); - sync_service_.FireStateChanged(); - base::RunLoop().RunUntilIdle(); - - // UnifiedConsentService starts syncing everything. - EXPECT_TRUE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); -} - TEST_F(UnifiedConsentServiceTest, EnableUnfiedConsent_WithCustomPassphrase) { base::HistogramTester histogram_tester; @@ -370,7 +335,6 @@ identity_test_environment_.SetPrimaryAccount("testaccount"); sync_service_.GetUserSettings()->SetChosenDataTypes( true, syncer::UserSelectableTypes()); - syncer::SyncPrefs sync_prefs(&pref_service_); EXPECT_TRUE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); EXPECT_FALSE(pref_service_.GetBoolean(prefs::kUnifiedConsentGiven)); sync_service_.SetTransportState( @@ -385,16 +349,12 @@ EXPECT_EQ(GetMigrationState(), unified_consent::MigrationState::kInProgressWaitForSyncInit); EXPECT_TRUE(consent_service_->ShouldShowConsentBump()); - // Sync-everything is still on because sync is not active yet. - EXPECT_TRUE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); // When sync is active, the migration should continue and finish. sync_service_.SetTransportState(syncer::SyncService::TransportState::ACTIVE); sync_service_.FireStateChanged(); base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); - // No metric for the consent bump suppress reason should have been recorded at // this point. histogram_tester.ExpectTotalCount("UnifiedConsent.ConsentBump.SuppressReason", @@ -419,7 +379,6 @@ identity_test_environment_.SetPrimaryAccount("testaccount"); sync_service_.GetUserSettings()->SetChosenDataTypes( true, syncer::UserSelectableTypes()); - syncer::SyncPrefs sync_prefs(&pref_service_); EXPECT_TRUE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); EXPECT_FALSE(pref_service_.GetBoolean(prefs::kUnifiedConsentGiven)); EXPECT_TRUE(sync_service_.IsSyncFeatureActive()); @@ -429,7 +388,6 @@ // After the creation of the consent service, the profile is migrated and // |ShouldShowConsentBump| should return false. EXPECT_FALSE(pref_service_.GetBoolean(prefs::kUnifiedConsentGiven)); - EXPECT_FALSE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); EXPECT_EQ(GetMigrationState(), unified_consent::MigrationState::kCompleted); EXPECT_FALSE(consent_service_->ShouldShowConsentBump()); @@ -462,12 +420,10 @@ } TEST_F(UnifiedConsentServiceTest, Migration_UpdateSettings) { - // Create user that syncs everything + // Create user that syncs history and has no custom passphrase. identity_test_environment_.SetPrimaryAccount("testaccount"); sync_service_.GetUserSettings()->SetChosenDataTypes( - true, syncer::UserSelectableTypes()); - syncer::SyncPrefs sync_prefs(&pref_service_); - EXPECT_TRUE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); + false, syncer::ModelTypeSet(syncer::TYPED_URLS)); EXPECT_TRUE(sync_service_.IsSyncFeatureActive()); // Url keyed data collection is off before the migration. EXPECT_FALSE(pref_service_.GetBoolean( @@ -476,7 +432,6 @@ CreateConsentService(); EXPECT_EQ(GetMigrationState(), unified_consent::MigrationState::kCompleted); // During the migration Url keyed data collection is enabled. - EXPECT_FALSE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); EXPECT_TRUE(pref_service_.GetBoolean( prefs::kUrlKeyedAnonymizedDataCollectionEnabled)); } @@ -540,98 +495,16 @@ } #endif // !defined(OS_CHROMEOS) -TEST_F(UnifiedConsentServiceTest, Rollback_WasSyncingEverything) { - identity_test_environment_.SetPrimaryAccount("testaccount"); - syncer::SyncPrefs sync_prefs(&pref_service_); - sync_service_.GetUserSettings()->SetChosenDataTypes( - true, syncer::UserSelectableTypes()); - EXPECT_TRUE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); - - // Migrate - CreateConsentService(); - // Check expectations after migration. - EXPECT_FALSE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); - EXPECT_FALSE(pref_service_.GetBoolean(prefs::kUnifiedConsentGiven)); - EXPECT_EQ(unified_consent::MigrationState::kCompleted, GetMigrationState()); - EXPECT_TRUE( - pref_service_.GetBoolean(prefs::kHadEverythingSyncedBeforeMigration)); - - consent_service_->Shutdown(); - consent_service_.reset(); - SetUnifiedConsentFeatureState(UnifiedConsentFeatureState::kDisabled); - - // Rollback - UnifiedConsentService::RollbackIfNeeded(&pref_service_, &sync_service_, - service_client_.get()); - base::RunLoop().RunUntilIdle(); - - // Unified consent prefs should be cleared. - EXPECT_FALSE(pref_service_.GetBoolean(prefs::kUnifiedConsentGiven)); - EXPECT_EQ(unified_consent::MigrationState::kNotInitialized, - GetMigrationState()); - EXPECT_FALSE( - pref_service_.GetBoolean(prefs::kHadEverythingSyncedBeforeMigration)); - // Sync everything should be back on. - EXPECT_TRUE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); - - // Run until idle so the RollbackHelper is deleted. - base::RunLoop().RunUntilIdle(); -} - -TEST_F(UnifiedConsentServiceTest, Rollback_WasNotSyncingEverything) { - identity_test_environment_.SetPrimaryAccount("testaccount"); - syncer::SyncPrefs sync_prefs(&pref_service_); - syncer::ModelTypeSet chosen_data_types = syncer::UserSelectableTypes(); - chosen_data_types.Remove(syncer::BOOKMARKS); - sync_service_.GetUserSettings()->SetChosenDataTypes(false, chosen_data_types); - EXPECT_FALSE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); - EXPECT_FALSE(sync_service_.GetPreferredDataTypes().HasAll( - syncer::UserSelectableTypes())); - - // Migrate - CreateConsentService(); - // Check expectations after migration. - EXPECT_FALSE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); - EXPECT_FALSE(pref_service_.GetBoolean(prefs::kUnifiedConsentGiven)); - EXPECT_EQ(unified_consent::MigrationState::kCompleted, GetMigrationState()); - EXPECT_FALSE( - pref_service_.GetBoolean(prefs::kHadEverythingSyncedBeforeMigration)); - - consent_service_->Shutdown(); - consent_service_.reset(); - - // Rollback - UnifiedConsentService::RollbackIfNeeded(&pref_service_, &sync_service_, - service_client_.get()); - // Unified consent prefs should be cleared. - EXPECT_FALSE(pref_service_.GetBoolean(prefs::kUnifiedConsentGiven)); - EXPECT_EQ(unified_consent::MigrationState::kNotInitialized, - GetMigrationState()); - - // Sync everything should be off because not all user types were on. - EXPECT_FALSE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); - - // Run until idle so the RollbackHelper is deleted. - base::RunLoop().RunUntilIdle(); -} - TEST_F(UnifiedConsentServiceTest, Rollback_UserOptedIntoUnifiedConsent) { identity_test_environment_.SetPrimaryAccount("testaccount"); - syncer::SyncPrefs sync_prefs(&pref_service_); - sync_service_.GetUserSettings()->SetChosenDataTypes( - true, syncer::UserSelectableTypes()); - EXPECT_TRUE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); // Migrate and opt into unified consent. CreateConsentService(); consent_service_->SetUnifiedConsentGiven(true); // Check expectations after opt-in. - EXPECT_TRUE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); EXPECT_TRUE(pref_service_.GetBoolean(prefs::kUnifiedConsentGiven)); EXPECT_EQ(unified_consent::MigrationState::kCompleted, GetMigrationState()); EXPECT_TRUE( - pref_service_.GetBoolean(prefs::kHadEverythingSyncedBeforeMigration)); - EXPECT_TRUE( pref_service_.GetBoolean(prefs::kAllUnifiedConsentServicesWereEnabled)); consent_service_->Shutdown(); @@ -647,10 +520,6 @@ EXPECT_FALSE(pref_service_.GetBoolean(prefs::kUnifiedConsentGiven)); EXPECT_EQ(unified_consent::MigrationState::kNotInitialized, GetMigrationState()); - EXPECT_FALSE( - pref_service_.GetBoolean(prefs::kHadEverythingSyncedBeforeMigration)); - // Sync everything should still be on. - EXPECT_TRUE(sync_service_.GetUserSettings()->IsSyncEverythingEnabled()); // Off-by-default services should be turned off. EXPECT_NE(ServiceState::kEnabled, service_client_->GetServiceState(
diff --git a/components/url_formatter/url_formatter.cc b/components/url_formatter/url_formatter.cc index 4ef6820d..b060780 100644 --- a/components/url_formatter/url_formatter.cc +++ b/components/url_formatter/url_formatter.cc
@@ -414,7 +414,6 @@ const FormatUrlType kFormatUrlOmitHTTP = 1 << 1; const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname = 1 << 2; const FormatUrlType kFormatUrlOmitHTTPS = 1 << 3; -const FormatUrlType kFormatUrlExperimentalElideAfterHost = 1 << 4; const FormatUrlType kFormatUrlOmitTrivialSubdomains = 1 << 5; const FormatUrlType kFormatUrlTrimAfterHost = 1 << 6; const FormatUrlType kFormatUrlOmitFileScheme = 1 << 7; @@ -554,19 +553,9 @@ } // Path & query. Both get the same general unescape & convert treatment. - if ((format_types & kFormatUrlTrimAfterHost) || - ((format_types & kFormatUrlExperimentalElideAfterHost) && - url.IsStandard() && !url.SchemeIsFile() && !url.SchemeIsFileSystem())) { - // Only elide when the eliding is required and when the host is followed by - // more than just one forward slash. - bool should_elide = (format_types & kFormatUrlExperimentalElideAfterHost) && - ((parsed.path.len > 1) || parsed.query.is_valid() || - parsed.ref.is_valid()); - - // Either remove the path completely, or, if eliding, keep the first slash. - const size_t new_path_len = should_elide ? 1 : 0; - - size_t trimmed_length = parsed.path.len - new_path_len; + if ((format_types & kFormatUrlTrimAfterHost) && url.IsStandard() && + !url.SchemeIsFile() && !url.SchemeIsFileSystem()) { + size_t trimmed_length = parsed.path.len; // Remove query and the '?' delimeter. if (parsed.query.is_valid()) trimmed_length += parsed.query.len + 1; @@ -575,15 +564,8 @@ if (parsed.ref.is_valid()) trimmed_length += parsed.ref.len + 1; - if (should_elide) { - // Replace everything after the host with a forward slash and ellipsis. - url_string.push_back('/'); - constexpr base::char16 kEllipsisUTF16[] = {0x2026, 0}; - url_string.append(kEllipsisUTF16); - } - - adjustments->push_back(base::OffsetAdjuster::Adjustment( - parsed.path.begin + new_path_len, trimmed_length, new_path_len)); + adjustments->push_back( + base::OffsetAdjuster::Adjustment(parsed.path.begin, trimmed_length, 0)); } else if ((format_types & kFormatUrlOmitTrailingSlashOnBareHostname) && CanStripTrailingSlash(url)) {
diff --git a/components/url_formatter/url_formatter.h b/components/url_formatter/url_formatter.h index 95fb222..98bc5ba9 100644 --- a/components/url_formatter/url_formatter.h +++ b/components/url_formatter/url_formatter.h
@@ -73,10 +73,6 @@ // If the scheme is 'https://', it's removed. Not in kFormatUrlOmitDefaults. extern const FormatUrlType kFormatUrlOmitHTTPS; -// Replaces the path, query, and ref with an ellipsis. Experimental and not in -// kFormatUrlOmitDefaults. -extern const FormatUrlType kFormatUrlExperimentalElideAfterHost; - // Omits some trivially informative subdomains such as "www" or "m". Not in // kFormatUrlOmitDefaults. extern const FormatUrlType kFormatUrlOmitTrivialSubdomains;
diff --git a/components/url_formatter/url_formatter_unittest.cc b/components/url_formatter/url_formatter_unittest.cc index a437f27..eac7a01 100644 --- a/components/url_formatter/url_formatter_unittest.cc +++ b/components/url_formatter/url_formatter_unittest.cc
@@ -1253,41 +1253,6 @@ "view-source:http://a.b/", kFormatUrlOmitDefaults, net::UnescapeRule::NORMAL, L"view-source:a.b", 12}, - // -------- elide after host -------- - {"elide after host but still strip trailing slashes", - "http://google.com/", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, L"google.com", 0}, - {"elide after host in simple filename-only case", "http://google.com/foo", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, - {"elide after host in directory and file case", "http://google.com/ab/cd", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, - {"elide after host with query only", "http://google.com/?foo=bar", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, - {"elide after host with ref only", "http://google.com/#foobar", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, - {"elide after host with path and query only", "http://google.com/foo?a=b", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, - {"elide after host with path and ref only", "http://google.com/foo#c", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, - {"elide after host with query and ref only", "http://google.com/?a=b#c", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, - {"elide after host with path, query and ref", - "http://google.com/foo?a=b#c", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, - {"elide after host with repeated delimiters (sanity check)", - "http://google.com////???####", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, L"google.com/\x2026\x0000", 0}, - // -------- omit https -------- {"omit https", "https://www.google.com/", kFormatUrlOmitHTTPS, net::UnescapeRule::NORMAL, L"www.google.com/", 0}, @@ -1402,6 +1367,10 @@ "http://google.com////???####", kFormatUrlOmitDefaults | kFormatUrlTrimAfterHost, net::UnescapeRule::NORMAL, L"google.com", 0}, + {"never trim file paths", "file:///Users/homedirname/folder/file.pdf/", + kFormatUrlOmitDefaults | kFormatUrlTrimAfterHost, + net::UnescapeRule::NORMAL, + L"file:///Users/homedirname/folder/file.pdf/", 7}, }; // clang-format on @@ -1751,34 +1720,6 @@ CheckAdjustedOffsets("http://user@foo.com/", kFormatUrlOmitDefaults, net::UnescapeRule::NORMAL, omit_all_offsets); - const size_t elide_after_host_offsets[] = { - 0, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 0, 1, 2, 3, 4, - 5, 6, 7, 8, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 9}; - CheckAdjustedOffsets( - "http://foo.com/abcdefg", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, elide_after_host_offsets); - CheckAdjustedOffsets( - "http://foo.com/abc/def", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, elide_after_host_offsets); - CheckAdjustedOffsets( - "http://foo.com/abc?a=b", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, elide_after_host_offsets); - CheckAdjustedOffsets( - "http://foo.com/abc#def", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, elide_after_host_offsets); - CheckAdjustedOffsets( - "http://foo.com/a?a=b#f", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, elide_after_host_offsets); - CheckAdjustedOffsets( - "http://foo.com//??###", - kFormatUrlOmitDefaults | kFormatUrlExperimentalElideAfterHost, - net::UnescapeRule::NORMAL, elide_after_host_offsets); - const size_t trim_after_host_offsets[] = { 0, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 0, 1, 2, 3, 4, 5, 6, 7, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 9};
diff --git a/components/viz/common/quads/DEPS b/components/viz/common/quads/DEPS index 8353b9e..5e8f6e13 100644 --- a/components/viz/common/quads/DEPS +++ b/components/viz/common/quads/DEPS
@@ -8,6 +8,7 @@ "+gpu/command_buffer/common", "+third_party/skia", + "+ui/gl/dc_renderer_layer_params.h", "+ui/latency", ]
diff --git a/components/viz/common/quads/draw_quad_unittest.cc b/components/viz/common/quads/draw_quad_unittest.cc index cae3f216..2560020 100644 --- a/components/viz/common/quads/draw_quad_unittest.cc +++ b/components/viz/common/quads/draw_quad_unittest.cc
@@ -400,7 +400,8 @@ float resource_multiplier = 2.001f; uint32_t bits_per_channel = 5; bool require_overlay = true; - bool is_protected_video = true; + ui::ProtectedVideoType protected_video_type = + ui::ProtectedVideoType::kHardwareProtected; gfx::ColorSpace video_color_space = gfx::ColorSpace::CreateJpeg(); CREATE_SHARED_STATE(); @@ -424,13 +425,13 @@ EXPECT_EQ(resource_multiplier, copy_quad->resource_multiplier); EXPECT_EQ(bits_per_channel, copy_quad->bits_per_channel); EXPECT_FALSE(copy_quad->require_overlay); - EXPECT_FALSE(copy_quad->is_protected_video); + EXPECT_EQ(ui::ProtectedVideoType::kClear, copy_quad->protected_video_type); CREATE_QUAD_ALL(YUVVideoDrawQuad, ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size, uv_tex_size, y_plane_resource_id, u_plane_resource_id, v_plane_resource_id, a_plane_resource_id, video_color_space, resource_offset, resource_multiplier, - bits_per_channel, require_overlay, is_protected_video); + bits_per_channel, require_overlay, protected_video_type); EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material); EXPECT_EQ(ya_tex_coord_rect, copy_quad->ya_tex_coord_rect); EXPECT_EQ(uv_tex_coord_rect, copy_quad->uv_tex_coord_rect); @@ -444,7 +445,7 @@ EXPECT_EQ(resource_multiplier, copy_quad->resource_multiplier); EXPECT_EQ(bits_per_channel, copy_quad->bits_per_channel); EXPECT_EQ(require_overlay, copy_quad->require_overlay); - EXPECT_EQ(is_protected_video, copy_quad->is_protected_video); + EXPECT_EQ(protected_video_type, copy_quad->protected_video_type); } TEST(DrawQuadTest, CopyPictureDrawQuad) {
diff --git a/components/viz/common/quads/yuv_video_draw_quad.cc b/components/viz/common/quads/yuv_video_draw_quad.cc index bf46a5d..9654db2 100644 --- a/components/viz/common/quads/yuv_video_draw_quad.cc +++ b/components/viz/common/quads/yuv_video_draw_quad.cc
@@ -67,7 +67,7 @@ float multiplier, uint32_t bits_per_channel, bool require_overlay, - bool is_protected_video) { + ui::ProtectedVideoType protected_video_type) { DrawQuad::SetAll(shared_quad_state, DrawQuad::YUV_VIDEO_CONTENT, rect, visible_rect, needs_blending); this->ya_tex_coord_rect = ya_tex_coord_rect; @@ -84,7 +84,7 @@ this->resource_multiplier = multiplier; this->bits_per_channel = bits_per_channel; this->require_overlay = require_overlay; - this->is_protected_video = is_protected_video; + this->protected_video_type = protected_video_type; } const YUVVideoDrawQuad* YUVVideoDrawQuad::MaterialCast(const DrawQuad* quad) { @@ -107,7 +107,8 @@ value->SetInteger("a_plane_resource_id", resources.ids[kAPlaneResourceIdIndex]); value->SetBoolean("require_overlay", require_overlay); - value->SetBoolean("is_protected_video", is_protected_video); + value->SetInteger("protected_video_type", + static_cast<int>(protected_video_type)); } } // namespace viz
diff --git a/components/viz/common/quads/yuv_video_draw_quad.h b/components/viz/common/quads/yuv_video_draw_quad.h index 82ff32c..08c0645 100644 --- a/components/viz/common/quads/yuv_video_draw_quad.h +++ b/components/viz/common/quads/yuv_video_draw_quad.h
@@ -14,6 +14,7 @@ #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/size.h" +#include "ui/gl/dc_renderer_layer_params.h" namespace viz { @@ -71,7 +72,7 @@ float multiplier, uint32_t bits_per_channel, bool require_overlay, - bool is_protected_video); + ui::ProtectedVideoType protected_video_type); gfx::RectF ya_tex_coord_rect; gfx::RectF uv_tex_coord_rect; @@ -83,7 +84,7 @@ // TODO(hubbe): Move to ResourceProvider::ScopedSamplerGL. gfx::ColorSpace video_color_space; bool require_overlay = false; - bool is_protected_video = false; + ui::ProtectedVideoType protected_video_type = ui::ProtectedVideoType::kClear; static const YUVVideoDrawQuad* MaterialCast(const DrawQuad*);
diff --git a/components/viz/service/display/dc_layer_overlay.cc b/components/viz/service/display/dc_layer_overlay.cc index 0a698c1..8ae586f 100644 --- a/components/viz/service/display/dc_layer_overlay.cc +++ b/components/viz/service/display/dc_layer_overlay.cc
@@ -31,13 +31,10 @@ dc_layer_overlay->filter = GL_LINEAR; dc_layer_overlay->color_space = quad->video_color_space; dc_layer_overlay->require_overlay = quad->require_overlay; - if (quad->is_protected_video) { - dc_layer_overlay->protected_video_type = - ui::ProtectedVideoType::kHardwareProtected; - } - // Protected Videos have to go through the overlay swapchain path, + dc_layer_overlay->protected_video_type = quad->protected_video_type; + // HW Protected Videos have to go through the overlay swapchain path, // so they can be protected by Windows OS and hardware - if (dc_layer_overlay->IsProtectedVideo()) + if (quad->protected_video_type == ui::ProtectedVideoType::kHardwareProtected) dc_layer_overlay->require_overlay = true; return DCLayerOverlayProcessor::DC_LAYER_SUCCESS;
diff --git a/components/viz/service/display/display_scheduler.cc b/components/viz/service/display/display_scheduler.cc index 5c32768..7c5c22d 100644 --- a/components/viz/service/display/display_scheduler.cc +++ b/components/viz/service/display/display_scheduler.cc
@@ -485,7 +485,6 @@ if (pending_swaps_ < max_pending_swaps_) return DrawAndSwap(); } else { - ReportNotDrawReason(); // We are going idle, so reset expectations. // TODO(eseckler): Should we avoid going idle if // |expecting_root_surface_damage_because_of_resize_| is true? @@ -529,15 +528,4 @@ ScheduleBeginFrameDeadline(); } -void DisplayScheduler::ReportNotDrawReason() { - DCHECK(!ShouldDraw()); - UMA_HISTOGRAM_BOOLEAN("DisplayScheduler.ShouldNotDraw.DrawNotNeeded", - !needs_draw_); - UMA_HISTOGRAM_BOOLEAN("DisplayScheduler.ShouldNotDraw.OutputSurfaceLost", - output_surface_lost_); - UMA_HISTOGRAM_BOOLEAN("DisplayScheduler.ShouldNotDraw.NotVisible", !visible_); - UMA_HISTOGRAM_BOOLEAN("DisplayScheduler.ShouldNotDraw.RootFrameMissing", - root_frame_missing_); -} - } // namespace viz
diff --git a/components/viz/service/display/display_scheduler.h b/components/viz/service/display/display_scheduler.h index f4f1387..e3a8760 100644 --- a/components/viz/service/display/display_scheduler.h +++ b/components/viz/service/display/display_scheduler.h
@@ -126,7 +126,6 @@ void DidFinishFrame(bool did_draw); // Updates |has_pending_surfaces_| and returns whether its value changed. bool UpdateHasPendingSurfaces(); - void ReportNotDrawReason(); DisplaySchedulerClient* client_; BeginFrameSource* begin_frame_source_;
diff --git a/components/webdata_services/web_data_service_wrapper.cc b/components/webdata_services/web_data_service_wrapper.cc index 28a3f673..2d34f022 100644 --- a/components/webdata_services/web_data_service_wrapper.cc +++ b/components/webdata_services/web_data_service_wrapper.cc
@@ -77,7 +77,6 @@ const scoped_refptr<autofill::AutofillWebDataService>& autofill_web_data, const base::FilePath& context_path, const std::string& app_locale, - bool is_full_sync, autofill::AutofillWebDataBackend* autofill_backend) { DCHECK(db_task_runner->RunsTasksInCurrentSequence()); @@ -106,7 +105,7 @@ if (base::FeatureList::IsEnabled(switches::kSyncUSSAutofillWalletData)) { autofill::AutofillWalletSyncBridge::CreateForWebDataServiceAndBackend( - app_locale, wallet_active_callback, is_full_sync, autofill_backend, + app_locale, wallet_active_callback, autofill_backend, autofill_web_data.get()); } else { autofill::AutofillWalletSyncableService::CreateForWebDataServiceAndBackend( @@ -178,10 +177,9 @@ profile_autofill_web_data_->GetAutofillBackend(base::Bind( &InitSyncableProfileServicesOnDBSequence, db_task_runner, flare, profile_autofill_web_data_, context_path, application_locale)); - profile_autofill_web_data_->GetAutofillBackend( - base::Bind(&InitSyncableAccountServicesOnDBSequence, db_task_runner, - flare, profile_autofill_web_data_, context_path, - application_locale, /*is_full_sync=*/true)); + profile_autofill_web_data_->GetAutofillBackend(base::Bind( + &InitSyncableAccountServicesOnDBSequence, db_task_runner, flare, + profile_autofill_web_data_, context_path, application_locale)); if (base::FeatureList::IsEnabled( autofill::features::kAutofillEnableAccountWalletStorage)) { @@ -195,10 +193,9 @@ account_database_, ui_task_runner, db_task_runner, base::Bind(show_error_callback, ERROR_LOADING_ACCOUNT_AUTOFILL)); account_autofill_web_data_->Init(); - account_autofill_web_data_->GetAutofillBackend( - base::Bind(&InitSyncableAccountServicesOnDBSequence, db_task_runner, - flare, account_autofill_web_data_, context_path, - application_locale, /*is_full_sync=*/false)); + account_autofill_web_data_->GetAutofillBackend(base::Bind( + &InitSyncableAccountServicesOnDBSequence, db_task_runner, flare, + account_autofill_web_data_, context_path, application_locale)); } }
diff --git a/content/app/strings/translations/content_strings_cs.xtb b/content/app/strings/translations/content_strings_cs.xtb index 119d424f53e..bc963c8 100644 --- a/content/app/strings/translations/content_strings_cs.xtb +++ b/content/app/strings/translations/content_strings_cs.xtb
@@ -151,6 +151,7 @@ <translation id="6453774872122745852">poděkování</translation> <translation id="648732519525291180">výběr času</translation> <translation id="6550675742724504774">Možnosti</translation> +<translation id="6572309429103589720">Neplatná gramatika</translation> <translation id="658823671542763450">přejít do režimu celé obrazovky</translation> <translation id="663493177488814956">zdroj</translation> <translation id="6637586476836377253">protokol</translation> @@ -200,6 +201,7 @@ <translation id="8105797009065549151">odkaz na poznámku</translation> <translation id="8117451130807776954">Tento týden</translation> <translation id="8199524924445686405">rrrr</translation> +<translation id="8261464734335370856">Neplatný pravopis</translation> <translation id="8284326494547611709">Titulky</translation> <translation id="835897206747267392">Neplatná hodnota.</translation> <translation id="8415319359811155763">část</translation>
diff --git a/content/app/strings/translations/content_strings_el.xtb b/content/app/strings/translations/content_strings_el.xtb index 0ee66ea..20182c2 100644 --- a/content/app/strings/translations/content_strings_el.xtb +++ b/content/app/strings/translations/content_strings_el.xtb
@@ -151,6 +151,7 @@ <translation id="6453774872122745852">ευχαριστίες</translation> <translation id="648732519525291180">εργαλείο επιλογής ώρας</translation> <translation id="6550675742724504774">Επιλογές</translation> +<translation id="6572309429103589720">Μη έγκυρη γραμματική</translation> <translation id="658823671542763450">ενεργοποίηση πλήρους οθόνης</translation> <translation id="663493177488814956">ροή</translation> <translation id="6637586476836377253">αρχείο καταγραφής</translation> @@ -200,6 +201,7 @@ <translation id="8105797009065549151">παραπομπή</translation> <translation id="8117451130807776954">Αυτήν την εβδομάδα</translation> <translation id="8199524924445686405">εεεε</translation> +<translation id="8261464734335370856">Μη έγκυρη ορθογραφία</translation> <translation id="8284326494547611709">Υπότιτλοι</translation> <translation id="835897206747267392">Μη έγκυρη τιμή.</translation> <translation id="8415319359811155763">τμήμα</translation>
diff --git a/content/app/strings/translations/content_strings_en-GB.xtb b/content/app/strings/translations/content_strings_en-GB.xtb index cdcd671..0dc72b5 100644 --- a/content/app/strings/translations/content_strings_en-GB.xtb +++ b/content/app/strings/translations/content_strings_en-GB.xtb
@@ -151,6 +151,7 @@ <translation id="6453774872122745852">acknowledgements</translation> <translation id="648732519525291180">time picker</translation> <translation id="6550675742724504774">Options</translation> +<translation id="6572309429103589720">Invalid grammar</translation> <translation id="658823671542763450">enter full screen</translation> <translation id="663493177488814956">feed</translation> <translation id="6637586476836377253">log</translation> @@ -200,6 +201,7 @@ <translation id="8105797009065549151">note reference</translation> <translation id="8117451130807776954">This week</translation> <translation id="8199524924445686405">yyyy</translation> +<translation id="8261464734335370856">Invalid spelling</translation> <translation id="8284326494547611709">Captions</translation> <translation id="835897206747267392">Invalid value.</translation> <translation id="8415319359811155763">part</translation>
diff --git a/content/app/strings/translations/content_strings_te.xtb b/content/app/strings/translations/content_strings_te.xtb index f3704ccd..8ca4c0b 100644 --- a/content/app/strings/translations/content_strings_te.xtb +++ b/content/app/strings/translations/content_strings_te.xtb
@@ -214,7 +214,7 @@ <translation id="8550857728288566671">గ్రాఫిక్స్ చిహ్నం</translation> <translation id="8583702881314752957">నిర్వచన జాబితా</translation> <translation id="8597182159515967513">శీర్షిక</translation> -<translation id="860475260694818407">విషయ పట్టిక</translation> +<translation id="860475260694818407">కంటెంట్ల పట్టిక</translation> <translation id="8613126697340063924">రిమోట్ ప్లేబ్యాక్ను నియంత్రిస్తుంది</translation> <translation id="862370744433916922">ఉపశీర్షిక</translation> <translation id="8750798805984357768">దయచేసి ఈ ఎంపికలలో ఒకదాన్ని ఎంచుకోండి.</translation>
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 2987224..85eb70e 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1940,6 +1940,8 @@ sources += [ "gpu/ca_transaction_gpu_coordinator.cc", "gpu/ca_transaction_gpu_coordinator.h", + "sandbox_support_mac_impl.h", + "sandbox_support_mac_impl.mm", "web_contents/web_contents_ns_view_bridge.h", "web_contents/web_contents_ns_view_bridge.mm", ]
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc index ab4166e3..f37ebdb2 100644 --- a/content/browser/browser_context.cc +++ b/content/browser/browser_context.cc
@@ -23,6 +23,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/memory/weak_ptr.h" #include "base/no_destructor.h" #include "base/rand_util.h" #include "base/supports_user_data.h" @@ -66,6 +67,7 @@ #include "services/file/user_id_map.h" #include "services/network/public/cpp/features.h" #include "services/service_manager/public/cpp/connector.h" +#include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/mojom/service.mojom.h" #include "storage/browser/blob/blob_storage_context.h" #include "storage/browser/database/database_tracker.h" @@ -247,11 +249,18 @@ : public base::SupportsUserData::Data { public: explicit BrowserContextServiceManagerConnectionHolder( + BrowserContext* browser_context, service_manager::mojom::ServiceRequest request) - : service_manager_connection_(ServiceManagerConnection::Create( + : browser_context_(browser_context), + service_manager_connection_(ServiceManagerConnection::Create( std::move(request), base::CreateSingleThreadTaskRunnerWithTraits( - {BrowserThread::IO}))) {} + {BrowserThread::IO}))) { + service_manager_connection_->SetDefaultServiceRequestHandler( + base::BindRepeating( + &BrowserContextServiceManagerConnectionHolder::OnServiceRequest, + weak_ptr_factory_.GetWeakPtr())); + } ~BrowserContextServiceManagerConnectionHolder() override {} ServiceManagerConnection* service_manager_connection() { @@ -259,7 +268,35 @@ } private: + void OnServiceRequest(const std::string& service_name, + service_manager::mojom::ServiceRequest request) { + std::unique_ptr<service_manager::Service> service = + browser_context_->HandleServiceRequest(service_name, + std::move(request)); + if (!service) { + LOG(ERROR) << "Ignoring request for unknown per-browser-context service:" + << service_name; + return; + } + + auto* raw_service = service.get(); + service->set_termination_closure(base::BindOnce( + &BrowserContextServiceManagerConnectionHolder::OnServiceQuit, + base::Unretained(this), raw_service)); + running_services_.emplace(raw_service, std::move(service)); + } + + void OnServiceQuit(service_manager::Service* service) { + running_services_.erase(service); + } + + BrowserContext* const browser_context_; std::unique_ptr<ServiceManagerConnection> service_manager_connection_; + std::map<service_manager::Service*, std::unique_ptr<service_manager::Service>> + running_services_; + + base::WeakPtrFactory<BrowserContextServiceManagerConnectionHolder> + weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(BrowserContextServiceManagerConnectionHolder); }; @@ -591,7 +628,7 @@ BrowserContextServiceManagerConnectionHolder* connection_holder = new BrowserContextServiceManagerConnectionHolder( - std::move(service_request)); + browser_context, std::move(service_request)); browser_context->SetUserData(kServiceManagerConnection, base::WrapUnique(connection_holder)); @@ -739,6 +776,12 @@ return base::UnguessableToken::Create().ToString(); } +std::unique_ptr<service_manager::Service> BrowserContext::HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request) { + return nullptr; +} + const std::string& BrowserContext::UniqueId() const { return unique_id_; }
diff --git a/content/browser/code_cache/generated_code_cache_context.cc b/content/browser/code_cache/generated_code_cache_context.cc index b119832..6dc0fb9 100644 --- a/content/browser/code_cache/generated_code_cache_context.cc +++ b/content/browser/code_cache/generated_code_cache_context.cc
@@ -7,6 +7,7 @@ #include "content/browser/code_cache/generated_code_cache.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#include "third_party/blink/public/common/features.h" namespace content { @@ -29,9 +30,13 @@ generated_js_code_cache_.reset( new GeneratedCodeCache(path.AppendASCII("js"), max_bytes, GeneratedCodeCache::CodeCacheType::kJavaScript)); - generated_wasm_code_cache_.reset( - new GeneratedCodeCache(path.AppendASCII("wasm"), max_bytes, - GeneratedCodeCache::CodeCacheType::kWebAssembly)); + + // Only create the Wasm cache if it's enabled. + if (base::FeatureList::IsEnabled(blink::features::kWasmCodeCache)) { + generated_wasm_code_cache_.reset(new GeneratedCodeCache( + path.AppendASCII("wasm"), max_bytes, + GeneratedCodeCache::CodeCacheType::kWebAssembly)); + } } GeneratedCodeCache* GeneratedCodeCacheContext::generated_js_code_cache() const {
diff --git a/content/browser/devtools/devtools_renderer_channel.cc b/content/browser/devtools/devtools_renderer_channel.cc index 23cd857..9166d37 100644 --- a/content/browser/devtools/devtools_renderer_channel.cc +++ b/content/browser/devtools/devtools_renderer_channel.cc
@@ -59,6 +59,11 @@ blink::mojom::DevToolsAgent* agent, int process_id, RenderFrameHostImpl* frame_host) { + // Child workers will eventually disconnect, but timing depends on the + // renderer process. To ensure consistent view over protocol, disconnect them + // right now. + for (WorkerDevToolsAgentHost* host : child_workers_) + host->ForceDetachAllSessions(); process_id_ = process_id; frame_host_ = frame_host; if (agent && !report_attachers_.empty()) {
diff --git a/content/browser/devtools/devtools_renderer_channel.h b/content/browser/devtools/devtools_renderer_channel.h index 10ec64a..6b369b9 100644 --- a/content/browser/devtools/devtools_renderer_channel.h +++ b/content/browser/devtools/devtools_renderer_channel.h
@@ -22,6 +22,7 @@ class DevToolsAgentHostImpl; class DevToolsSession; class RenderFrameHostImpl; +class WorkerDevToolsAgentHost; namespace protocol { class TargetAutoAttacher; @@ -81,7 +82,7 @@ RenderFrameHostImpl* frame_host_ = nullptr; base::flat_set<protocol::TargetAutoAttacher*> report_attachers_; base::flat_set<protocol::TargetAutoAttacher*> wait_for_debugger_attachers_; - base::flat_set<DevToolsAgentHostImpl*> child_workers_; + base::flat_set<WorkerDevToolsAgentHost*> child_workers_; base::WeakPtrFactory<DevToolsRendererChannel> weak_factory_; DISALLOW_COPY_AND_ASSIGN(DevToolsRendererChannel);
diff --git a/content/browser/frame_host/OWNERS b/content/browser/frame_host/OWNERS index 1a2abc4..4b0c00a 100644 --- a/content/browser/frame_host/OWNERS +++ b/content/browser/frame_host/OWNERS
@@ -2,6 +2,7 @@ # For surface ID propagation and synchronization per-file render_widget_host_view_guest*=fsamuel@chromium.org +per-file render_widget_host_view_guest*=samans@chromium.org # For compositing and input related changes. per-file cross_process_frame_connector*=kenrb@chromium.org
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index acf0feee..e7ca131 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -302,16 +302,24 @@ : base::Optional<url::Origin>( frame_tree_node->frame_tree()->root()->current_origin()); + auto navigation_params = mojom::BeginNavigationParams::New( + extra_headers, net::LOAD_NORMAL, false /* skip_service_worker */, + blink::mojom::RequestContextType::LOCATION, + blink::WebMixedContentContextType::kBlockable, is_form_submission, + GURL() /* searchable_form_url */, + std::string() /* searchable_form_encoding */, initiator, + GURL() /* client_side_redirect_url */, + base::nullopt /* devtools_initiator_info */); + + // Shift-Reload forces bypassing caches and service workers. + if (common_params.navigation_type == + FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE) { + navigation_params->load_flags |= net::LOAD_BYPASS_CACHE; + navigation_params->skip_service_worker = true; + } + std::unique_ptr<NavigationRequest> navigation_request(new NavigationRequest( - frame_tree_node, common_params, - mojom::BeginNavigationParams::New( - extra_headers, net::LOAD_NORMAL, false /* skip_service_worker */, - blink::mojom::RequestContextType::LOCATION, - blink::WebMixedContentContextType::kBlockable, is_form_submission, - GURL() /* searchable_form_url */, - std::string() /* searchable_form_encoding */, initiator, - GURL() /* client_side_redirect_url */, - base::nullopt /* devtools_initiator_info */), + frame_tree_node, common_params, std::move(navigation_params), request_params, browser_initiated, false /* from_begin_navigation */, &frame_entry, &entry, std::move(navigation_ui_data), nullptr, nullptr)); navigation_request->blob_url_loader_factory_ =
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 2bf931a..abb6239 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -165,7 +165,6 @@ #include "services/network/public/cpp/features.h" #include "services/network/public/cpp/wrapper_shared_url_loader_factory.h" #include "services/network/public/mojom/network_service.mojom.h" -#include "services/resource_coordinator/public/cpp/frame_resource_coordinator.h" #include "services/resource_coordinator/public/cpp/resource_coordinator_features.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_provider.h" @@ -444,6 +443,14 @@ return url::Origin::Resolve(target_url, fallback_origin); } +service_manager::Connector* MaybeGetConnectorForProcess() { + auto* connection = ServiceManagerConnection::GetForProcess(); + if (!connection) + return nullptr; + + return connection->GetConnector(); +} + } // namespace class RenderFrameHostImpl::DroppedInterfaceRequestLogger @@ -604,7 +611,7 @@ proxy_ = nullptr; if (!render_frame_host_) return; - std::move(callback_).Run(FileChooserResult::New()); + std::move(callback_).Run(nullptr); } private: @@ -762,6 +769,7 @@ accessibility_reset_count_(0), browser_plugin_embedder_ax_tree_id_(ui::AXTreeIDUnknown()), no_create_browser_accessibility_manager_for_testing_(false), + frame_resource_coordinator_(MaybeGetConnectorForProcess()), web_ui_type_(WebUI::kNoWebUI), pending_web_ui_type_(WebUI::kNoWebUI), should_reuse_web_ui_(false), @@ -860,6 +868,15 @@ : frame_tree_node_->opener(); if (frame_owner) CSPContext::SetSelf(frame_owner->current_origin()); + + // Hook up the Resource Coordinator edges to the associated process and + // parent frame, if any. + frame_resource_coordinator_.SetProcess( + *GetProcess()->GetProcessResourceCoordinator()); + if (parent_) { + parent_->GetFrameResourceCoordinator()->AddChildFrame( + frame_resource_coordinator_); + } } RenderFrameHostImpl::~RenderFrameHostImpl() { @@ -4762,6 +4779,7 @@ // Disconnect with ImageDownloader Mojo service in RenderFrame. mojo_image_downloader_.reset(); + // Make sure the renderer cannot add new bindings. frame_resource_coordinator_.reset(); // The geolocation service and sensor provider proxy may attempt to cancel @@ -4893,17 +4911,7 @@ resource_coordinator::FrameResourceCoordinator* RenderFrameHostImpl::GetFrameResourceCoordinator() { - if (!frame_resource_coordinator_) { - auto* connection = ServiceManagerConnection::GetForProcess(); - frame_resource_coordinator_ = - std::make_unique<resource_coordinator::FrameResourceCoordinator>( - connection ? connection->GetConnector() : nullptr); - if (parent_) { - parent_->GetFrameResourceCoordinator()->AddChildFrame( - *frame_resource_coordinator_); - } - } - return frame_resource_coordinator_.get(); + return &frame_resource_coordinator_; } void RenderFrameHostImpl::ResetLoadingState() {
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 4eb886e..d764b5224 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -59,6 +59,7 @@ #include "mojo/public/cpp/system/data_pipe.h" #include "net/http/http_response_headers.h" #include "services/device/public/mojom/wake_lock_context.mojom.h" +#include "services/resource_coordinator/public/cpp/frame_resource_coordinator.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/mojom/interface_provider.mojom.h" #include "services/viz/public/interfaces/hit_test/input_target_client.mojom.h" @@ -1556,8 +1557,7 @@ blink::mojom::FindInPageAssociatedPtr find_in_page_; // Holds the interface wrapper to the Global Resource Coordinator service. - std::unique_ptr<resource_coordinator::FrameResourceCoordinator> - frame_resource_coordinator_; + resource_coordinator::FrameResourceCoordinator frame_resource_coordinator_; // Holds a NavigationRequest when it's about to commit, ie. after // OnCrossDocumentCommitProcessed has returned a positive answer for this
diff --git a/content/browser/message_port_provider.cc b/content/browser/message_port_provider.cc index 649b69b..f0647216 100644 --- a/content/browser/message_port_provider.cc +++ b/content/browser/message_port_provider.cc
@@ -76,12 +76,10 @@ const base::android::JavaParamRef<jstring>& target_origin, const base::android::JavaParamRef<jstring>& data, const base::android::JavaParamRef<jobjectArray>& ports) { - PostMessageToFrameInternal( - web_contents, - ToString16(env, source_origin), - ToString16(env, target_origin), - ToString16(env, data), - AppWebMessagePort::UnwrapJavaArray(env, ports)); + PostMessageToFrameInternal(web_contents, ToString16(env, source_origin), + ToString16(env, target_origin), + ToString16(env, data), + AppWebMessagePort::UnwrapJavaArray(env, ports)); } #endif
diff --git a/content/browser/renderer_host/OWNERS b/content/browser/renderer_host/OWNERS index 5108375..10340fbe 100644 --- a/content/browser/renderer_host/OWNERS +++ b/content/browser/renderer_host/OWNERS
@@ -22,9 +22,11 @@ # For surface ID propagation and synchronization fsamuel@chromium.org +samans@chromium.org # DelegatedFrame* per-file *delegated_frame*=fsamuel@chromium.org +per-file *delegated_frame*=samans@chromium.org # WebSQL per-file web_database_*=jsbell@chromium.org
diff --git a/content/browser/renderer_host/input/touch_action_filter.cc b/content/browser/renderer_host/input/touch_action_filter.cc index 8c838779..1a6c79f7 100644 --- a/content/browser/renderer_host/input/touch_action_filter.cc +++ b/content/browser/renderer_host/input/touch_action_filter.cc
@@ -48,6 +48,62 @@ UMA_HISTOGRAM_BOOLEAN("TouchAction.GestureEventFiltered", event_filtered); } +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class GestureEventFilterResults { + kGSBAllowedByMain = 0, + kGSBAllowedByCC = 1, + kGSBFilteredByMain = 2, + kGSBFilteredByCC = 3, + kGSBDeferred = 4, + kGSUAllowedByMain = 5, + kGSUAllowedByCC = 6, + kGSUFilteredByMain = 7, + kGSUFilteredByCC = 8, + kGSUDeferred = 9, + kFilterResultsCount = 10, + kMaxValue = kFilterResultsCount +}; + +void ReportGestureEventFilterResults(bool is_gesture_scroll_begin, + bool active_touch_action_known, + FilterGestureEventResult result) { + GestureEventFilterResults report_type; + if (is_gesture_scroll_begin) { + if (result == FilterGestureEventResult::kFilterGestureEventAllowed) { + if (active_touch_action_known) + report_type = GestureEventFilterResults::kGSBAllowedByMain; + else + report_type = GestureEventFilterResults::kGSBAllowedByCC; + } else if (result == + FilterGestureEventResult::kFilterGestureEventFiltered) { + if (active_touch_action_known) + report_type = GestureEventFilterResults::kGSBFilteredByMain; + else + report_type = GestureEventFilterResults::kGSBFilteredByCC; + } else { + report_type = GestureEventFilterResults::kGSBDeferred; + } + } else { + if (result == FilterGestureEventResult::kFilterGestureEventAllowed) { + if (active_touch_action_known) + report_type = GestureEventFilterResults::kGSUAllowedByMain; + else + report_type = GestureEventFilterResults::kGSUAllowedByCC; + } else if (result == + FilterGestureEventResult::kFilterGestureEventFiltered) { + if (active_touch_action_known) + report_type = GestureEventFilterResults::kGSUFilteredByMain; + else + report_type = GestureEventFilterResults::kGSUFilteredByCC; + } else { + report_type = GestureEventFilterResults::kGSUDeferred; + } + } + UMA_HISTOGRAM_ENUMERATION("TouchAction.GestureEventFilterResults", + report_type, GestureEventFilterResults::kMaxValue); +} + } // namespace TouchActionFilter::TouchActionFilter() @@ -69,8 +125,16 @@ return FilterGestureEventResult::kFilterGestureEventDelayed; } - if (compositor_touch_action_enabled_ && has_deferred_events_) + if (compositor_touch_action_enabled_ && has_deferred_events_) { + WebInputEvent::Type type = gesture_event->GetType(); + if (type == WebInputEvent::kGestureScrollBegin || + type == WebInputEvent::kGestureScrollUpdate) { + ReportGestureEventFilterResults( + type == WebInputEvent::kGestureScrollBegin, false, + FilterGestureEventResult::kFilterGestureEventDelayed); + } return FilterGestureEventResult::kFilterGestureEventDelayed; + } base::Optional<cc::TouchAction> touch_action = active_touch_action_.has_value() ? active_touch_action_ @@ -101,17 +165,27 @@ DCHECK(touch_action.has_value()); drop_scroll_events_ = ShouldSuppressScrolling(*gesture_event, touch_action.value()); - if (!drop_scroll_events_) - return FilterGestureEventResult::kFilterGestureEventAllowed; - if (active_touch_action_.has_value()) - return FilterGestureEventResult::kFilterGestureEventFiltered; - has_deferred_events_ = true; - return FilterGestureEventResult::kFilterGestureEventDelayed; + FilterGestureEventResult res; + if (!drop_scroll_events_) { + res = FilterGestureEventResult::kFilterGestureEventAllowed; + } else if (active_touch_action_.has_value()) { + res = FilterGestureEventResult::kFilterGestureEventFiltered; + } else { + has_deferred_events_ = true; + res = FilterGestureEventResult::kFilterGestureEventDelayed; + } + ReportGestureEventFilterResults(true, active_touch_action_.has_value(), + res); + return res; } case WebInputEvent::kGestureScrollUpdate: { - if (drop_scroll_events_) + if (drop_scroll_events_) { + ReportGestureEventFilterResults( + false, active_touch_action_.has_value(), + FilterGestureEventResult::kFilterGestureEventFiltered); return FilterGestureEventResult::kFilterGestureEventFiltered; + } if (!compositor_touch_action_enabled_) gesture_sequence_.append("U"); @@ -135,6 +209,9 @@ !active_touch_action_.has_value() && gesture_event->data.scroll_update.delta_y != 0) { has_deferred_events_ = true; + ReportGestureEventFilterResults( + false, active_touch_action_.has_value(), + FilterGestureEventResult::kFilterGestureEventDelayed); return FilterGestureEventResult::kFilterGestureEventDelayed; } gesture_event->data.scroll_update.delta_y = 0; @@ -144,11 +221,17 @@ !active_touch_action_.has_value() && gesture_event->data.scroll_update.delta_x != 0) { has_deferred_events_ = true; + ReportGestureEventFilterResults( + false, active_touch_action_.has_value(), + FilterGestureEventResult::kFilterGestureEventDelayed); return FilterGestureEventResult::kFilterGestureEventDelayed; } gesture_event->data.scroll_update.delta_x = 0; gesture_event->data.scroll_update.velocity_x = 0; } + ReportGestureEventFilterResults( + false, active_touch_action_.has_value(), + FilterGestureEventResult::kFilterGestureEventAllowed); break; }
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index aa40b98c2..9586e9b 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -205,7 +205,6 @@ #include "services/network/public/cpp/features.h" #include "services/network/public/cpp/network_switches.h" #include "services/network/public/mojom/network_service.mojom.h" -#include "services/resource_coordinator/public/cpp/process_resource_coordinator.h" #include "services/service_manager/embedder/switches.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/connector.h" @@ -1306,6 +1305,14 @@ base::BindOnce(&AddCorbExceptionForPluginOnUIThread, process_id)); } +service_manager::Connector* MaybeGetConnectorForProcess() { + auto* connection = ServiceManagerConnection::GetForProcess(); + if (!connection) + return nullptr; + + return connection->GetConnector(); +} + } // namespace // Held by the RPH and used to control an (unowned) ConnectionFilterImpl from @@ -1586,6 +1593,7 @@ channel_connected_(false), sent_render_process_ready_(false), renderer_host_binding_(this), + process_resource_coordinator_(MaybeGetConnectorForProcess()), instance_weak_factory_( new base::WeakPtrFactory<RenderProcessHostImpl>(this)), frame_sink_provider_(id_), @@ -2512,13 +2520,7 @@ resource_coordinator::ProcessResourceCoordinator* RenderProcessHostImpl::GetProcessResourceCoordinator() { - if (!process_resource_coordinator_) { - auto* connection = ServiceManagerConnection::GetForProcess(); - process_resource_coordinator_ = - std::make_unique<resource_coordinator::ProcessResourceCoordinator>( - connection ? connection->GetConnector() : nullptr); - } - return process_resource_coordinator_.get(); + return &process_resource_coordinator_; } void RenderProcessHostImpl::CreateURLLoaderFactory( @@ -4144,7 +4146,8 @@ // Make sure no IPCs or mojo calls from the old process get dispatched after // it has died. ResetIPC(); - process_resource_coordinator_.reset(); + + process_resource_coordinator_.SetProcessExitStatus(info.exit_code); UpdateProcessPriority();
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 1406a87c..08b221d 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -53,6 +53,7 @@ #include "mojo/public/cpp/system/invitation.h" #include "services/network/public/mojom/mdns_responder.mojom.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" +#include "services/resource_coordinator/public/cpp/process_resource_coordinator.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/mojom/service.mojom.h" #include "services/viz/public/interfaces/compositing/compositing_mode_watcher.mojom.h" @@ -854,7 +855,7 @@ // determine if if a process should be backgrounded. int media_stream_count_ = 0; - std::unique_ptr<resource_coordinator::ProcessResourceCoordinator> + resource_coordinator::ProcessResourceCoordinator process_resource_coordinator_; // A WeakPtrFactory which is reset every time Cleanup() runs. Used to vend
diff --git a/content/browser/renderer_host/text_input_client_mac.mm b/content/browser/renderer_host/text_input_client_mac.mm index 3a6bcfb5..2942917 100644 --- a/content/browser/renderer_host/text_input_client_mac.mm +++ b/content/browser/renderer_host/text_input_client_mac.mm
@@ -106,7 +106,7 @@ BeforeRequest(); // http://crbug.com/121917 - base::ThreadRestrictions::ScopedAllowWait allow_wait; + base::ScopedAllowBaseSyncPrimitives allow_wait; condition_.TimedWait(base::TimeDelta::FromMilliseconds(kWaitTimeout)); AfterRequest(); @@ -131,7 +131,7 @@ BeforeRequest(); // http://crbug.com/121917 - base::ThreadRestrictions::ScopedAllowWait allow_wait; + base::ScopedAllowBaseSyncPrimitives allow_wait; condition_.TimedWait(base::TimeDelta::FromMilliseconds(kWaitTimeout)); AfterRequest();
diff --git a/content/browser/sandbox_support_mac_impl.h b/content/browser/sandbox_support_mac_impl.h new file mode 100644 index 0000000..525c03a5 --- /dev/null +++ b/content/browser/sandbox_support_mac_impl.h
@@ -0,0 +1,42 @@ +// 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 CONTENT_BROWSER_SANDBOX_SUPPORT_MAC_IMPL_H_ +#define CONTENT_BROWSER_SANDBOX_SUPPORT_MAC_IMPL_H_ + +#include "base/macros.h" +#include "content/common/sandbox_support_mac.mojom.h" +#include "mojo/public/cpp/bindings/binding_set.h" + +namespace service_manager { +struct BindSourceInfo; +} + +namespace content { + +// Performs privileged operations on behalf of sandboxed child processes. +// This is used to implement the blink::WebSandboxSupport interface in the +// renderer. However all child process types have access to this interface. +// This class lives on the IO thread and is owned by the Mojo interface +// registry. +class SandboxSupportMacImpl : public mojom::SandboxSupportMac { + public: + SandboxSupportMacImpl(); + ~SandboxSupportMacImpl() override; + + void BindRequest(mojom::SandboxSupportMacRequest request, + const service_manager::BindSourceInfo& source_info); + + // content::mojom::SandboxSupportMac: + void GetSystemColors(GetSystemColorsCallback callback) override; + + private: + mojo::BindingSet<mojom::SandboxSupportMac> bindings_; + + DISALLOW_COPY_AND_ASSIGN(SandboxSupportMacImpl); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SANDBOX_SUPPORT_MAC_IMPL_H_
diff --git a/content/browser/sandbox_support_mac_impl.mm b/content/browser/sandbox_support_mac_impl.mm new file mode 100644 index 0000000..a9f5741 --- /dev/null +++ b/content/browser/sandbox_support_mac_impl.mm
@@ -0,0 +1,35 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "content/browser/sandbox_support_mac_impl.h" + +#include "base/bind.h" +#include "base/task/post_task.h" +#include "base/task_runner_util.h" +#import "content/browser/theme_helper_mac.h" +#include "content/public/browser/browser_task_traits.h" + +namespace content { + +SandboxSupportMacImpl::SandboxSupportMacImpl() = default; + +SandboxSupportMacImpl::~SandboxSupportMacImpl() = default; + +void SandboxSupportMacImpl::BindRequest( + mojom::SandboxSupportMacRequest request, + const service_manager::BindSourceInfo& source_info) { + bindings_.AddBinding(this, std::move(request)); +} + +void SandboxSupportMacImpl::GetSystemColors(GetSystemColorsCallback callback) { + auto task_runner = + base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}); + base::PostTaskAndReplyWithResult( + task_runner.get(), FROM_HERE, + base::BindOnce(&ThemeHelperMac::DuplicateReadOnlyColorMapRegion, + base::Unretained(ThemeHelperMac::GetInstance())), + std::move(callback)); +} + +} // namespace content
diff --git a/content/browser/service_manager/common_browser_interfaces.cc b/content/browser/service_manager/common_browser_interfaces.cc index 631c580..ef7b723 100644 --- a/content/browser/service_manager/common_browser_interfaces.cc +++ b/content/browser/service_manager/common_browser_interfaces.cc
@@ -33,6 +33,7 @@ #include "content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h" #include "content/public/common/font_cache_dispatcher_win.h" #elif defined(OS_MACOSX) +#include "content/browser/sandbox_support_mac_impl.h" #include "content/common/font_loader_dispatcher_mac.h" #endif @@ -51,6 +52,9 @@ {base::TaskPriority::USER_BLOCKING, base::MayBlock()})); #elif defined(OS_MACOSX) registry_.AddInterface(base::BindRepeating(&FontLoaderDispatcher::Create)); + registry_.AddInterface( + base::BindRepeating(&SandboxSupportMacImpl::BindRequest, + base::Owned(new SandboxSupportMacImpl))); #endif if (!features::IsMultiProcessMash()) { // For mus, the mojom::discardable_memory::DiscardableSharedMemoryManager
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc index 07c6fcd..0bc52c66 100644 --- a/content/browser/service_manager/service_manager_context.cc +++ b/content/browser/service_manager/service_manager_context.cc
@@ -412,6 +412,20 @@ return std::make_unique<video_capture::ServiceImpl>(std::move(request)); } +#if defined(OS_LINUX) +void CreateFontService(service_manager::mojom::ServiceRequest request) { + // The font service owns itself here, deleting on self-termination. + auto service = + std::make_unique<font_service::FontServiceApp>(std::move(request)); + auto* raw_service = service.get(); + raw_service->set_termination_closure(base::BindOnce( + [](std::unique_ptr<font_service::FontServiceApp> service) { + // Nothing to do but let |service| go out of scope. + }, + std::move(service))); +} +#endif // defined(OS_LINUX) + } // namespace // State which lives on the IO thread and drives the ServiceManager. @@ -698,16 +712,16 @@ base::BindRepeating(&base::ASCIIToUTF16, "Data Decoder Service"); #if defined(OS_LINUX) - { - service_manager::EmbeddedServiceInfo font_service_info; - font_service_info.factory = - base::BindRepeating(font_service::FontServiceApp::CreateService); - font_service_info.task_runner = base::CreateSequencedTaskRunnerWithTraits( - base::TaskTraits({base::MayBlock(), base::WithBaseSyncPrimitives(), - base::TaskPriority::USER_BLOCKING})); - packaged_services_connection_->AddEmbeddedService( - font_service::mojom::kServiceName, font_service_info); - } + packaged_services_connection_->AddServiceRequestHandler( + font_service::mojom::kServiceName, + base::BindRepeating([](service_manager::mojom::ServiceRequest request) { + auto task_runner = + base::CreateSequencedTaskRunnerWithTraits(base::TaskTraits( + {base::MayBlock(), base::WithBaseSyncPrimitives(), + base::TaskPriority::USER_BLOCKING})); + task_runner->PostTask(FROM_HERE, base::BindOnce(&CreateFontService, + std::move(request))); + })); #endif bool network_service_enabled =
diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc index 4ee2f9fc..62a7603fe 100644 --- a/content/browser/storage_partition_impl_unittest.cc +++ b/content/browser/storage_partition_impl_unittest.cc
@@ -42,6 +42,7 @@ #include "storage/browser/test/mock_quota_manager.h" #include "storage/browser/test/mock_special_storage_policy.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" #if BUILDFLAG(ENABLE_PLUGINS) #include "ppapi/shared_impl/ppapi_constants.h" // nogncheck @@ -1305,16 +1306,10 @@ GURL origin = GURL(kTestOrigin1); std::string data("SomeData"); - std::string data2("SomeData.wasm"); tester.AddEntry(RemoveCodeCacheTester::kJs, kResourceURL, origin, data); - tester.AddEntry(RemoveCodeCacheTester::kWebAssembly, kResourceURL, origin, - data2); EXPECT_TRUE( tester.ContainsEntry(RemoveCodeCacheTester::kJs, kResourceURL, origin)); EXPECT_EQ(tester.received_data(), data); - EXPECT_TRUE(tester.ContainsEntry(RemoveCodeCacheTester::kWebAssembly, - kResourceURL, origin)); - EXPECT_EQ(tester.received_data(), data2); base::RunLoop run_loop; base::ThreadTaskRunnerHandle::Get()->PostTask( @@ -1323,6 +1318,42 @@ EXPECT_FALSE( tester.ContainsEntry(RemoveCodeCacheTester::kJs, kResourceURL, origin)); + + // Make sure there isn't a second invalid callback sitting in the queue. + // (this used to be a bug). + base::RunLoop().RunUntilIdle(); +} + +TEST_F(StoragePartitionImplTest, ClearWasmCodeCache) { + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeatures( + std::vector<base::Feature>( + {net::features::kIsolatedCodeCache, blink::features::kWasmCodeCache}), + std::vector<base::Feature>()); + ASSERT_TRUE(base::FeatureList::IsEnabled(net::features::kIsolatedCodeCache)); + ASSERT_TRUE(base::FeatureList::IsEnabled(blink::features::kWasmCodeCache)); + + StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>( + BrowserContext::GetDefaultStoragePartition(browser_context())); + // Ensure code cache is initialized. + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(partition->GetGeneratedCodeCacheContext() != nullptr); + + RemoveCodeCacheTester tester(partition->GetGeneratedCodeCacheContext()); + + GURL origin = GURL(kTestOrigin1); + std::string data("SomeData.wasm"); + tester.AddEntry(RemoveCodeCacheTester::kWebAssembly, kResourceURL, origin, + data); + EXPECT_TRUE(tester.ContainsEntry(RemoveCodeCacheTester::kWebAssembly, + kResourceURL, origin)); + EXPECT_EQ(tester.received_data(), data); + + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&ClearCodeCache, partition, &run_loop)); + run_loop.Run(); + EXPECT_FALSE(tester.ContainsEntry(RemoveCodeCacheTester::kWebAssembly, kResourceURL, origin));
diff --git a/content/browser/theme_helper_mac.h b/content/browser/theme_helper_mac.h index 644b37b..07fdd7a1 100644 --- a/content/browser/theme_helper_mac.h +++ b/content/browser/theme_helper_mac.h
@@ -6,13 +6,24 @@ #define CONTENT_BROWSER_THEME_HELPER_MAC_H_ #include "base/macros.h" -#include "base/memory/singleton.h" +#include "base/memory/read_only_shared_memory_region.h" +#include "base/memory/writable_shared_memory_region.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +#include "third_party/blink/public/common/sandbox_support/sandbox_support_mac.h" #include "third_party/blink/public/platform/mac/web_scrollbar_theme.h" +#if __OBJC__ +@class SystemThemeObserver; +#else +class SystemThemeObserver; +#endif + namespace content { +// This class is used to monitor macOS system appearance changes and to notify +// sandboxed child processes when they change. This class lives on the UI +// thread. class ThemeHelperMac : public NotificationObserver { public: // Return pointer to the singleton instance for the current process, or NULL @@ -23,17 +34,33 @@ // as the blink enum value. static blink::ScrollerStyle GetPreferredScrollerStyle(); - private: - friend struct base::DefaultSingletonTraits<ThemeHelperMac>; + // Duplicates a handle to the read-only copy of the system color table, + // which can be shared to sandboxed child processes. + base::ReadOnlySharedMemoryRegion DuplicateReadOnlyColorMapRegion(); + private: ThemeHelperMac(); ~ThemeHelperMac() override; + // Looks up the blink::MacSystemColorID corresponding to the NSColor + // selector and stores them in the |writable_color_map_| table. + void LoadSystemColors(); + // Overridden from NotificationObserver: void Observe(int type, const NotificationSource& source, const NotificationDetails& details) override; + // ObjC object that observes notifications from the system. + SystemThemeObserver* theme_observer_; // strong + + // Writable and mapped array of SkColor values, indexed by MacSystemColorID. + base::WritableSharedMemoryMapping writable_color_map_; + + // Read-only handle to the |writable_color_map_| that can be duplicated for + // sharing to child processes. + base::ReadOnlySharedMemoryRegion read_only_color_map_; + NotificationRegistrar registrar_; DISALLOW_COPY_AND_ASSIGN(ThemeHelperMac);
diff --git a/content/browser/theme_helper_mac.mm b/content/browser/theme_helper_mac.mm index 75fe00eb..2d5c21d 100644 --- a/content/browser/theme_helper_mac.mm +++ b/content/browser/theme_helper_mac.mm
@@ -4,10 +4,14 @@ #include "content/browser/theme_helper_mac.h" +#import <Carbon/Carbon.h> #import <Cocoa/Cocoa.h> +#include "base/bind.h" +#include "base/callback.h" #include "base/command_line.h" #include "base/mac/mac_util.h" +#include "base/mac/scoped_nsobject.h" #include "base/strings/sys_string_conversions.h" #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h" @@ -20,6 +24,7 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_iterator.h" #include "content/public/common/content_switches.h" +#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" using content::RenderProcessHost; using content::RenderProcessHostImpl; @@ -76,20 +81,110 @@ [defaults stringForKey:@"AppleHighlightColor"])); } +SkColor NSColorToSkColor(NSColor* color) { + NSColor* color_in_color_space = + [color colorUsingColorSpace:[NSColorSpace sRGBColorSpace]]; + if (color_in_color_space) { + // Use nextafter() to avoid rounding colors in a way that could be off-by- + // one. See https://bugs.webkit.org/show_bug.cgi?id=6129. + static const double kScaleFactor = nextafter(256.0, 0.0); + return SkColorSetARGB( + static_cast<int>(kScaleFactor * [color_in_color_space alphaComponent]), + static_cast<int>(kScaleFactor * [color_in_color_space redComponent]), + static_cast<int>(kScaleFactor * [color_in_color_space greenComponent]), + static_cast<int>(kScaleFactor * [color_in_color_space blueComponent])); + } + + // This conversion above can fail if the NSColor in question is an + // NSPatternColor (as many system colors are). These colors are actually a + // repeating pattern not just a solid color. To work around this we simply + // draw a 1x1 image of the color and use that pixel's color. It might be + // better to use an average of the colors in the pattern instead. + base::scoped_nsobject<NSBitmapImageRep> offscreen_rep( + [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil + pixelsWide:1 + pixelsHigh:1 + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow:4 + bitsPerPixel:32]); + + { + gfx::ScopedNSGraphicsContextSaveGState gstate; + [NSGraphicsContext + setCurrentContext:[NSGraphicsContext + graphicsContextWithBitmapImageRep:offscreen_rep]]; + [color set]; + NSRectFill(NSMakeRect(0, 0, 1, 1)); + } + + NSUInteger pixel[4]; + [offscreen_rep getPixel:pixel atX:0 y:0]; + // This recursive call will not recurse again, because the color space + // the second time around is NSDeviceRGBColorSpace. + return NSColorToSkColor([NSColor colorWithDeviceRed:pixel[0] / 255. + green:pixel[1] / 255. + blue:pixel[2] / 255. + alpha:1.]); +} + +SkColor MenuBackgroundColor() { + base::scoped_nsobject<NSBitmapImageRep> offscreen_rep( + [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil + pixelsWide:1 + pixelsHigh:1 + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow:4 + bitsPerPixel:32]); + + CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext + graphicsContextWithBitmapImageRep:offscreen_rep] graphicsPort]); + CGRect rect = CGRectMake(0, 0, 1, 1); + HIThemeMenuDrawInfo draw_info; + draw_info.version = 0; + draw_info.menuType = kThemeMenuTypePopUp; + HIThemeDrawMenuBackground(&rect, &draw_info, context, + kHIThemeOrientationInverted); + + NSUInteger pixel[4]; + [offscreen_rep getPixel:pixel atX:0 y:0]; + return NSColorToSkColor([NSColor colorWithDeviceRed:pixel[0] / 255. + green:pixel[1] / 255. + blue:pixel[2] / 255. + alpha:1.]); +} + } // namespace -@interface ScrollbarPrefsObserver : NSObject +@interface SystemThemeObserver : NSObject { + base::RepeatingClosure colorsChangedCallback_; +} -+ (void)registerAsObserver; -+ (void)appearancePrefsChanged:(NSNotification*)notification; -+ (void)behaviorPrefsChanged:(NSNotification*)notification; -+ (void)notifyPrefsChangedWithRedraw:(BOOL)redraw; +- (instancetype)initWithColorsChangedCallback: + (base::RepeatingClosure)colorsChangedCallback; +- (void)appearancePrefsChanged:(NSNotification*)notification; +- (void)behaviorPrefsChanged:(NSNotification*)notification; +- (void)notifyPrefsChangedWithRedraw:(BOOL)redraw; @end -@implementation ScrollbarPrefsObserver +@implementation SystemThemeObserver -+ (void)registerAsObserver { +- (instancetype)initWithColorsChangedCallback: + (base::RepeatingClosure)colorsChangedCallback { + if (!(self = [super init])) { + return nil; + } + + colorsChangedCallback_ = std::move(colorsChangedCallback); + NSDistributedNotificationCenter* distributedCenter = [NSDistributedNotificationCenter defaultCenter]; [distributedCenter addObserver:self @@ -141,17 +236,26 @@ name:NSSystemColorsDidChangeNotification object:nil]; } + + return self; } -+ (void)appearancePrefsChanged:(NSNotification*)notification { +- (void)dealloc { + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; +} + +- (void)appearancePrefsChanged:(NSNotification*)notification { [self notifyPrefsChangedWithRedraw:YES]; } -+ (void)behaviorPrefsChanged:(NSNotification*)notification { +- (void)behaviorPrefsChanged:(NSNotification*)notification { [self notifyPrefsChangedWithRedraw:NO]; } -+ (void)systemColorsChanged:(NSNotification*)notification { +- (void)systemColorsChanged:(NSNotification*)notification { + colorsChangedCallback_.Run(); + for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator()); !it.IsAtEnd(); it.Advance()) { @@ -160,7 +264,7 @@ } } -+ (void)notifyPrefsChangedWithRedraw:(BOOL)redraw { +- (void)notifyPrefsChangedWithRedraw:(BOOL)redraw { for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator()); !it.IsAtEnd(); it.Advance()) { @@ -190,8 +294,8 @@ // static ThemeHelperMac* ThemeHelperMac::GetInstance() { - return base::Singleton<ThemeHelperMac, - base::LeakySingletonTraits<ThemeHelperMac>>::get(); + static ThemeHelperMac* instance = new ThemeHelperMac(); + return instance; } // static @@ -199,14 +303,112 @@ return static_cast<blink::ScrollerStyle>([NSScroller preferredScrollerStyle]); } +base::ReadOnlySharedMemoryRegion +ThemeHelperMac::DuplicateReadOnlyColorMapRegion() { + return read_only_color_map_.Duplicate(); +} + ThemeHelperMac::ThemeHelperMac() { - [ScrollbarPrefsObserver registerAsObserver]; + // Allocate a region for the SkColor value table and map it. + auto writable_region = base::WritableSharedMemoryRegion::Create( + sizeof(SkColor) * blink::kMacSystemColorIDCount); + writable_color_map_ = writable_region.Map(); + // Downgrade the region to read-only after it has been mapped. + read_only_color_map_ = base::WritableSharedMemoryRegion::ConvertToReadOnly( + std::move(writable_region)); + // Store the current color scheme into the table. + LoadSystemColors(); + + theme_observer_ = [[SystemThemeObserver alloc] + initWithColorsChangedCallback:base::BindRepeating( + &ThemeHelperMac::LoadSystemColors, + base::Unretained(this))]; registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CREATED, NotificationService::AllSources()); } ThemeHelperMac::~ThemeHelperMac() { + [theme_observer_ release]; +} + +void ThemeHelperMac::LoadSystemColors() { + base::span<SkColor> values = writable_color_map_.GetMemoryAsSpan<SkColor>( + blink::kMacSystemColorIDCount); + for (size_t i = 0; i < blink::kMacSystemColorIDCount; ++i) { + blink::MacSystemColorID color_id = static_cast<blink::MacSystemColorID>(i); + switch (color_id) { + case blink::MacSystemColorID::kAlternateSelectedControl: + values[i] = NSColorToSkColor([NSColor alternateSelectedControlColor]); + break; + case blink::MacSystemColorID::kControlBackground: + values[i] = NSColorToSkColor([NSColor controlBackgroundColor]); + break; + case blink::MacSystemColorID::kControlDarkShadow: + values[i] = NSColorToSkColor([NSColor controlDarkShadowColor]); + break; + case blink::MacSystemColorID::kControlHighlight: + values[i] = NSColorToSkColor([NSColor controlHighlightColor]); + break; + case blink::MacSystemColorID::kControlLightHighlight: + values[i] = NSColorToSkColor([NSColor controlLightHighlightColor]); + break; + case blink::MacSystemColorID::kControlShadow: + values[i] = NSColorToSkColor([NSColor controlShadowColor]); + break; + case blink::MacSystemColorID::kControlText: + values[i] = NSColorToSkColor([NSColor controlTextColor]); + break; + case blink::MacSystemColorID::kDisabledControlText: + values[i] = NSColorToSkColor([NSColor disabledControlTextColor]); + break; + case blink::MacSystemColorID::kHeader: + values[i] = NSColorToSkColor([NSColor headerColor]); + break; + case blink::MacSystemColorID::kHighlight: + values[i] = NSColorToSkColor([NSColor highlightColor]); + break; + case blink::MacSystemColorID::kKeyboardFocusIndicator: + values[i] = NSColorToSkColor([NSColor keyboardFocusIndicatorColor]); + break; + case blink::MacSystemColorID::kMenuBackground: + values[i] = MenuBackgroundColor(); + break; + case blink::MacSystemColorID::kScrollBar: + values[i] = NSColorToSkColor([NSColor scrollBarColor]); + break; + case blink::MacSystemColorID::kSecondarySelectedControl: + values[i] = NSColorToSkColor([NSColor secondarySelectedControlColor]); + break; + case blink::MacSystemColorID::kSelectedMenuItemText: + values[i] = NSColorToSkColor([NSColor selectedMenuItemTextColor]); + break; + case blink::MacSystemColorID::kSelectedText: + values[i] = NSColorToSkColor([NSColor selectedTextColor]); + break; + case blink::MacSystemColorID::kSelectedTextBackground: + values[i] = NSColorToSkColor([NSColor selectedTextBackgroundColor]); + break; + case blink::MacSystemColorID::kShadow: + values[i] = NSColorToSkColor([NSColor shadowColor]); + break; + case blink::MacSystemColorID::kText: + values[i] = NSColorToSkColor([NSColor textColor]); + break; + case blink::MacSystemColorID::kWindowBackground: + values[i] = NSColorToSkColor([NSColor windowBackgroundColor]); + break; + case blink::MacSystemColorID::kWindowFrame: + values[i] = NSColorToSkColor([NSColor windowFrameColor]); + break; + case blink::MacSystemColorID::kWindowFrameText: + values[i] = NSColorToSkColor([NSColor windowFrameTextColor]); + break; + case blink::MacSystemColorID::kCount: + NOTREACHED(); + break; + } + } } void ThemeHelperMac::Observe(int type,
diff --git a/content/browser/webauth/authenticator_impl.cc b/content/browser/webauth/authenticator_impl.cc index 1c561ef..7568c4e 100644 --- a/content/browser/webauth/authenticator_impl.cc +++ b/content/browser/webauth/authenticator_impl.cc
@@ -666,10 +666,12 @@ options->authenticator_selection) : device::AuthenticatorSelectionCriteria(); + auto ctap_request = CreateCtapMakeCredentialRequest( + client_data_json_, options, individual_attestation); + ctap_request.set_is_u2f_only(OriginIsCryptoTokenExtension(caller_origin)); + request_ = std::make_unique<device::MakeCredentialRequestHandler>( - connector_, transports_, - CreateCtapMakeCredentialRequest(client_data_json_, options, - individual_attestation), + connector_, transports_, std::move(ctap_request), std::move(authenticator_selection_criteria), base::BindOnce(&AuthenticatorImpl::OnRegisterResponse, weak_factory_.GetWeakPtr())); @@ -777,7 +779,6 @@ auto ctap_request = CreateCtapGetAssertionRequest(client_data_json_, std::move(options), alternative_application_parameter_); - auto opt_platform_authenticator_info = CreatePlatformAuthenticatorIfAvailableAndCheckIfCredentialExists( ctap_request);
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc index 50da7ebb..c89d947 100644 --- a/content/browser/webauth/authenticator_impl_unittest.cc +++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -769,6 +769,46 @@ } } +// Requests originating from cryptotoken should only target U2F devices. +TEST_F(AuthenticatorImplTest, CryptoTokenU2fOnly) { + EnableFeature(device::kWebAuthProxyCryptotoken); + constexpr char kCryptotokenOrigin[] = + "chrome-extension://kmendfapggjehodndflmmgagdbamhnfd"; + TestServiceManagerContext smc; + SimulateNavigation(GURL(kTestOrigin1)); + auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>( + base::Time::Now(), base::TimeTicks::Now()); + auto authenticator = ConstructAuthenticatorWithTimer(task_runner); + url::AddStandardScheme("chrome-extension", url::SCHEME_WITH_HOST); + + // TODO(martinkr): ScopedVirtualFidoDevice does not offer devices that + // support both U2F and CTAP yet; we should test those. + for (const bool u2f_authenticator : {true, false}) { + SCOPED_TRACE(u2f_authenticator ? "U2F" : "CTAP"); + OverrideLastCommittedOrigin(main_rfh(), + url::Origin::Create(GURL(kCryptotokenOrigin))); + + device::test::ScopedVirtualFidoDevice scoped_virtual_device; + scoped_virtual_device.SetSupportedProtocol( + u2f_authenticator ? device::ProtocolVersion::kU2f + : device::ProtocolVersion::kCtap); + + PublicKeyCredentialCreationOptionsPtr options = + GetTestPublicKeyCredentialCreationOptions(); + TestMakeCredentialCallback callback_receiver; + authenticator->MakeCredential(std::move(options), + callback_receiver.callback()); + + base::RunLoop().RunUntilIdle(); + task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1)); + callback_receiver.WaitForCallback(); + + EXPECT_EQ((u2f_authenticator ? AuthenticatorStatus::SUCCESS + : AuthenticatorStatus::NOT_ALLOWED_ERROR), + callback_receiver.status()); + } +} + // Verify that a credential registered with U2F can be used via webauthn. TEST_F(AuthenticatorImplTest, AppIdExtension) { SimulateNavigation(GURL(kTestOrigin1));
diff --git a/content/child/child_process_sandbox_support_impl_mac.cc b/content/child/child_process_sandbox_support_impl_mac.cc index 0cd80ca2..8f50309 100644 --- a/content/child/child_process_sandbox_support_impl_mac.cc +++ b/content/child/child_process_sandbox_support_impl_mac.cc
@@ -12,11 +12,27 @@ #include "base/strings/sys_string_conversions.h" #include "content/common/mac/font_loader.h" #include "content/public/child/child_thread.h" +#include "content/public/common/service_names.mojom.h" #include "mojo/public/cpp/system/buffer.h" +#include "services/service_manager/public/cpp/connector.h" namespace content { -bool LoadFont(CTFontRef font, CGFontRef* out, uint32_t* font_id) { +WebSandboxSupportMac::WebSandboxSupportMac( + service_manager::Connector* connector) { + connector->BindInterface(content::mojom::kBrowserServiceName, + mojo::MakeRequest(&sandbox_support_)); + sandbox_support_->GetSystemColors(base::BindOnce( + &WebSandboxSupportMac::OnGotSystemColors, base::Unretained(this))); +} + +WebSandboxSupportMac::~WebSandboxSupportMac() = default; + +// TODO(rsesek): Move font loading off the content.mojom.FontLoaderMac +// interface and onto the SandboxSupportMac interface. +bool WebSandboxSupportMac::LoadFont(CTFontRef font, + CGFontRef* out, + uint32_t* font_id) { base::ScopedCFTypeRef<CFStringRef> name_ref(CTFontCopyPostScriptName(font)); base::string16 font_name = SysCFStringRefToUTF16(name_ref); float font_point_size = CTFontGetSize(font); @@ -42,4 +58,19 @@ std::move(font_data), static_cast<uint32_t>(font_data_size), out); } +SkColor WebSandboxSupportMac::GetSystemColor(blink::MacSystemColorID color_id) { + if (!color_map_.IsValid()) { + DLOG(ERROR) << "GetSystemColor does not have a valid color_map_"; + return SK_ColorMAGENTA; + } + base::span<const SkColor> color_map = + color_map_.GetMemoryAsSpan<SkColor>(blink::kMacSystemColorIDCount); + return color_map[static_cast<size_t>(color_id)]; +} + +void WebSandboxSupportMac::OnGotSystemColors( + base::ReadOnlySharedMemoryRegion region) { + color_map_ = region.Map(); +} + } // namespace content
diff --git a/content/child/child_process_sandbox_support_impl_mac.h b/content/child/child_process_sandbox_support_impl_mac.h index 53cdad1d..b9e53e1 100644 --- a/content/child/child_process_sandbox_support_impl_mac.h +++ b/content/child/child_process_sandbox_support_impl_mac.h
@@ -7,11 +7,37 @@ #include <CoreText/CoreText.h> +#include "base/memory/read_only_shared_memory_region.h" +#include "base/memory/shared_memory_mapping.h" +#include "content/common/sandbox_support_mac.mojom.h" +#include "third_party/blink/public/platform/mac/web_sandbox_support.h" + +namespace service_manager { +class Connector; +} + namespace content { -// Load a font specified by |font| into |out| through communicating -// with browser. -bool LoadFont(CTFontRef font, CGFontRef* out, uint32_t* font_id); +// Implementation of the interface used by Blink to upcall to the privileged +// process (browser) for handling requests for data that are not allowed within +// the sandbox. +class WebSandboxSupportMac : public blink::WebSandboxSupport { + public: + explicit WebSandboxSupportMac(service_manager::Connector* connector); + ~WebSandboxSupportMac() override; + + // blink::WebSandboxSupport: + bool LoadFont(CTFontRef font, CGFontRef* out, uint32_t* font_id) override; + SkColor GetSystemColor(blink::MacSystemColorID color_id) override; + + private: + void OnGotSystemColors(base::ReadOnlySharedMemoryRegion region); + + mojom::SandboxSupportMacPtr sandbox_support_; + base::ReadOnlySharedMemoryMapping color_map_; + + DISALLOW_COPY_AND_ASSIGN(WebSandboxSupportMac); +}; }; // namespace content
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 5bbf50e..e1ef617 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -436,6 +436,8 @@ WebRuntimeFeatures::EnableIsolatedCodeCache( base::FeatureList::IsEnabled(net::features::kIsolatedCodeCache)); + WebRuntimeFeatures::EnableWasmCodeCache( + base::FeatureList::IsEnabled(blink::features::kWasmCodeCache)); if (base::FeatureList::IsEnabled(features::kSignedHTTPExchange)) { WebRuntimeFeatures::EnableSignedHTTPExchange(true);
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index ad5e640..90ef93f 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -548,6 +548,7 @@ sources += [ "font_loader_mac.mojom", "render_widget_host_ns_view.mojom", + "sandbox_support_mac.mojom", ] }
diff --git a/content/common/content_param_traits.cc b/content/common/content_param_traits.cc index 80d00d2..78b7421 100644 --- a/content/common/content_param_traits.cc +++ b/content/common/content_param_traits.cc
@@ -211,6 +211,7 @@ WriteParam(m, p->data.stack_trace_debugger_id_first); WriteParam(m, p->data.stack_trace_debugger_id_second); WriteParam(m, p->data.ports); + WriteParam(m, p->data.stream_channels); WriteParam(m, p->data.has_user_gesture); WriteParam(m, !!p->data.user_activation); if (p->data.user_activation) { @@ -241,6 +242,7 @@ !ReadParam(m, iter, &(*r)->data.stack_trace_debugger_id_first) || !ReadParam(m, iter, &(*r)->data.stack_trace_debugger_id_second) || !ReadParam(m, iter, &(*r)->data.ports) || + !ReadParam(m, iter, &(*r)->data.stream_channels) || !ReadParam(m, iter, &(*r)->data.has_user_gesture) || !ReadParam(m, iter, &has_activation)) { return false;
diff --git a/content/common/sandbox_support_mac.mojom b/content/common/sandbox_support_mac.mojom new file mode 100644 index 0000000..86b5a5e --- /dev/null +++ b/content/common/sandbox_support_mac.mojom
@@ -0,0 +1,15 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module content.mojom; + +import "mojo/public/mojom/base/shared_memory.mojom"; + +// Interface for a sandboxed child process to request services of +// the browser. +interface SandboxSupportMac { + // Returns the shared memory region containing system theme color + // information. + GetSystemColors() => (mojo_base.mojom.ReadOnlySharedMemoryRegion region); +};
diff --git a/content/common/service_manager/service_manager_connection_impl.cc b/content/common/service_manager/service_manager_connection_impl.cc index 95426e0..b4954002 100644 --- a/content/common/service_manager/service_manager_connection_impl.cc +++ b/content/common/service_manager/service_manager_connection_impl.cc
@@ -69,6 +69,12 @@ io_thread_checker_.DetachFromThread(); } + void SetDefaultServiceRequestHandler( + const ServiceManagerConnection::DefaultServiceRequestHandler& handler) { + DCHECK(!started_); + default_request_handler_ = handler; + } + // Safe to call from any thread. void Start(const base::Closure& stop_callback) { DCHECK(!started_); @@ -312,15 +318,24 @@ DCHECK(io_thread_checker_.CalledOnValidThread()); auto it = request_handlers_.find(name); if (it == request_handlers_.end()) { - LOG(ERROR) << "Can't create service " << name << ". No handler found."; - return; + if (default_request_handler_) { + callback_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(default_request_handler_, name, std::move(request))); + } else { + LOG(ERROR) << "Can't create service " << name << ". No handler found."; + } + } else { + it->second.Run(std::move(request), std::move(pid_receiver)); } - it->second.Run(std::move(request), std::move(pid_receiver)); } base::ThreadChecker io_thread_checker_; bool started_ = false; + ServiceManagerConnection::DefaultServiceRequestHandler + default_request_handler_; + // Temporary state established on construction and consumed on the IO thread // once the connection is started. service_manager::mojom::ServiceRequest pending_service_request_; @@ -475,6 +490,11 @@ context_->AddServiceRequestHandlerWithPID(name, handler); } +void ServiceManagerConnectionImpl::SetDefaultServiceRequestHandler( + const DefaultServiceRequestHandler& handler) { + context_->SetDefaultServiceRequestHandler(handler); +} + void ServiceManagerConnectionImpl::OnConnectionLost() { if (!connection_lost_handler_.is_null()) connection_lost_handler_.Run();
diff --git a/content/common/service_manager/service_manager_connection_impl.h b/content/common/service_manager/service_manager_connection_impl.h index e0f3c00..52a4b28 100644 --- a/content/common/service_manager/service_manager_connection_impl.h +++ b/content/common/service_manager/service_manager_connection_impl.h
@@ -49,6 +49,8 @@ void AddServiceRequestHandlerWithPID( const std::string& name, const ServiceRequestHandlerWithPID& handler) override; + void SetDefaultServiceRequestHandler( + const DefaultServiceRequestHandler& handler) override; void OnConnectionLost(); void GetInterface(service_manager::mojom::InterfaceProvider* provider,
diff --git a/content/ppapi_plugin/ppapi_blink_platform_impl.cc b/content/ppapi_plugin/ppapi_blink_platform_impl.cc index 74cc14d6..cb94a69 100644 --- a/content/ppapi_plugin/ppapi_blink_platform_impl.cc +++ b/content/ppapi_plugin/ppapi_blink_platform_impl.cc
@@ -19,7 +19,7 @@ #include "third_party/blink/public/platform/web_string.h" #if defined(OS_MACOSX) -#include "third_party/blink/public/platform/mac/web_sandbox_support.h" +#include "content/child/child_process_sandbox_support_impl_mac.h" #elif defined(OS_POSIX) && !defined(OS_ANDROID) #include "content/child/child_process_sandbox_support_impl_linux.h" #include "third_party/blink/public/platform/linux/out_of_process_font.h" @@ -36,19 +36,14 @@ namespace content { -#if !defined(OS_ANDROID) && !defined(OS_WIN) +#if defined(OS_LINUX) class PpapiBlinkPlatformImpl::SandboxSupport : public WebSandboxSupport { public: -#if defined(OS_LINUX) explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader) : font_loader_(std::move(font_loader)) {} -#endif ~SandboxSupport() override {} -#if defined(OS_MACOSX) - bool LoadFont(CTFontRef srcFont, CGFontRef* out, uint32_t* fontID) override; -#elif defined(OS_LINUX) SandboxSupport(); void GetFallbackFontForCharacter( WebUChar32 character, @@ -72,23 +67,8 @@ sk_sp<font_service::FontLoader> font_loader_; // For debugging https://crbug.com/312965 base::SequenceCheckerImpl creation_thread_sequence_checker_; -#endif }; -#if defined(OS_MACOSX) - -bool PpapiBlinkPlatformImpl::SandboxSupport::LoadFont(CTFontRef src_font, - CGFontRef* out, - uint32_t* font_id) { - // TODO(brettw) this should do the something similar to what - // RendererBlinkPlatformImpl does and request that the browser load the font. - // Note: need to unlock the proxy lock like ensureFontLoaded does. - NOTIMPLEMENTED(); - return false; -} - -#elif defined(OS_POSIX) - PpapiBlinkPlatformImpl::SandboxSupport::SandboxSupport() {} void PpapiBlinkPlatformImpl::SandboxSupport::GetFallbackFontForCharacter( @@ -137,8 +117,6 @@ #endif -#endif // !defined(OS_ANDROID) && !defined(OS_WIN) - PpapiBlinkPlatformImpl::PpapiBlinkPlatformImpl() { #if defined(OS_LINUX) font_loader_ = @@ -147,7 +125,8 @@ sandbox_support_.reset( new PpapiBlinkPlatformImpl::SandboxSupport(font_loader_)); #elif defined(OS_MACOSX) - sandbox_support_.reset(new PpapiBlinkPlatformImpl::SandboxSupport()); + sandbox_support_.reset( + new WebSandboxSupportMac(ChildThread::Get()->GetConnector())); #endif } @@ -155,7 +134,7 @@ } void PpapiBlinkPlatformImpl::Shutdown() { -#if !defined(OS_ANDROID) && !defined(OS_WIN) +#if defined(OS_LINUX) || defined(OS_MACOSX) // SandboxSupport contains a map of OutOfProcessFont objects, which hold // WebStrings and WebVectors, which become invalidated when blink is shut // down. Hence, we need to clear that map now, just before blink::shutdown() @@ -165,7 +144,7 @@ } blink::WebSandboxSupport* PpapiBlinkPlatformImpl::GetSandboxSupport() { -#if !defined(OS_ANDROID) && !defined(OS_WIN) +#if defined(OS_LINUX) || defined(OS_MACOSX) return sandbox_support_.get(); #else return nullptr;
diff --git a/content/ppapi_plugin/ppapi_blink_platform_impl.h b/content/ppapi_plugin/ppapi_blink_platform_impl.h index 279b883..c6f4ddb 100644 --- a/content/ppapi_plugin/ppapi_blink_platform_impl.h +++ b/content/ppapi_plugin/ppapi_blink_platform_impl.h
@@ -42,12 +42,12 @@ bool sync_dir) override; private: -#if !defined(OS_ANDROID) && !defined(OS_WIN) - class SandboxSupport; - std::unique_ptr<SandboxSupport> sandbox_support_; +#if defined(OS_LINUX) || defined(OS_MACOSX) + std::unique_ptr<blink::WebSandboxSupport> sandbox_support_; #endif #if defined(OS_LINUX) + class SandboxSupport; sk_sp<font_service::FontLoader> font_loader_; #endif
diff --git a/content/public/android/java/src/org/chromium/content/browser/AppWebMessagePort.java b/content/public/android/java/src/org/chromium/content/browser/AppWebMessagePort.java index 17f92fad..94bc465 100644 --- a/content/public/android/java/src/org/chromium/content/browser/AppWebMessagePort.java +++ b/content/public/android/java/src/org/chromium/content/browser/AppWebMessagePort.java
@@ -256,6 +256,7 @@ msg.arrayBufferContentsArray = new SerializedArrayBufferContents[0]; msg.imageBitmapContentsArray = new Bitmap[0]; msg.ports = ports; + msg.streamChannels = new MessagePipeHandle[0]; mConnector.accept(msg.serializeWithHeader(mMojoCore, MESSAGE_HEADER)); }
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json index 6eec762..9c57623 100644 --- a/content/public/app/mojo/content_browser_manifest.json +++ b/content/public/app/mojo/content_browser_manifest.json
@@ -82,6 +82,9 @@ "viz.mojom.CompositingModeReporter", "ws.mojom.Gpu" ], + "sandbox_support": [ + "content.mojom.SandboxSupportMac" + ], "service_manager:service_factory": [ "service_manager.mojom.ServiceFactory" ]
diff --git a/content/public/app/mojo/content_plugin_manifest.json b/content/public/app/mojo/content_plugin_manifest.json index c00ea402..faa6fd9 100644 --- a/content/public/app/mojo/content_plugin_manifest.json +++ b/content/public/app/mojo/content_plugin_manifest.json
@@ -22,7 +22,8 @@ "dwrite_font_proxy", "field_trials", "font_cache", - "plugin" + "plugin", + "sandbox_support" ], "device": [ "device:power_monitor" ], "font_service": [ "font_service" ],
diff --git a/content/public/app/mojo/content_renderer_manifest.json b/content/public/app/mojo/content_renderer_manifest.json index e19c5e68..4fb7c65 100644 --- a/content/public/app/mojo/content_renderer_manifest.json +++ b/content/public/app/mojo/content_renderer_manifest.json
@@ -33,7 +33,8 @@ "dwrite_font_proxy", "field_trials", "font_loader", - "renderer" + "renderer", + "sandbox_support" ], "font_service": [ "font_service" ], "metrics": [ "url_keyed_metrics" ],
diff --git a/content/public/app/mojo/content_utility_manifest.json b/content/public/app/mojo/content_utility_manifest.json index 2c4dcb1..bb410686 100644 --- a/content/public/app/mojo/content_utility_manifest.json +++ b/content/public/app/mojo/content_utility_manifest.json
@@ -24,7 +24,8 @@ "content_browser": [ "dwrite_font_proxy", "field_trials", - "font_cache" + "font_cache", + "sandbox_support" ], "device": [ "device:power_monitor",
diff --git a/content/public/browser/browser_context.h b/content/public/browser/browser_context.h index 777d4d6..b6181e5 100644 --- a/content/public/browser/browser_context.h +++ b/content/public/browser/browser_context.h
@@ -22,6 +22,7 @@ #include "net/url_request/url_request_job_factory.h" #include "services/network/public/mojom/cors_origin_pattern.mojom.h" #include "services/service_manager/public/cpp/embedded_service_info.h" +#include "services/service_manager/public/mojom/service.mojom.h" #include "third_party/blink/public/mojom/blob/blob.mojom.h" #if !defined(OS_ANDROID) @@ -41,6 +42,7 @@ namespace service_manager { class Connector; +class Service; } namespace storage { @@ -338,6 +340,12 @@ // by the Service Manager. virtual void RegisterInProcessServices(StaticServiceMap* services) {} + // Handles a service request for a service expected to run an instance per + // BrowserContext. + virtual std::unique_ptr<service_manager::Service> HandleServiceRequest( + const std::string& service_name, + service_manager::mojom::ServiceRequest request); + // Returns a unique string associated with this browser context. virtual const std::string& UniqueId() const;
diff --git a/content/public/common/service_manager_connection.h b/content/public/common/service_manager_connection.h index 193af7a..a2a3e8e 100644 --- a/content/public/common/service_manager_connection.h +++ b/content/public/common/service_manager_connection.h
@@ -125,6 +125,14 @@ virtual void AddServiceRequestHandlerWithPID( const std::string& name, const ServiceRequestHandlerWithPID& handler) = 0; + + // Sets a request handler to use if no registered handlers were interested in + // an incoming service request. Must be called before |Start()|. + using DefaultServiceRequestHandler = + base::RepeatingCallback<void(const std::string& service_name, + service_manager::mojom::ServiceRequest)>; + virtual void SetDefaultServiceRequestHandler( + const DefaultServiceRequestHandler& handler) = 0; }; } // namespace content
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc index e181340..ef173c2c 100644 --- a/content/public/test/mock_render_process_host.cc +++ b/content/public/test/mock_render_process_host.cc
@@ -400,8 +400,11 @@ resource_coordinator::ProcessResourceCoordinator* MockRenderProcessHost::GetProcessResourceCoordinator() { if (!process_resource_coordinator_) { + content::ServiceManagerConnection* connection = + content::ServiceManagerConnection::GetForProcess(); + // Tests may not set up a connection. service_manager::Connector* connector = - content::ServiceManagerConnection::GetForProcess()->GetConnector(); + connection ? connection->GetConnector() : nullptr; process_resource_coordinator_ = std::make_unique<resource_coordinator::ProcessResourceCoordinator>( connector);
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 6cb3021..4546847 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -691,6 +691,7 @@ "//third_party/libyuv", "//third_party/opus", "//third_party/sqlite", + "//third_party/webrtc/api:create_peerconnection_factory", "//third_party/webrtc/api:libjingle_logging_api", "//third_party/webrtc/api:libjingle_peerconnection_api", "//third_party/webrtc/api:rtc_stats_api",
diff --git a/content/renderer/OWNERS b/content/renderer/OWNERS index 63ad4d3..d9f1b9b 100644 --- a/content/renderer/OWNERS +++ b/content/renderer/OWNERS
@@ -20,3 +20,9 @@ per-file child_frame_compositor*=fsamuel@chromium.org per-file child_frame_compositing_helper*=fsamuel@chromium.org per-file render_frame_metadata*=fsamuel@chromium.org +per-file render_frame_proxy*=samans@chromium.org +per-file render_view_impl*=samans@chromium.org +per-file render_widget*=samans@chromium.org +per-file child_frame_compositor*=samans@chromium.org +per-file child_frame_compositing_helper*=samans@chromium.org +per-file render_frame_metadata*=samans@chromium.org
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc index 6fc630a..20a771f 100644 --- a/content/renderer/accessibility/render_accessibility_impl.cc +++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -685,6 +685,8 @@ case ax::mojom::Action::kNone: NOTREACHED(); break; + case ax::mojom::Action::kGetTextLocation: + break; } }
diff --git a/content/renderer/gpu/OWNERS b/content/renderer/gpu/OWNERS index 83153f2..9147699 100644 --- a/content/renderer/gpu/OWNERS +++ b/content/renderer/gpu/OWNERS
@@ -6,5 +6,6 @@ # For surface synchronization fsamuel@chromium.org +samans@chromium.org # COMPONENT: Internals>Compositing
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc index 0c67b3d..aa11481 100644 --- a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc +++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -62,6 +62,7 @@ #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/webrtc/api/create_peerconnection_factory.h" #include "third_party/webrtc/api/mediaconstraintsinterface.h" #include "third_party/webrtc/api/video_codecs/video_decoder_factory.h" #include "third_party/webrtc/api/video_codecs/video_encoder_factory.h"
diff --git a/content/renderer/media/webrtc/webrtc_video_utils.cc b/content/renderer/media/webrtc/webrtc_video_utils.cc index 0c7662f4..3b63e67 100644 --- a/content/renderer/media/webrtc/webrtc_video_utils.cc +++ b/content/renderer/media/webrtc/webrtc_video_utils.cc
@@ -59,7 +59,6 @@ case webrtc::ColorSpace::PrimaryID::kJEDECP22: primaries = media::VideoColorSpace::PrimaryID::EBU_3213_E; break; - case webrtc::ColorSpace::PrimaryID::kInvalid: default: break; } @@ -115,7 +114,6 @@ case webrtc::ColorSpace::TransferID::kARIB_STD_B67: transfer = media::VideoColorSpace::TransferID::ARIB_STD_B67; break; - case webrtc::ColorSpace::TransferID::kInvalid: default: break; } @@ -153,7 +151,6 @@ case webrtc::ColorSpace::MatrixID::kSMPTE2085: matrix = media::VideoColorSpace::MatrixID::YDZDX; break; - case webrtc::ColorSpace::MatrixID::kInvalid: default: break; } @@ -166,7 +163,6 @@ case webrtc::ColorSpace::RangeID::kFull: range = gfx::ColorSpace::RangeID::FULL; break; - case webrtc::ColorSpace::RangeID::kInvalid: default: break; }
diff --git a/content/renderer/pepper/pepper_file_chooser_host.cc b/content/renderer/pepper/pepper_file_chooser_host.cc index e7b5157d..84fb620f 100644 --- a/content/renderer/pepper/pepper_file_chooser_host.cc +++ b/content/renderer/pepper/pepper_file_chooser_host.cc
@@ -47,20 +47,22 @@ } void DidChooseFiles(blink::mojom::FileChooserResultPtr result) { - DCHECK(result); if (host_.get()) { - std::vector<blink::mojom::FileChooserFileInfoPtr> mojo_files = - std::move(result->files); std::vector<PepperFileChooserHost::ChosenFileInfo> files; - for (size_t i = 0; i < mojo_files.size(); i++) { - base::FilePath file_path = mojo_files[i]->get_native_file()->file_path; - // Drop files of which names can not be converted to Unicode. We - // can't expose such files in Flash. - if (blink::FilePathToWebString(file_path).IsEmpty()) - continue; - files.push_back(PepperFileChooserHost::ChosenFileInfo( - file_path, - base::UTF16ToUTF8(mojo_files[i]->get_native_file()->display_name))); + if (result) { + std::vector<blink::mojom::FileChooserFileInfoPtr> mojo_files = + std::move(result->files); + for (size_t i = 0; i < mojo_files.size(); i++) { + base::FilePath file_path = + mojo_files[i]->get_native_file()->file_path; + // Drop files of which names can not be converted to Unicode. We + // can't expose such files in Flash. + if (blink::FilePathToWebString(file_path).IsEmpty()) + continue; + files.push_back(PepperFileChooserHost::ChosenFileInfo( + file_path, base::UTF16ToUTF8( + mojo_files[i]->get_native_file()->display_name))); + } } host_->StoreChosenFiles(files); }
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 0a22404..d80d269 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -112,7 +112,6 @@ #if defined(OS_MACOSX) #include "content/child/child_process_sandbox_support_impl_mac.h" #include "content/common/mac/font_loader.h" -#include "third_party/blink/public/platform/mac/web_sandbox_support.h" #endif #if defined(OS_POSIX) @@ -194,21 +193,14 @@ //------------------------------------------------------------------------------ -#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_FUCHSIA) +#if defined(OS_LINUX) class RendererBlinkPlatformImpl::SandboxSupport : public blink::WebSandboxSupport { public: -#if defined(OS_LINUX) explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader) : font_loader_(std::move(font_loader)) {} -#endif ~SandboxSupport() override {} -#if defined(OS_MACOSX) - bool LoadFont(CTFontRef src_font, - CGFontRef* container, - uint32_t* font_id) override; -#elif defined(OS_LINUX) void GetFallbackFontForCharacter( blink::WebUChar32 character, const char* preferred_locale, @@ -230,9 +222,8 @@ base::Lock unicode_font_families_mutex_; std::map<int32_t, blink::OutOfProcessFont> unicode_font_families_; sk_sp<font_service::FontLoader> font_loader_; -#endif }; -#endif // !defined(OS_ANDROID) && !defined(OS_WIN) +#endif // defined(OS_LINUX) //------------------------------------------------------------------------------ @@ -265,10 +256,10 @@ connector_ = service_manager::Connector::Create(&request); } -#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_FUCHSIA) +#if defined(OS_LINUX) || defined(OS_MACOSX) if (g_sandbox_enabled && sandboxEnabled()) { #if defined(OS_MACOSX) - sandbox_support_.reset(new RendererBlinkPlatformImpl::SandboxSupport()); + sandbox_support_.reset(new WebSandboxSupportMac(connector_.get())); #else sandbox_support_.reset( new RendererBlinkPlatformImpl::SandboxSupport(font_loader_)); @@ -294,7 +285,7 @@ } void RendererBlinkPlatformImpl::Shutdown() { -#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_FUCHSIA) +#if defined(OS_LINUX) || defined(OS_MACOSX) // SandboxSupport contains a map of OutOfProcessFont objects, which hold // WebStrings and WebVectors, which become invalidated when blink is shut // down. Hence, we need to clear that map now, just before blink::shutdown() @@ -388,11 +379,11 @@ } blink::WebSandboxSupport* RendererBlinkPlatformImpl::GetSandboxSupport() { -#if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_FUCHSIA) - // These platforms do not require sandbox support. - return NULL; -#else +#if defined(OS_LINUX) || defined(OS_MACOSX) return sandbox_support_.get(); +#else + // These platforms do not require sandbox support. + return nullptr; #endif } @@ -569,15 +560,7 @@ //------------------------------------------------------------------------------ -#if defined(OS_MACOSX) - -bool RendererBlinkPlatformImpl::SandboxSupport::LoadFont(CTFontRef src_font, - CGFontRef* out, - uint32_t* font_id) { - return content::LoadFont(src_font, out, font_id); -} - -#elif defined(OS_POSIX) && !defined(OS_ANDROID) +#if defined(OS_LINUX) void RendererBlinkPlatformImpl::SandboxSupport::GetFallbackFontForCharacter( blink::WebUChar32 character,
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index d12e1fc..63e86af 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -264,9 +264,8 @@ std::unique_ptr<service_manager::Connector> connector_; scoped_refptr<base::SingleThreadTaskRunner> io_runner_; -#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_FUCHSIA) - class SandboxSupport; - std::unique_ptr<SandboxSupport> sandbox_support_; +#if defined(OS_LINUX) || defined(OS_MACOSX) + std::unique_ptr<blink::WebSandboxSupport> sandbox_support_; #endif // This counter keeps track of the number of times sudden termination is @@ -301,6 +300,7 @@ scoped_refptr<blink::mojom::ThreadSafeCodeCacheHostPtr> code_cache_host_; #if defined(OS_LINUX) + class SandboxSupport; sk_sp<font_service::FontLoader> font_loader_; #endif
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 8264df1..5b5f30a 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1974,7 +1974,6 @@ ] data_deps = [ - "//components/services/filesystem:filesystem", "//testing/buildbot/filters:content_unittests_filters", "//third_party/mesa_headers", ]
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index 9bebf62..4500ad3b 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -970,6 +970,8 @@ ['linux', ('nvidia', 0x1cb3)], bug=780706) self.Flaky('conformance2/rendering/canvas-resizing-with-pbo-bound.html', ['linux', 'nvidia'], bug=906846) + self.Flaky('conformance2/rendering/blitframebuffer-test.html', + ['linux', 'nvidia'], bug=906889) # Linux NVIDIA Quadro P400, OpenGL backend self.Fail('conformance/limits/gl-max-texture-dimensions.html',
diff --git a/content/utility/utility_blink_platform_with_sandbox_support_impl.cc b/content/utility/utility_blink_platform_with_sandbox_support_impl.cc index 84cd39b..f5a34a53 100644 --- a/content/utility/utility_blink_platform_with_sandbox_support_impl.cc +++ b/content/utility/utility_blink_platform_with_sandbox_support_impl.cc
@@ -9,8 +9,7 @@ #if defined(OS_MACOSX) #include "base/mac/foundation_util.h" #include "content/child/child_process_sandbox_support_impl_mac.h" -#include "third_party/blink/public/platform/mac/web_sandbox_support.h" -#elif defined(OS_POSIX) && !defined(OS_ANDROID) +#elif defined(OS_LINUX) #include "base/synchronization/lock.h" #include "content/child/child_process_sandbox_support_impl_linux.h" #include "content/child/child_thread_impl.h" @@ -27,20 +26,15 @@ namespace content { -#if defined(OS_POSIX) && !defined(OS_ANDROID) +#if defined(OS_LINUX) class UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport : public blink::WebSandboxSupport { public: -#if defined(OS_LINUX) explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader) : font_loader_(std::move(font_loader)) {} -#endif ~SandboxSupport() override {} -#if defined(OS_MACOSX) - bool LoadFont(CTFontRef srcFont, CGFontRef* out, uint32_t* fontID) override; -#else void GetFallbackFontForCharacter( blink::WebUChar32 character, const char* preferred_locale, @@ -63,10 +57,9 @@ // Maps unicode chars to their fallback fonts. std::map<int32_t, blink::OutOfProcessFont> unicode_font_families_; sk_sp<font_service::FontLoader> font_loader_; -#endif // defined(OS_MACOSX) }; -#endif // defined(OS_POSIX) && !defined(OS_ANDROID) +#endif // defined(OS_LINUX) UtilityBlinkPlatformWithSandboxSupportImpl:: UtilityBlinkPlatformWithSandboxSupportImpl( @@ -76,7 +69,7 @@ SkFontConfigInterface::SetGlobal(font_loader_); sandbox_support_ = std::make_unique<SandboxSupport>(font_loader_); #elif defined(OS_MACOSX) - sandbox_support_ = std::make_unique<SandboxSupport>(); + sandbox_support_ = std::make_unique<WebSandboxSupportMac>(connector); #endif } @@ -85,23 +78,14 @@ blink::WebSandboxSupport* UtilityBlinkPlatformWithSandboxSupportImpl::GetSandboxSupport() { -#if defined(OS_POSIX) && !defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_MACOSX) return sandbox_support_.get(); #else return nullptr; #endif } -#if defined(OS_MACOSX) - -bool UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport::LoadFont( - CTFontRef src_font, - CGFontRef* out, - uint32_t* font_id) { - return content::LoadFont(src_font, out, font_id); -} - -#elif defined(OS_POSIX) && !defined(OS_ANDROID) +#if defined(OS_LINUX) void UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport:: GetFallbackFontForCharacter(blink::WebUChar32 character,
diff --git a/content/utility/utility_blink_platform_with_sandbox_support_impl.h b/content/utility/utility_blink_platform_with_sandbox_support_impl.h index b2eb141c..29fe2de8 100644 --- a/content/utility/utility_blink_platform_with_sandbox_support_impl.h +++ b/content/utility/utility_blink_platform_with_sandbox_support_impl.h
@@ -11,7 +11,7 @@ #include "build/build_config.h" #include "third_party/blink/public/platform/platform.h" -#if defined(OS_POSIX) && !defined(OS_ANDROID) +#if defined(OS_LINUX) #include "components/services/font/public/cpp/font_loader.h" // nogncheck #include "third_party/skia/include/core/SkRefCnt.h" // nogncheck #endif @@ -39,11 +39,11 @@ blink::WebSandboxSupport* GetSandboxSupport() override; private: -#if defined(OS_POSIX) && !defined(OS_ANDROID) - class SandboxSupport; - std::unique_ptr<SandboxSupport> sandbox_support_; +#if defined(OS_LINUX) || defined(OS_MACOSX) + std::unique_ptr<blink::WebSandboxSupport> sandbox_support_; #endif #if defined(OS_LINUX) + class SandboxSupport; sk_sp<font_service::FontLoader> font_loader_; #endif
diff --git a/device/fido/ctap_make_credential_request.h b/device/fido/ctap_make_credential_request.h index cfe777c..eac90cf 100644 --- a/device/fido/ctap_make_credential_request.h +++ b/device/fido/ctap_make_credential_request.h
@@ -85,6 +85,9 @@ return pin_auth_; } + void set_is_u2f_only(bool is_u2f_only) { is_u2f_only_ = is_u2f_only; } + bool is_u2f_only() { return is_u2f_only_; } + private: std::string client_data_json_; std::array<uint8_t, kClientDataHashLength> client_data_hash_; @@ -101,6 +104,10 @@ // asserted to CTAP2 authenticators. bool hmac_secret_ = false; + // If true, instruct the request handler only to dispatch this request via + // U2F. + bool is_u2f_only_ = false; + base::Optional<std::vector<PublicKeyCredentialDescriptor>> exclude_list_; base::Optional<std::vector<uint8_t>> pin_auth_; base::Optional<uint8_t> pin_protocol_;
diff --git a/device/fido/make_credential_task.cc b/device/fido/make_credential_task.cc index 60c57978..1206da092 100644 --- a/device/fido/make_credential_task.cc +++ b/device/fido/make_credential_task.cc
@@ -25,10 +25,11 @@ // is not required and the device supports U2F protocol. // TODO(hongjunchoi): Remove this once ClientPin command is implemented. // See: https://crbug.com/870892 -bool IsClientPinOptionCompatible(const FidoDevice* device, - const CtapMakeCredentialRequest& request) { +bool ShouldUseU2fBecauseCtapRequiresClientPin( + const FidoDevice* device, + const CtapMakeCredentialRequest& request) { if (request.user_verification() == UserVerificationRequirement::kRequired) - return true; + return false; DCHECK(device && device->device_info()); bool client_pin_set = @@ -36,7 +37,7 @@ AuthenticatorSupportedOptions::ClientPinAvailability::kSupportedAndPinSet; bool supports_u2f = base::ContainsKey(device->device_info()->versions(), ProtocolVersion::kU2f); - return !client_pin_set || !supports_u2f; + return client_pin_set && supports_u2f; } } // namespace @@ -55,7 +56,8 @@ void MakeCredentialTask::StartTask() { if (base::FeatureList::IsEnabled(kNewCtap2Device) && device()->supported_protocol() == ProtocolVersion::kCtap && - IsClientPinOptionCompatible(device(), request_parameter_)) { + !request_parameter_.is_u2f_only() && + !ShouldUseU2fBecauseCtapRequiresClientPin(device(), request_parameter_)) { MakeCredential(); } else { device()->set_supported_protocol(ProtocolVersion::kU2f);
diff --git a/device/fido/make_credential_task_unittest.cc b/device/fido/make_credential_task_unittest.cc index 75ec372..a63a2727 100644 --- a/device/fido/make_credential_task_unittest.cc +++ b/device/fido/make_credential_task_unittest.cc
@@ -187,5 +187,32 @@ EXPECT_FALSE(make_credential_callback_receiver().value()); } +TEST_F(FidoMakeCredentialTaskTest, TestU2fOnly) { + // Regardless of the device's supported protocol, it should receive a U2F + // request, because the task is instantiated in U2F-only mode. + auto device = MockFidoDevice::MakeCtap(); + + device->ExpectRequestAndRespondWith( + test_data::kU2fRegisterCommandApdu, + test_data::kApduEncodedNoErrorRegisterResponse); + + PublicKeyCredentialRpEntity rp(test_data::kRelyingPartyId); + PublicKeyCredentialUserEntity user( + fido_parsing_utils::Materialize(test_data::kUserId)); + auto request = CtapMakeCredentialRequest( + test_data::kClientDataJson, std::move(rp), std::move(user), + PublicKeyCredentialParams( + std::vector<PublicKeyCredentialParams::CredentialInfo>(1))); + request.set_is_u2f_only(true); + const auto task = std::make_unique<MakeCredentialTask>( + device.get(), std::move(request), callback_receiver_.callback()); + make_credential_callback_receiver().WaitForCallback(); + + EXPECT_EQ(CtapDeviceResponseCode::kSuccess, + make_credential_callback_receiver().status()); + EXPECT_TRUE(make_credential_callback_receiver().value()); + EXPECT_EQ(device->supported_protocol(), ProtocolVersion::kU2f); +} + } // namespace } // namespace device
diff --git a/device/fido/win/authenticator.cc b/device/fido/win/authenticator.cc index e630d97..4a09e40 100644 --- a/device/fido/win/authenticator.cc +++ b/device/fido/win/authenticator.cc
@@ -191,7 +191,7 @@ WEBAUTHN_CREDENTIALS{ 0, nullptr}, // Ignored because pExcludeCredentialList is set. WEBAUTHN_EXTENSIONS{extensions.size(), extensions.data()}, - use_u2f_only_ + request.is_u2f_only() ? WEBAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM_U2F_V2 : ToWinAuthenticatorAttachment(request.authenticator_attachment()), request.resident_key_required(), @@ -279,6 +279,15 @@ static BOOL kUseAppIdTrue = TRUE; // const base::string16 rp_id16 = base::UTF8ToUTF16(request.rp_id()); + base::Optional<base::string16> opt_app_id16 = base::nullopt; + // TODO(martinkr): alternative_application_parameter() is already hashed, + // so this doesn't work. We need to make it store the full AppID. + if (request.alternative_application_parameter()) { + opt_app_id16 = base::UTF8ToUTF16(base::StringPiece( + reinterpret_cast<const char*>( + request.alternative_application_parameter()->data()), + request.alternative_application_parameter()->size())); + } WEBAUTHN_CLIENT_DATA client_data{ WEBAUTHN_CLIENT_DATA_CURRENT_VERSION, request.client_data_json().size(), @@ -299,12 +308,11 @@ 0, nullptr}, // Ignored because pAllowCredentialList is set. WEBAUTHN_EXTENSIONS{0, nullptr}, // Note that attachment is effectively restricted via |allow_list|. - use_u2f_only_ ? WEBAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM_U2F_V2 - : WEBAUTHN_AUTHENTICATOR_ATTACHMENT_ANY, + WEBAUTHN_AUTHENTICATOR_ATTACHMENT_ANY, ToWinUserVerificationRequirement(request.user_verification()), - 0, // flags - use_u2f_only_ ? rp_id16.c_str() : nullptr, // pwszU2fAppId - use_u2f_only_ ? &kUseAppIdTrue : nullptr, // pbU2fAppId + 0, // flags + opt_app_id16 ? opt_app_id16->c_str() : nullptr, // pwszU2fAppId + opt_app_id16 ? &kUseAppIdTrue : nullptr, // pbU2fAppId &cancellation_id_, &allow_credential_list, };
diff --git a/device/fido/win/authenticator.h b/device/fido/win/authenticator.h index 899ed90..8c0f6b5 100644 --- a/device/fido/win/authenticator.h +++ b/device/fido/win/authenticator.h
@@ -32,19 +32,6 @@ WinWebAuthnApiAuthenticator(WinWebAuthnApi* win_api, HWND current_window); ~WinWebAuthnApiAuthenticator() override; - // Forces the Windows WebAuthn API not to communicate with CTAP2 devices for - // this request. Dual-protocol devices will use U2F. - // - // If enabled, the RP ID field of the request will be interpreted and used as - // an App ID instead. - // - // This method must not be called after any of the FidoAuthenticator - // interface methods have been invoked. - void enable_u2f_only_mode() { - DCHECK(!thread_); - use_u2f_only_ = true; - } - // FidoAuthenticator void InitializeAuthenticator(base::OnceClosure callback) override; void MakeCredential(CtapMakeCredentialRequest request, @@ -82,7 +69,6 @@ WinWebAuthnApi* win_api_; std::unique_ptr<base::Thread> thread_; HWND current_window_; - bool use_u2f_only_ = false; GUID cancellation_id_ = {}; base::AtomicFlag operation_cancelled_;
diff --git a/docs/adding_to_third_party.md b/docs/adding_to_third_party.md index 693a1cf..26b1c9fe 100644 --- a/docs/adding_to_third_party.md +++ b/docs/adding_to_third_party.md
@@ -136,10 +136,13 @@ sure to highlight risk to security@chromium.org. You may be asked to add a README.security or, in dangerous cases, README.SECURITY.URGENTLY file. * Add chromium-third-party@google.com as a reviewer on your change. This - will trigger an automatic round-robin assignment of the review to an - appropriate reviewer. This list does not receive or deliver email, so only - use it as a reviewer, not for other communication. (Internally, see - b/119558132 for details about how this is configured.) + will trigger an automatic round-robin assignment to a reviewer who will check + licensing matters. These reviewers may not be able to +1 a change so look for + verbal approval in the comments. (This list does not receive or deliver + email, so only use it as a reviewer, not for other communication. Internally, + see cl/221704656 for details about how this is configured.) +* Lastly, if all other steps are complete, get a positive code review from a + member of [//third_party/OWNERS](../third_party/OWNERS) to land the change. Please send separate emails to the eng review and security lists.
diff --git a/docs/infra/cq_builders.md b/docs/infra/cq_builders.md index 4a55b9c..f0497a6 100644 --- a/docs/infra/cq_builders.md +++ b/docs/infra/cq_builders.md
@@ -119,6 +119,16 @@ * [`//third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees`](https://cs.chromium.org/search/?q=package:%5Echromium$+file:third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees) * [`//third_party/WebKit/LayoutTests/flag-specific/enable-blink-gen-property-trees/.+`](https://cs.chromium.org/chromium/src/third_party/WebKit/LayoutTests/flag-specific/enable-blink-gen-property-trees/) +* [linux-blink-rel](https://ci.chromium.org/p/chromium/builders/luci.chromium.try/linux-blink-rel) ([`cq.cfg` entry](https://cs.chromium.org/search/?q=package:%5Echromium$+file:cq.cfg+linux-blink-rel)) ([matching builders](https://cs.chromium.org/search/?q=file:trybots.py+linux-blink-rel)) + + Path regular expressions: + * [`//cc/.+`](https://cs.chromium.org/chromium/src/cc/) + * [`//third_party/WebKit/LayoutTests/FlagExpectations/(enable-slimming-paint-v2|enable-blink-gen-property-trees)`](https://cs.chromium.org/search/?q=package:%5Echromium$+file:third_party/WebKit/LayoutTests/FlagExpectations/(enable-slimming-paint-v2|enable-blink-gen-property-trees)) + * [`//third_party/WebKit/LayoutTests/flag-specific/(enable-slimming-paint-v2|enable-blink-gen-property-trees)/.+`](https://cs.chromium.org/search/?q=package:%5Echromium$+file:third_party/WebKit/LayoutTests/flag-specific/(enable-slimming-paint-v2|enable-blink-gen-property-trees)/) + * [`//third_party/blink/renderer/core/layout/compositing/.+`](https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/layout/compositing/) + * [`//third_party/blink/renderer/core/(svg|paint)/.+`](https://cs.chromium.org/search/?q=package:%5Echromium$+file:third_party/blink/renderer/core/(svg|paint)/) + * [`//third_party/blink/renderer/platform/graphics/.+`](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/graphics/) + * [linux_chromium_dbg_ng](https://ci.chromium.org/p/chromium/builders/luci.chromium.try/linux_chromium_dbg_ng) ([`cq.cfg` entry](https://cs.chromium.org/search/?q=package:%5Echromium$+file:cq.cfg+linux_chromium_dbg_ng)) ([matching builders](https://cs.chromium.org/search/?q=file:trybots.py+linux_chromium_dbg_ng)) Path regular expressions: @@ -192,16 +202,6 @@ * [`//third_party/blink/renderer/platform/graphics/gpu/.+`](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/graphics/gpu/) * [`//ui/gl/.+`](https://cs.chromium.org/chromium/src/ui/gl/) -* [linux_trusty_blink_rel](https://ci.chromium.org/p/chromium/builders/luci.chromium.try/linux_trusty_blink_rel) ([`cq.cfg` entry](https://cs.chromium.org/search/?q=package:%5Echromium$+file:cq.cfg+linux_trusty_blink_rel)) ([matching builders](https://cs.chromium.org/search/?q=file:trybots.py+linux_trusty_blink_rel)) - - Path regular expressions: - * [`//cc/.+`](https://cs.chromium.org/chromium/src/cc/) - * [`//third_party/WebKit/LayoutTests/FlagExpectations/(enable-slimming-paint-v2|enable-blink-gen-property-trees)`](https://cs.chromium.org/search/?q=package:%5Echromium$+file:third_party/WebKit/LayoutTests/FlagExpectations/(enable-slimming-paint-v2|enable-blink-gen-property-trees)) - * [`//third_party/WebKit/LayoutTests/flag-specific/(enable-slimming-paint-v2|enable-blink-gen-property-trees)/.+`](https://cs.chromium.org/search/?q=package:%5Echromium$+file:third_party/WebKit/LayoutTests/flag-specific/(enable-slimming-paint-v2|enable-blink-gen-property-trees)/) - * [`//third_party/blink/renderer/core/layout/compositing/.+`](https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/layout/compositing/) - * [`//third_party/blink/renderer/core/(svg|paint)/.+`](https://cs.chromium.org/search/?q=package:%5Echromium$+file:third_party/blink/renderer/core/(svg|paint)/) - * [`//third_party/blink/renderer/platform/graphics/.+`](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/graphics/) - * [android_compile_x64_dbg](https://ci.chromium.org/p/chromium/builders/luci.chromium.try/android_compile_x64_dbg) ([`cq.cfg` entry](https://cs.chromium.org/search/?q=package:%5Echromium$+file:cq.cfg+android_compile_x64_dbg)) ([matching builders](https://cs.chromium.org/search/?q=file:trybots.py+android_compile_x64_dbg)) Path regular expressions: @@ -245,7 +245,7 @@ * [linux-chromeos-compile-dbg](https://ci.chromium.org/p/chromium/builders/luci.chromium.try/linux-chromeos-compile-dbg) ([`cq.cfg` entry](https://cs.chromium.org/search/?q=package:%5Echromium$+file:cq.cfg+linux-chromeos-compile-dbg)) ([matching builders](https://cs.chromium.org/search/?q=file:trybots.py+linux-chromeos-compile-dbg)) - * Experimental percentage: 50 + * Experimental percentage: 100 * [linux-dcheck-off-rel](https://ci.chromium.org/p/chromium/builders/luci.chromium.try/linux-dcheck-off-rel) ([`cq.cfg` entry](https://cs.chromium.org/search/?q=package:%5Echromium$+file:cq.cfg+linux-dcheck-off-rel)) ([matching builders](https://cs.chromium.org/search/?q=file:trybots.py+linux-dcheck-off-rel)) @@ -257,7 +257,7 @@ https://crbug.com/855319 - * Experimental percentage: 20 + * Experimental percentage: 50 * [win-libfuzzer-asan-rel](https://ci.chromium.org/p/chromium/builders/luci.chromium.try/win-libfuzzer-asan-rel) ([`cq.cfg` entry](https://cs.chromium.org/search/?q=package:%5Echromium$+file:cq.cfg+win-libfuzzer-asan-rel)) ([matching builders](https://cs.chromium.org/search/?q=file:trybots.py+win-libfuzzer-asan-rel))
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc index 802d5a7..68e826e1 100644 --- a/extensions/browser/api/web_request/web_request_api.cc +++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -1737,7 +1737,8 @@ extension_info_map, listener->id.extension_id, request->url, request->frame_data ? request->frame_data->tab_id : -1, crosses_incognito, - WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL, + WebRequestPermissions:: + REQUIRE_HOST_PERMISSION_FOR_URL_AND_INITIATOR, request->initiator); if (access != PermissionsData::PageAccess::kAllowed) {
diff --git a/extensions/browser/api/web_request/web_request_event_details.cc b/extensions/browser/api/web_request/web_request_event_details.cc index da0c7b7..9d990a6 100644 --- a/extensions/browser/api/web_request/web_request_event_details.cc +++ b/extensions/browser/api/web_request/web_request_event_details.cc
@@ -162,6 +162,9 @@ } // Only listeners with a permission for the initiator should recieve it. + // TODO(karandeepb): This probably shouldn't be needed anymore since we + // require the extension to have access to the initiator to intercept a + // request. if (extension_info_map && initiator_) { int tab_id = -1; dict_.GetInteger(keys::kTabIdKey, &tab_id);
diff --git a/extensions/browser/api/web_request/web_request_permissions.cc b/extensions/browser/api/web_request/web_request_permissions.cc index 3a06789..4c76a5b 100644 --- a/extensions/browser/api/web_request/web_request_permissions.cc +++ b/extensions/browser/api/web_request/web_request_permissions.cc
@@ -38,11 +38,16 @@ // numeric values should never be reused. enum class InitiatorAccess { kAbsent = 0, - kNoAccess = 1, - kHasAccess = 2, + kOpaque = 1, + kNoAccess = 2, + kHasAccess = 3, kMaxValue = kHasAccess, }; +void LogInitiatorAccess(InitiatorAccess access) { + UMA_HISTOGRAM_ENUMERATION("Extensions.WebRequest.InitiatorAccess2", access); +} + // Returns true if the scheme is one we want to allow extensions to have access // to. Extensions still need specific permissions for a given URL, which is // covered by CanExtensionAccessURL. @@ -139,8 +144,18 @@ case WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL_AND_INITIATOR: { PermissionsData::PageAccess request_access = GetHostAccessForURL(*extension, url, tab_id); - if (!initiator || initiator->opaque() || - request_access == PermissionsData::PageAccess::kDenied) { + if (request_access == PermissionsData::PageAccess::kDenied) + return request_access; + + // For cases, where an extension has (allowed or withheld) access to the + // request url, log if it has access to the request initiator. + if (!initiator) { + LogInitiatorAccess(InitiatorAccess::kAbsent); + return request_access; + } + + if (initiator->opaque()) { + LogInitiatorAccess(InitiatorAccess::kOpaque); return request_access; } @@ -163,7 +178,13 @@ // access to the request. This is important for extensions with webRequest // to work well with runtime host permissions. See crbug.com/851722. - return GetHostAccessForURL(*extension, initiator->GetURL(), tab_id); + PermissionsData::PageAccess initiator_access = + GetHostAccessForURL(*extension, initiator->GetURL(), tab_id); + LogInitiatorAccess(initiator_access == + PermissionsData::PageAccess::kDenied + ? InitiatorAccess::kNoAccess + : InitiatorAccess::kHasAccess); + return initiator_access; break; } case WebRequestPermissions::REQUIRE_ALL_URLS: @@ -332,32 +353,9 @@ bool crosses_incognito, HostPermissionsCheck host_permissions_check, const base::Optional<url::Origin>& initiator) { - PermissionsData::PageAccess access = CanExtensionAccessURLInternal( - extension_info_map, extension_id, url, tab_id, crosses_incognito, - host_permissions_check, initiator); - - // For clients only checking host permissions for |url| (e.g. the web request - // API), log metrics to see whether they have host permissions to |initiator|, - // given they have access to |url|. - bool log_metrics = - host_permissions_check == REQUIRE_HOST_PERMISSION_FOR_URL && - access != PermissionsData::PageAccess::kDenied; - if (!log_metrics) - return access; - - InitiatorAccess initiator_access = InitiatorAccess::kAbsent; - if (initiator) { - PermissionsData::PageAccess access = CanExtensionAccessURLInternal( - extension_info_map, extension_id, initiator->GetURL(), tab_id, - crosses_incognito, REQUIRE_HOST_PERMISSION_FOR_URL, base::nullopt); - initiator_access = access == PermissionsData::PageAccess::kDenied - ? InitiatorAccess::kNoAccess - : InitiatorAccess::kHasAccess; - } - - UMA_HISTOGRAM_ENUMERATION("Extensions.WebRequest.InitiatorAccess", - initiator_access); - return access; + return CanExtensionAccessURLInternal(extension_info_map, extension_id, url, + tab_id, crosses_incognito, + host_permissions_check, initiator); } // static
diff --git a/extensions/browser/extension_event_histogram_value.h b/extensions/browser/extension_event_histogram_value.h index 0de0295..d3d964d 100644 --- a/extensions/browser/extension_event_histogram_value.h +++ b/extensions/browser/extension_event_histogram_value.h
@@ -445,6 +445,7 @@ WEB_REQUEST_ON_ACTION_IGNORED = 424, ARC_APPS_PRIVATE_ON_INSTALLED = 425, FILE_MANAGER_PRIVATE_ON_CROSTINI_SHARED_PATHS_CHANGED = 426, + AUTOMATION_INTERNAL_ON_GET_TEXT_LOCATION_RESULT = 427, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index de866fa4..577449bc 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1354,6 +1354,7 @@ BRAILLEDISPLAYPRIVATE_UPDATEBLUETOOTHBRAILLEDISPLAYADDRESS = 1291, AUTOTESTPRIVATE_SETASSISTANTENABLED = 1292, AUTOTESTPRIVATE_ISARCPROVISIONED = 1293, + CRYPTOTOKENPRIVATE_CANPROXYTOWEBAUTHN = 1294, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/renderer/gin_port.cc b/extensions/renderer/gin_port.cc index 100a945..1bb6b92 100644 --- a/extensions/renderer/gin_port.cc +++ b/extensions/renderer/gin_port.cc
@@ -242,6 +242,12 @@ } void GinPort::InvalidateEvents(v8::Local<v8::Context> context) { + // No need to invalidate the events if the context itself was already + // invalidated; the APIEventHandler will have already cleaned up the + // listeners. + if (state_ == kInvalidated) + return; + // TODO(devlin): By calling GetEvent() here, we'll end up creating an event // if one didn't exist. It would be more efficient to only invalidate events // that the port has already created.
diff --git a/extensions/renderer/resources/test_custom_bindings.js b/extensions/renderer/resources/test_custom_bindings.js index bd98cc26..0008a71 100644 --- a/extensions/renderer/resources/test_custom_bindings.js +++ b/extensions/renderer/resources/test_custom_bindings.js
@@ -94,7 +94,7 @@ pendingCallbacks = 0; lastTest = currentTest; - currentTest = chromeTest.tests.shift(); + currentTest = $Array.shift(chromeTest.tests); if (!currentTest) { allTestsDone(); @@ -107,7 +107,7 @@ if (e !== failureException) chromeTest.fail('uncaught exception: ' + message); }); - currentTest.call(); + $Function.call(currentTest); } catch (e) { handleException(e.message, e); }
diff --git a/gin/converter.cc b/gin/converter.cc index 1111d2aa..ce40d59 100644 --- a/gin/converter.cc +++ b/gin/converter.cc
@@ -44,7 +44,9 @@ } bool Converter<bool>::FromV8(Isolate* isolate, Local<Value> val, bool* out) { - return FromMaybe(val->BooleanValue(isolate->GetCurrentContext()), out); + *out = val->BooleanValue(isolate); + // BooleanValue cannot throw. + return true; } Local<Value> Converter<int32_t>::ToV8(Isolate* isolate, int32_t val) {
diff --git a/google_apis/gcm/base/socket_stream_unittest.cc b/google_apis/gcm/base/socket_stream_unittest.cc index 918a411..25b9261 100644 --- a/google_apis/gcm/base/socket_stream_unittest.cc +++ b/google_apis/gcm/base/socket_stream_unittest.cc
@@ -91,6 +91,7 @@ // net:: components. net::AddressList address_list_; + std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_; std::unique_ptr<network::NetworkService> network_service_; network::mojom::NetworkContextPtr network_context_ptr_; net::MockClientSocketFactory socket_factory_; @@ -104,6 +105,7 @@ GCMSocketStreamTest::GCMSocketStreamTest() : scoped_task_environment_( base::test::ScopedTaskEnvironment::MainThreadType::IO), + network_change_notifier_(net::NetworkChangeNotifier::CreateMock()), network_service_(network::NetworkService::CreateForTesting()), url_request_context_(true /* delay_initialization */) { address_list_ = net::AddressList::CreateFromIPAddress(
diff --git a/google_apis/gcm/engine/connection_factory_impl_unittest.cc b/google_apis/gcm/engine/connection_factory_impl_unittest.cc index f35955d..65d99f8 100644 --- a/google_apis/gcm/engine/connection_factory_impl_unittest.cc +++ b/google_apis/gcm/engine/connection_factory_impl_unittest.cc
@@ -304,6 +304,7 @@ std::unique_ptr<base::RunLoop> run_loop_; GURL connected_server_; + std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_; std::unique_ptr<network::NetworkService> network_service_; network::mojom::NetworkContextPtr network_context_ptr_; std::unique_ptr<network::NetworkContext> network_context_; @@ -320,6 +321,7 @@ base::Bind(&ConnectionFactoryImplTest::ConnectionsComplete, base::Unretained(this))), run_loop_(new base::RunLoop()), + network_change_notifier_(net::NetworkChangeNotifier::CreateMock()), network_service_(network::NetworkService::CreateForTesting()) { network::mojom::NetworkContextParamsPtr params = network::mojom::NetworkContextParams::New();
diff --git a/google_apis/gcm/engine/connection_handler_impl_unittest.cc b/google_apis/gcm/engine/connection_handler_impl_unittest.cc index d047f27..7ec425e 100644 --- a/google_apis/gcm/engine/connection_handler_impl_unittest.cc +++ b/google_apis/gcm/engine/connection_handler_impl_unittest.cc
@@ -191,6 +191,7 @@ net::AddressList address_list_; base::test::ScopedTaskEnvironment scoped_task_environment_; std::unique_ptr<base::RunLoop> run_loop_; + std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_; std::unique_ptr<network::NetworkService> network_service_; network::mojom::NetworkContextPtr network_context_ptr_; net::MockClientSocketFactory socket_factory_; @@ -205,6 +206,7 @@ : last_error_(0), scoped_task_environment_( base::test::ScopedTaskEnvironment::MainThreadType::IO), + network_change_notifier_(net::NetworkChangeNotifier::CreateMock()), network_service_(network::NetworkService::CreateForTesting()), url_request_context_(true /* delay_initialization */) { address_list_ = net::AddressList::CreateFromIPAddress(
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index 2b04a59..7932e099 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc
@@ -1029,10 +1029,11 @@ validators_.texture_internal_format_storage.AddValue(GL_ETC1_RGB8_OES); } - // TODO(kainino): Once we have a way to query whether ANGLE is exposing - // native support for ETC2 textures, require that here. - // http://anglebug.com/1552 - if (gl_version_info_->is_es3 && !gl_version_info_->is_angle) { + // Expose GL_CHROMIUM_compressed_texture_etc when ANGLE exposes it directly or + // running on top of a non-ANGLE ES driver. We assume that this implies native + // support of these formats. + if (gfx::HasExtension(extensions, "GL_CHROMIUM_compressed_texture_etc") || + (gl_version_info_->is_es3 && !gl_version_info_->is_angle)) { AddExtensionString("GL_CHROMIUM_compressed_texture_etc"); validators_.UpdateETCCompressedTextureFormats(); }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h index 4a3fa61..0a36589 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -399,7 +399,7 @@ } // Copy into the destination - DCHECK(*length < bufsize); + DCHECK(*length <= bufsize); std::copy(scratch_params, scratch_params + *length, params); return error::kNoError;
diff --git a/gpu/command_buffer/tests/fuzzer_main.cc b/gpu/command_buffer/tests/fuzzer_main.cc index 1a93a102..1897401 100644 --- a/gpu/command_buffer/tests/fuzzer_main.cc +++ b/gpu/command_buffer/tests/fuzzer_main.cc
@@ -403,9 +403,11 @@ if (translator) translator->AddRef(); #endif - decoder_->Destroy(true); + bool context_lost = + decoder_->WasContextLost() || !decoder_->CheckResetStatus(); + decoder_->Destroy(!context_lost); decoder_.reset(); - if (recreate_context_) { + if (recreate_context_ || context_lost) { context_->ReleaseCurrent(nullptr); context_ = nullptr; }
diff --git a/gpu/vulkan/generate_bindings.py b/gpu/vulkan/generate_bindings.py index 1d17365..842bee5 100755 --- a/gpu/vulkan/generate_bindings.py +++ b/gpu/vulkan/generate_bindings.py
@@ -71,6 +71,11 @@ { 'name': 'vkWaitForFences' }, ] +VULKAN_DEVICE_FUNCTIONS_ANDROID = [ +{ 'name': 'vkImportSemaphoreFdKHR' }, +{ 'name': 'vkGetSemaphoreFdKHR' }, +] + VULKAN_QUEUE_FUNCTIONS = [ { 'name': 'vkQueueSubmit' }, { 'name': 'vkQueueWaitIdle' }, @@ -123,8 +128,8 @@ def GenerateHeaderFile(file, unassociated_functions, instance_functions, physical_device_functions, device_functions, - queue_functions, command_buffer_functions, - swapchain_functions): + device_functions_android, queue_functions, + command_buffer_functions, swapchain_functions): """Generates gpu/vulkan/vulkan_function_pointers.h""" file.write(LICENSE_AND_HEADER + @@ -136,6 +141,7 @@ #include <vulkan/vulkan.h> #include "base/native_library.h" +#include "build/build_config.h" #include "gpu/vulkan/vulkan_export.h" namespace gpu { @@ -196,6 +202,18 @@ file.write("""\ + // Android only device functions. +#if defined(OS_ANDROID) +""") + + WriteFunctionDeclarations(file, device_functions_android) + + file.write("""\ +#endif +""") + + file.write("""\ + // Queue functions """) @@ -255,6 +273,17 @@ file.write("""\ +#if defined(OS_ANDROID) +""") + + WriteMacros(file, device_functions_android) + + file.write("""\ +#endif +""") + + file.write("""\ + // Queue functions """) @@ -305,8 +334,8 @@ def GenerateSourceFile(file, unassociated_functions, instance_functions, physical_device_functions, device_functions, - queue_functions, command_buffer_functions, - swapchain_functions): + device_functions_android, queue_functions, + command_buffer_functions, swapchain_functions): """Generates gpu/vulkan/vulkan_function_pointers.cc""" file.write(LICENSE_AND_HEADER + @@ -374,6 +403,18 @@ file.write("""\ +#if defined(OS_ANDROID) + +""") + + WriteDeviceFunctionPointerInitialization(file, device_functions_android) + + file.write("""\ +#endif +""") + + file.write("""\ + // Queue functions """) WriteDeviceFunctionPointerInitialization(file, queue_functions) @@ -425,6 +466,7 @@ GenerateHeaderFile(header_file, VULKAN_UNASSOCIATED_FUNCTIONS, VULKAN_INSTANCE_FUNCTIONS, VULKAN_PHYSICAL_DEVICE_FUNCTIONS, VULKAN_DEVICE_FUNCTIONS, + VULKAN_DEVICE_FUNCTIONS_ANDROID, VULKAN_QUEUE_FUNCTIONS, VULKAN_COMMAND_BUFFER_FUNCTIONS, VULKAN_SWAPCHAIN_FUNCTIONS) header_file.close() @@ -435,6 +477,7 @@ GenerateSourceFile(source_file, VULKAN_UNASSOCIATED_FUNCTIONS, VULKAN_INSTANCE_FUNCTIONS, VULKAN_PHYSICAL_DEVICE_FUNCTIONS, VULKAN_DEVICE_FUNCTIONS, + VULKAN_DEVICE_FUNCTIONS_ANDROID, VULKAN_QUEUE_FUNCTIONS, VULKAN_COMMAND_BUFFER_FUNCTIONS, VULKAN_SWAPCHAIN_FUNCTIONS) source_file.close()
diff --git a/gpu/vulkan/vulkan_function_pointers.cc b/gpu/vulkan/vulkan_function_pointers.cc index dc06702..c635a59 100644 --- a/gpu/vulkan/vulkan_function_pointers.cc +++ b/gpu/vulkan/vulkan_function_pointers.cc
@@ -263,6 +263,20 @@ if (!vkWaitForFencesFn) return false; +#if defined(OS_ANDROID) + + vkImportSemaphoreFdKHRFn = reinterpret_cast<PFN_vkImportSemaphoreFdKHR>( + vkGetDeviceProcAddrFn(vk_device, "vkImportSemaphoreFdKHR")); + if (!vkImportSemaphoreFdKHRFn) + return false; + + vkGetSemaphoreFdKHRFn = reinterpret_cast<PFN_vkGetSemaphoreFdKHR>( + vkGetDeviceProcAddrFn(vk_device, "vkGetSemaphoreFdKHR")); + if (!vkGetSemaphoreFdKHRFn) + return false; + +#endif + // Queue functions vkQueueSubmitFn = reinterpret_cast<PFN_vkQueueSubmit>( vkGetDeviceProcAddrFn(vk_device, "vkQueueSubmit"));
diff --git a/gpu/vulkan/vulkan_function_pointers.h b/gpu/vulkan/vulkan_function_pointers.h index b3aaab04..970e4b25 100644 --- a/gpu/vulkan/vulkan_function_pointers.h +++ b/gpu/vulkan/vulkan_function_pointers.h
@@ -14,6 +14,7 @@ #include <vulkan/vulkan.h> #include "base/native_library.h" +#include "build/build_config.h" #include "gpu/vulkan/vulkan_export.h" namespace gpu { @@ -99,6 +100,12 @@ PFN_vkUpdateDescriptorSets vkUpdateDescriptorSetsFn = nullptr; PFN_vkWaitForFences vkWaitForFencesFn = nullptr; +// Android only device functions. +#if defined(OS_ANDROID) + PFN_vkImportSemaphoreFdKHR vkImportSemaphoreFdKHRFn = nullptr; + PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHRFn = nullptr; +#endif + // Queue functions PFN_vkQueueSubmit vkQueueSubmitFn = nullptr; PFN_vkQueueWaitIdle vkQueueWaitIdleFn = nullptr; @@ -207,6 +214,13 @@ gpu::GetVulkanFunctionPointers()->vkUpdateDescriptorSetsFn #define vkWaitForFences gpu::GetVulkanFunctionPointers()->vkWaitForFencesFn +#if defined(OS_ANDROID) +#define vkImportSemaphoreFdKHR \ + gpu::GetVulkanFunctionPointers()->vkImportSemaphoreFdKHRFn +#define vkGetSemaphoreFdKHR \ + gpu::GetVulkanFunctionPointers()->vkGetSemaphoreFdKHRFn +#endif + // Queue functions #define vkQueueSubmit gpu::GetVulkanFunctionPointers()->vkQueueSubmitFn #define vkQueueWaitIdle gpu::GetVulkanFunctionPointers()->vkQueueWaitIdleFn
diff --git a/infra/config/branch/cq.cfg b/infra/config/branch/cq.cfg index e72daa4..2961649 100644 --- a/infra/config/branch/cq.cfg +++ b/infra/config/branch/cq.cfg
@@ -131,6 +131,15 @@ path_regexp: "third_party/WebKit/LayoutTests/flag-specific/enable-blink-gen-property-trees/.+" } builders { + name: "linux-blink-rel" + path_regexp: "cc/.+" + path_regexp: "third_party/WebKit/LayoutTests/FlagExpectations/(enable-slimming-paint-v2|enable-blink-gen-property-trees)" + path_regexp: "third_party/WebKit/LayoutTests/flag-specific/(enable-slimming-paint-v2|enable-blink-gen-property-trees)/.+" + path_regexp: "third_party/blink/renderer/core/layout/compositing/.+" + path_regexp: "third_party/blink/renderer/core/(svg|paint)/.+" + path_regexp: "third_party/blink/renderer/platform/graphics/.+" + } + builders { name: "linux_chromium_dbg_ng" path_regexp: "build/.*check_gn_headers.*" } @@ -217,7 +226,7 @@ } builders { name: "linux-chromeos-compile-dbg" - experiment_percentage: 50 + experiment_percentage: 100 } # https://crbug.com/833482 builders { @@ -227,7 +236,7 @@ # https://crbug.com/855319 builders { name: "linux-goma-rbe-staging-rel" - experiment_percentage: 20 + experiment_percentage: 50 } builders { name: "win-libfuzzer-asan-rel" @@ -240,19 +249,6 @@ } buckets { - name: "master.tryserver.blink" - builders { - name: "linux_trusty_blink_rel" - path_regexp: "cc/.+" - path_regexp: "third_party/WebKit/LayoutTests/FlagExpectations/(enable-slimming-paint-v2|enable-blink-gen-property-trees)" - path_regexp: "third_party/WebKit/LayoutTests/flag-specific/(enable-slimming-paint-v2|enable-blink-gen-property-trees)/.+" - path_regexp: "third_party/blink/renderer/core/layout/compositing/.+" - path_regexp: "third_party/blink/renderer/core/(svg|paint)/.+" - path_regexp: "third_party/blink/renderer/platform/graphics/.+" - } - } - - buckets { name: "master.tryserver.chromium.android" builders { name: "android_compile_x64_dbg"
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg index dfa4013..cdd0974 100644 --- a/infra/config/global/cr-buildbucket.cfg +++ b/infra/config/global/cr-buildbucket.cfg
@@ -348,6 +348,12 @@ } builder_mixins { + name: "linux-dawn-try" + mixins: "linux" + mixins: "dawn-try" +} + +builder_mixins { name: "linux-optional-gpu-try" mixins: "linux" mixins: "gpu-optional-try" @@ -418,6 +424,12 @@ } builder_mixins { + name: "mac-dawn-try" + mixins: "mac" + mixins: "dawn-try" +} + +builder_mixins { name: "mac-optional-gpu-try" mixins: "mac" mixins: "gpu-optional-try" @@ -3111,6 +3123,7 @@ name: "linux_chromium_tsan_rel_ng" } builders { mixins: "linux-try" name: "linux_chromium_ubsan_rel_ng" } + builders { mixins: "linux-dawn-try" name: "linux-dawn-rel" } builders { mixins: "linux-try" name: "linux_layout_tests_layout_ng" } builders { mixins: "linux-try" name: "linux_layout_tests_slimming_paint_v2" } builders { mixins: "linux-try" name: "linux_mojo" } @@ -3164,6 +3177,7 @@ mixins: "goma-j150" name: "mac_chromium_rel_ng" } + builders { mixins: "mac-dawn-try" name: "mac-dawn-rel" } builders { mixins: "mac-optional-gpu-try" name: "mac_optional_gpu_tests_rel" @@ -3302,40 +3316,80 @@ mixins: "blink-try" } builders { + name: "linux_trusty_blink_rel" + mixins: "linux" + mixins: "blink-try" + } + builders { name: "mac10.10-blink-rel" mixins: "mac" mixins: "blink-try" } builders { + name: "mac10.10_blink_rel" + mixins: "mac" + mixins: "blink-try" + } + builders { name: "mac10.11-blink-rel" mixins: "mac" mixins: "blink-try" } builders { + name: "mac10.11_blink_rel" + mixins: "mac" + mixins: "blink-try" + } + builders { name: "mac10.12-blink-rel" mixins: "mac" mixins: "blink-try" } builders { + name: "mac10.12_blink_rel" + mixins: "mac" + mixins: "blink-try" + } + builders { name: "mac10.13-blink-rel" mixins: "mac" mixins: "blink-try" } builders { + name: "mac10.13_blink_rel" + mixins: "mac" + mixins: "blink-try" + } + builders { name: "mac10.13_retina-blink-rel" mixins: "mac" mixins: "blink-try" } builders { + name: "mac10.13_retina_blink_rel" + mixins: "mac" + mixins: "blink-try" + } + builders { name: "win10-blink-rel" mixins: "win" mixins: "blink-try" } builders { + name: "win10_blink_rel" + mixins: "win" + mixins: "blink-try" + } + builders { name: "win7-blink-rel" mixins: "win" mixins: "blink-try" } + builders { + name: "win7_blink_rel" + mixins: "win" + mixins: "blink-try" + } } }
diff --git a/infra/config/global/lint-luci-milo.py b/infra/config/global/lint-luci-milo.py index 65cd337..7514e7bd 100755 --- a/infra/config/global/lint-luci-milo.py +++ b/infra/config/global/lint-luci-milo.py
@@ -24,13 +24,19 @@ # are consistent with the builders on that subwaterfall's main page. # For example, checks that the builders on the "chromium.win" section # are the same as on the dedicated standalone chromium.win waterfall. - main_names = [', '.join(builder.name) for builder in main_builders] - sub_names = [', '.join(builder.name) for builder in sub_builders] + def to_list(builders): + desc_list = [] + for builder in builders: + desc_list.append('name: ' + ', '.join(builder.name)) + desc_list.append('short_name: ' + builder.short_name) + return desc_list + main_desc = to_list(main_builders) + sub_desc = to_list(sub_builders) - if main_names != sub_names: - print ('bot name lists different between main waterfall ' + + if main_desc != sub_desc: + print ('bot lists different between main waterfall ' + 'and stand-alone %s waterfall:' % name) - print '\n'.join(difflib.unified_diff(main_names, sub_names, + print '\n'.join(difflib.unified_diff(main_desc, sub_desc, fromfile='main', tofile=name, lineterm='')) print
diff --git a/infra/config/global/luci-milo.cfg b/infra/config/global/luci-milo.cfg index e06f435d..6e33e34 100644 --- a/infra/config/global/luci-milo.cfg +++ b/infra/config/global/luci-milo.cfg
@@ -972,7 +972,7 @@ builders { name: "buildbucket/luci.chromium.ci/Cast Linux" category: "cast" - short_name: "lnx" + short_name: "vid" } builders { name: "buildbucket/luci.chromium.ci/Cast Audio Linux" @@ -1586,27 +1586,33 @@ include_experimental_builds: true builders { name: "buildbucket/luci.chromium.ci/android-dbg" - short_name: "android|dbg" + category: "android" + short_name: "dbg" } builders { name: "buildbucket/luci.chromium.ci/android-rel" - short_name: "android|rel" + category: "android" + short_name: "rel" } builders { name: "buildbucket/luci.chromium.ci/linux-dbg" - short_name: "linux|dbg" + category: "linux" + short_name: "dbg" } builders { name: "buildbucket/luci.chromium.ci/linux-rel" - short_name: "linux|rel" + category: "linux" + short_name: "rel" } builders { name: "buildbucket/luci.chromium.ci/mac-dbg" - short_name: "mac|dbg" + category: "mac" + short_name: "dbg" } builders { name: "buildbucket/luci.chromium.ci/mac-rel" - short_name: "mac|rel" + category: "mac" + short_name: "rel" } builders { name: "buildbucket/luci.chromium.ci/win32-rel" @@ -2560,331 +2566,6 @@ consoles { header_id: "chromium" - id: "luci.chromium.fyi" - name: "luci.chromium.fyi" - repo_url: "https://chromium.googlesource.com/chromium/src" - refs: "refs/heads/master" - manifest_name: "REVISION" - include_experimental_builds: true - builders { - name: "buildbucket/luci.chromium.ci/Android Builder (dbg)" - category: "android_builder" - } - builders { - name: "buildbucket/luci.chromium.ci/Android Remoting Tests" - category: "android_tests" - } - builders { - name: "buildbucket/luci.chromium.ci/Android Find Annotated Test" - category: "android_tests" - } - builders { - name: "buildbucket/luci.chromium.ci/Android VR Tests" - category: "android_tests" - } - builders { - name: "buildbucket/luci.chromium.ci/Android ChromeDriver Tests (dbg)" - category: "android_tests" - } - builders { - name: "buildbucket/luci.chromium.ci/Afl Upload Linux ASan" - category: "chromium_afl" - } - builders { - name: "buildbucket/luci.chromium.ci/Libfuzzer Upload Linux ASan" - category: "chromium_libfuzzer" - } - builders { - name: "buildbucket/luci.chromium.ci/Libfuzzer Upload Linux ASan Debug" - category: "chromium_libfuzzer" - } - builders { - name: "buildbucket/luci.chromium.ci/Libfuzzer Upload Linux MSan" - category: "chromium_libfuzzer" - } - builders { - name: "buildbucket/luci.chromium.ci/Libfuzzer Upload Linux UBSan" - category: "chromium_libfuzzer" - } - builders { - name: "buildbucket/luci.chromium.ci/Libfuzzer Upload Mac ASan" - category: "chromium_libfuzzer" - } - builders { - name: "buildbucket/luci.chromium.ci/Libfuzzer Upload Windows ASan" - category: "chromium_libfuzzer" - } - builders { - name: "buildbucket/luci.chromium.ci/Linux Clang Analyzer" - category: "clang tot" - } - builders { - name: "buildbucket/luci.chromium.ci/Closure Compilation Linux" - category: "closure_compilation" - } - builders { - name: "buildbucket/luci.chromium.ci/linux-code-coverage" - category: "code_coverage" - short_name: "lnx" - } - builders { - name: "buildbucket/luci.chromium.ci/mac-code-coverage-generation" - category: "code_coverage" - short_name: "mac" - } - builders { - name: "buildbucket/luci.chromium.ci/ios-simulator-cronet" - category: "cronet" - } - builders { - name: "buildbucket/luci.chromium.ci/mac-views-rel" - category: "default" - } - builders { - name: "buildbucket/luci.chromium.ci/Chromium Mac 10.13" - category: "default" - } - builders { - name: "buildbucket/luci.chromium.ci/Chromium Windows Analyze" - category: "default" - } - builders { - name: "buildbucket/luci.chromium.ci/Mac deterministic" - category: "deterministic" - } - builders { - name: "buildbucket/luci.chromium.ci/Windows Clang deterministic" - category: "deterministic" - } - builders { - name: "buildbucket/luci.chromium.ci/Mac deterministic (dbg)" - category: "deterministic" - } - builders { - name: "buildbucket/luci.chromium.ci/fuchsia-fyi-arm64-rel" - category: "fuchsia" - } - builders { - name: "buildbucket/luci.chromium.ci/fuchsia-fyi-x64-dbg" - category: "fuchsia" - } - builders { - name: "buildbucket/luci.chromium.ci/fuchsia-fyi-x64-rel" - category: "fuchsia" - } - builders { - name: "buildbucket/luci.chromium.ci/Android Builder (dbg) Goma Canary" - category: "goma|android|debug" - } - builders { - name: "buildbucket/luci.chromium.ci/Linux Builder Goma Canary" - category: "goma|linux" - } - builders { - name: "buildbucket/luci.chromium.ci/Linux x64 Goma Canary (clobber)" - category: "goma|linux" - short_name: "clb" - } - builders { - name: "buildbucket/luci.chromium.ci/Linux x64 Goma Canary LocalOutputCache" - category: "goma|linux" - short_name: "loc" - } - builders { - name: "buildbucket/luci.chromium.ci/Mac Builder (dbg) Goma Canary" - category: "goma|mac|debug" - } - builders { - name: "buildbucket/luci.chromium.ci/Mac Builder (dbg) Goma Canary (clobber)" - category: "goma|mac|debug" - short_name: "clb" - } - builders { - name: "buildbucket/luci.chromium.ci/Mac Builder Goma Canary" - category: "goma|mac" - } - builders { - name: "buildbucket/luci.chromium.ci/Mac Goma Canary (clobber)" - category: "goma|mac" - short_name: "clb" - } - builders { - name: "buildbucket/luci.chromium.ci/Mac Goma Canary LocalOutputCache" - category: "goma|mac" - short_name: "loc" - } - builders { - name: "buildbucket/luci.chromium.ci/Win Builder (dbg) Goma Canary" - category: "goma|win|debug" - } - builders { - name: "buildbucket/luci.chromium.ci/Win7 Builder (dbg) Goma Canary" - category: "goma|win|debug" - short_name: "7" - } - builders { - name: "buildbucket/luci.chromium.ci/Win Builder Goma Canary" - category: "goma|win" - } - builders { - name: "buildbucket/luci.chromium.ci/Win Goma Canary LocalOutputCache" - category: "goma|win" - short_name: "loc" - } - builders { - name: "buildbucket/luci.chromium.ci/Win7 Builder Goma Canary" - category: "goma|win" - short_name: "7" - } - builders { - name: "buildbucket/luci.chromium.ci/Win cl.exe Goma Canary LocalOutputCache" - category: "goma|win|cl.exe" - short_name: "loc" - } - builders { - name: "buildbucket/luci.chromium.ci/WinMSVC64 Goma Canary" - category: "goma|win|cl.exe" - } - builders { - name: "buildbucket/luci.chromium.ci/chromeos-amd64-generic-rel-goma-canary" - category: "goma|chromeos" - } - builders { - name: "buildbucket/luci.chromium.ci/ios-device-goma-canary-clobber" - category: "goma|ios" - } - builders { - name: "buildbucket/luci.chromium.ci/ios12-sdk-device" - category: "iOS|iOS12" - short_name: "dev" - } - builders { - name: "buildbucket/luci.chromium.ci/ios12-sdk-simulator" - category: "iOS|iOS12" - short_name: "sim" - } - builders { - name: "buildbucket/luci.chromium.ci/Jumbo Linux x64" - category: "jumbo" - } - builders { - name: "buildbucket/luci.chromium.ci/Jumbo Mac" - category: "jumbo" - } - builders { - name: "buildbucket/luci.chromium.ci/Jumbo Win x64" - category: "jumbo" - } - builders { - name: "buildbucket/luci.chromium.ci/linux-blink-animation-use-time-delta" - category: "linux|blink" - short_name: "TD" - } - builders { - name: "buildbucket/luci.chromium.ci/linux-blink-heap-incremental-marking" - category: "linux|blink" - short_name: "IM" - } - builders { - name: "buildbucket/luci.chromium.ci/linux-blink-heap-unified-gc" - category: "linux|blink" - short_name: "UGC" - } - builders { - name: "buildbucket/luci.chromium.ci/linux-blink-heap-verification" - category: "linux|blink" - short_name: "VF" - } - builders { - name: "buildbucket/luci.chromium.ci/Linux ARM" - category: "linux" - } - builders { - name: "buildbucket/luci.chromium.ci/Headless Linux (dbg)" - category: "linux" - } - builders { - name: "buildbucket/luci.chromium.ci/VR Linux" - category: "linux" - } - builders { - name: "buildbucket/luci.chromium.ci/linux-tcmalloc-rel" - category: "linux" - } - builders { - name: "buildbucket/luci.chromium.ci/Mojo Android" - category: "mojo" - short_name: "and" - } - builders { - name: "buildbucket/luci.chromium.ci/android-mojo-webview-rel" - category: "mojo" - short_name: "aw" - } - builders { - name: "buildbucket/luci.chromium.ci/Mojo ChromiumOS" - category: "mojo" - short_name: "cr" - } - builders { - name: "buildbucket/luci.chromium.ci/Mojo Linux" - category: "mojo" - short_name: "lnx" - } - builders { - name: "buildbucket/luci.chromium.ci/mac-mojo-rel" - category: "mojo" - short_name: "mac" - } - builders { - name: "buildbucket/luci.chromium.ci/Mojo Windows" - category: "mojo" - short_name: "win" - } - builders { - name: "buildbucket/luci.chromium.ci/linux-chromium-tests-staging-builder" - category: "recipe|staging|linux" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium.ci/linux-chromium-tests-staging-tests" - category: "recipe|staging|linux" - short_name: "tst" - } - builders { - name: "buildbucket/luci.chromium.ci/Linux remote_run Builder" - category: "remote_run" - } - builders { - name: "buildbucket/luci.chromium.ci/Linux remote_run Tester" - category: "remote_run" - } - builders { - name: "buildbucket/luci.chromium.ci/Site Isolation Android" - category: "site_isolation" - } - builders { - name: "buildbucket/luci.chromium.ci/linux-annotator-rel" - category: "network|traffic|annotations" - short_name: "lnx" - } - builders { - name: "buildbucket/luci.chromium.ci/win-annotator-rel" - category: "network|traffic|annotations" - short_name: "win" - } - builders { - name: "buildbucket/luci.chromium.ci/Linux Viz" - category: "viz" - } - builders { - name: "buildbucket/luci.chromium.ci/Win 10 Fast Ring" - category: "win10" - } -} - -consoles { - header_id: "chromium" id: "chromium.fyi" name: "chromium.fyi" repo_url: "https://chromium.googlesource.com/chromium/src" @@ -3198,6 +2879,10 @@ category: "linux" } builders { + name: "buildbucket/luci.chromium.ci/linux-tcmalloc-rel" + category: "linux" + } + builders { name: "buildbot/chromium.fyi/Mojo Android" name: "buildbucket/luci.chromium.ci/Mojo Android" category: "mojo" @@ -4744,6 +4429,38 @@ name: "buildbot/tryserver.blink/win7-blink-rel" name: "buildbucket/luci.chromium.try/win7-blink-rel" } + builders { + name: "buildbot/tryserver.blink/linux_trusty_blink_rel" + name: "buildbucket/luci.chromium.try/linux_trusty_blink_rel" + } + builders { + name: "buildbot/tryserver.blink/mac10.10_blink_rel" + name: "buildbucket/luci.chromium.try/mac10.10_blink_rel" + } + builders { + name: "buildbot/tryserver.blink/mac10.11_blink_rel" + name: "buildbucket/luci.chromium.try/mac10.11_blink_rel" + } + builders { + name: "buildbot/tryserver.blink/mac10.13_retina_blink_rel" + name: "buildbucket/luci.chromium.try/mac10.13_retina_blink_rel" + } + builders { + name: "buildbot/tryserver.blink/mac10.12_blink_rel" + name: "buildbucket/luci.chromium.try/mac10.12_blink_rel" + } + builders { + name: "buildbot/tryserver.blink/mac10.13_blink_rel" + name: "buildbucket/luci.chromium.try/mac10.13_blink_rel" + } + builders { + name: "buildbot/tryserver.blink/win10_blink_rel" + name: "buildbucket/luci.chromium.try/win10_blink_rel" + } + builders { + name: "buildbot/tryserver.blink/win7_blink_rel" + name: "buildbucket/luci.chromium.try/win7_blink_rel" + } builder_view_only: true }
diff --git a/infra/config/global/luci-scheduler.cfg b/infra/config/global/luci-scheduler.cfg index 3fa9cbc3..8e2fa884 100644 --- a/infra/config/global/luci-scheduler.cfg +++ b/infra/config/global/luci-scheduler.cfg
@@ -1274,6 +1274,22 @@ } job { + id: "Dawn GPU Linux Release (Intel HD 630)" + # Triggered by "GPU FYI Linux Builder". + acl_sets: "triggered-by-parent-builders" + # This bot doesn't actually exist, so it's noop'ed out. crbug.com/819899 + noop: {} +} + +job { + id: "Dawn GPU Linux Release (NVIDIA)" + # Triggered by "GPU FYI Linux Builder". + acl_sets: "triggered-by-parent-builders" + # This bot doesn't actually exist, so it's noop'ed out. crbug.com/819899 + noop: {} +} + +job { id: "Deterministic Linux" acl_sets: "default" buildbucket: { @@ -1824,6 +1840,30 @@ ################################################################################ job { + id: "Dawn GPU Mac Release (Intel)" + # Triggered by "GPU FYI Mac Builder". + acl_sets: "triggered-by-parent-builders" + # This bot doesn't actually exist, so it's noop'ed out. crbug.com/819899 + noop: {} +} + +job { + id: "Dawn GPU Mac Retina Release (NVIDIA)" + # Triggered by "GPU FYI Mac Builder". + acl_sets: "triggered-by-parent-builders" + # This bot doesn't actually exist, so it's noop'ed out. crbug.com/819899 + noop: {} +} + +job { + id: "Dawn GPU Mac Retina Release (AMD)" + # Triggered by "GPU FYI Mac Builder". + acl_sets: "triggered-by-parent-builders" + # This bot doesn't actually exist, so it's noop'ed out. crbug.com/819899 + noop: {} +} + +job { id: "GPU FYI Mac Builder" acl_sets: "default" buildbucket: {
diff --git a/ios/chrome/app/strings/resources/ios_strings_cs.xtb b/ios/chrome/app/strings/resources/ios_strings_cs.xtb index c1d3c4f..69e10a1 100644 --- a/ios/chrome/app/strings/resources/ios_strings_cs.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_cs.xtb
@@ -115,6 +115,7 @@ <translation id="2780046210906776326">Žádné e-mailové účty</translation> <translation id="2781692009645368755">Google Pay</translation> <translation id="2800683595868705743">Opustit přepínač karet</translation> +<translation id="2830972654601096923">Spravovat adresy...</translation> <translation id="2834956026595107950"><ph name="TITLE" />, <ph name="STATE" />, <ph name="URL" /></translation> <translation id="2843803966603263712">Obnovit nastavení Překladače</translation> <translation id="285960592395650245">Znovu stáhnout</translation> @@ -133,6 +134,7 @@ <translation id="3024255823539804759">Z uplynulého dne</translation> <translation id="3037605927509011580">Aj, chyba!</translation> <translation id="3112556859945124369">Označit…</translation> +<translation id="3126574100374611517">Spravovat platební karty...</translation> <translation id="3157684681743766797">Označit vše…</translation> <translation id="3175081911749765310">Webové služby</translation> <translation id="3207960819495026254">Přidáno do záložek</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_el.xtb b/ios/chrome/app/strings/resources/ios_strings_el.xtb index dcad70e..1f1b152c7 100644 --- a/ios/chrome/app/strings/resources/ios_strings_el.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_el.xtb
@@ -115,6 +115,7 @@ <translation id="2780046210906776326">Κανένας Λογαρ. Email</translation> <translation id="2781692009645368755">Google Pay</translation> <translation id="2800683595868705743">Αποχώρηση από την εναλλαγή καρτελών</translation> +<translation id="2830972654601096923">Διαχείριση διευθύνσεων…</translation> <translation id="2834956026595107950"><ph name="TITLE" />, <ph name="STATE" />, <ph name="URL" /></translation> <translation id="2843803966603263712">Επαν.ρυθ.μετάφ.</translation> <translation id="285960592395650245">Επανάληψη λήψης</translation> @@ -133,6 +134,7 @@ <translation id="3024255823539804759">Τελευταία ημέρα</translation> <translation id="3037605927509011580">Όπα! Κάτι πήγε στραβά!</translation> <translation id="3112556859945124369">Επισήμανση…</translation> +<translation id="3126574100374611517">Διαχείριση πιστωτικών καρτών…</translation> <translation id="3157684681743766797">Επισήμανση όλων…</translation> <translation id="3175081911749765310">Υπηρ.ιστού</translation> <translation id="3207960819495026254">Προστέθηκε στους σελιδοδείκτες</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb b/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb index 375675a..2b8e0bc 100644 --- a/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb
@@ -115,6 +115,7 @@ <translation id="2780046210906776326">No Email Accounts</translation> <translation id="2781692009645368755">Google Pay</translation> <translation id="2800683595868705743">Leave Tab Switcher</translation> +<translation id="2830972654601096923">Manage Addresses…</translation> <translation id="2834956026595107950"><ph name="TITLE" />, <ph name="STATE" />, <ph name="URL" /></translation> <translation id="2843803966603263712">Reset Translate Settings</translation> <translation id="285960592395650245">Retry Download</translation> @@ -133,6 +134,7 @@ <translation id="3024255823539804759">Past Day</translation> <translation id="3037605927509011580">Aw, Snap!</translation> <translation id="3112556859945124369">Mark…</translation> +<translation id="3126574100374611517">Manage Credit Cards…</translation> <translation id="3157684681743766797">Mark All…</translation> <translation id="3175081911749765310">Web Services</translation> <translation id="3207960819495026254">Bookmarked</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_te.xtb b/ios/chrome/app/strings/resources/ios_strings_te.xtb index 6aef694..f9e6056 100644 --- a/ios/chrome/app/strings/resources/ios_strings_te.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_te.xtb
@@ -98,7 +98,7 @@ <translation id="2523184218357549926">మీరు సందర్శించే పేజీల URLలను Googleకి పంపుతుంది</translation> <translation id="2523363575747517183">ఈ వెబ్సైట్ మరో అప్లికేషన్ను తెరవడానికి పలుసార్లు ప్రయత్నిస్తోంది.</translation> <translation id="2529021024822217800">అన్నీ తెరువు</translation> -<translation id="2572712655377361602">ఒక పరికర విధానం మీ ఫోటోలకు ప్రాప్యతను బ్లాక్ చేసింది</translation> +<translation id="2572712655377361602">మీ ఫోటోలకు యాక్సెస్ను ఒక పరికర విధానం బ్లాక్ చేసింది</translation> <translation id="2584132361465095047">ఖాతాను జోడించు…</translation> <translation id="2625189173221582860">పాస్వర్డ్ కాపీ చేయబడింది</translation> <translation id="2648803196158606475">చదివిన వాటిని తొలగించు</translation> @@ -187,7 +187,7 @@ <translation id="4004204301268239848">మీ Google ఖాతాలో పాస్వర్డ్లు సేవ్ చేయబడతాయి కాబట్టి మీరు వాటిని ఏ పరికరంలోనైనా ఉపయోగించవచ్చు.</translation> <translation id="4038354071007134711">ఈ పరికరంలోని అప్లికేషన్ ఏదీ ఫైల్ను తెరవలేదు.</translation> <translation id="4042870976416480368">పేజీలో కనుగొనండి</translation> -<translation id="4049507953662678203">మీకు నెట్వర్క్ కనెక్షన్ ఉందని నిర్ధారించుకుని, ఆపై మళ్లీ ప్రయత్నించండి.</translation> +<translation id="4049507953662678203">మీ ఇంటర్నెట్ పని చేస్తోందో లేదో చెక్ చేసుకుని మళ్లీ ప్రయత్నించండి.</translation> <translation id="408404951701638773">ఇప్పుడు శోధన పట్టీకి మరింత సులభంగా చేరుకోవచ్చు</translation> <translation id="4084682180776658562">బుక్మార్క్ చెయ్యి</translation> <translation id="411254640334432676">డౌన్లోడ్ చేయడం విఫలమైంది.</translation>
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS index e5e244d..0f2369a1 100644 --- a/ios/chrome/browser/DEPS +++ b/ios/chrome/browser/DEPS
@@ -11,6 +11,7 @@ "+components/component_updater", "+components/content_settings/core", "+components/cookie_config", + "+components/country_codes", "+components/crash/core/browser", "+components/crash/core/common", "+components/dom_distiller/core",
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm index 733c184..9703252 100644 --- a/ios/chrome/browser/about_flags.mm +++ b/ios/chrome/browser/about_flags.mm
@@ -195,11 +195,6 @@ {"use-ddljson-api", flag_descriptions::kUseDdljsonApiName, flag_descriptions::kUseDdljsonApiDescription, flags_ui::kOsIos, MULTI_VALUE_TYPE(kUseDdljsonApiChoices)}, - {"omnibox-ui-elide-suggestion-url-after-host", - flag_descriptions::kOmniboxUIElideSuggestionUrlAfterHostName, - flag_descriptions::kOmniboxUIElideSuggestionUrlAfterHostDescription, - flags_ui::kOsIos, - FEATURE_VALUE_TYPE(omnibox::kUIExperimentElideSuggestionUrlAfterHost)}, {"drag_and_drop", flag_descriptions::kDragAndDropName, flag_descriptions::kDragAndDropDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kDragAndDrop)},
diff --git a/ios/chrome/browser/itunes_urls/BUILD.gn b/ios/chrome/browser/itunes_urls/BUILD.gn index 1a7608b..a2c68004 100644 --- a/ios/chrome/browser/itunes_urls/BUILD.gn +++ b/ios/chrome/browser/itunes_urls/BUILD.gn
@@ -16,6 +16,10 @@ "//ios/web", "//url", ] + libs = [ + "Foundation.framework", + "StoreKit.framework", + ] } source_set("unit_tests") {
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm b/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm index 3598ae4..c0e02df 100644 --- a/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm +++ b/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm
@@ -12,7 +12,6 @@ #include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/metrics/tab_usage_recorder.h" #import "ios/chrome/browser/metrics/tab_usage_recorder_test_util.h" -#import "ios/chrome/browser/ui/settings/privacy_collection_view_controller.h" #import "ios/chrome/browser/ui/settings/settings_collection_view_controller.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #include "ios/chrome/browser/ui/util/ui_util.h"
diff --git a/ios/chrome/browser/search_engines/BUILD.gn b/ios/chrome/browser/search_engines/BUILD.gn index e211925..e5d4f09 100644 --- a/ios/chrome/browser/search_engines/BUILD.gn +++ b/ios/chrome/browser/search_engines/BUILD.gn
@@ -36,6 +36,7 @@ ] deps = [ "//base", + "//components/country_codes", "//components/favicon/ios", "//components/google/core/browser", "//components/history/core/browser",
diff --git a/ios/chrome/browser/search_engines/search_engines_util.cc b/ios/chrome/browser/search_engines/search_engines_util.cc index 900fbb39..7c47af1 100644 --- a/ios/chrome/browser/search_engines/search_engines_util.cc +++ b/ios/chrome/browser/search_engines/search_engines_util.cc
@@ -11,6 +11,7 @@ #include "base/location.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" +#include "components/country_codes/country_codes.h" #include "components/prefs/pref_service.h" #include "components/search_engines/search_engines_pref_names.h" #include "components/search_engines/template_url_prepopulate_data.h" @@ -86,17 +87,18 @@ void UpdateSearchEnginesIfNeeded(PrefService* preferences, TemplateURLService* service) { - if (!preferences->HasPrefPath(prefs::kCountryIDAtInstall)) { + if (!preferences->HasPrefPath(country_codes::kCountryIDAtInstall)) { // No search engines were ever installed, just return. return; } - int old_country_id = preferences->GetInteger(prefs::kCountryIDAtInstall); - int country_id = TemplateURLPrepopulateData::GetCurrentCountryID(); + int old_country_id = + preferences->GetInteger(country_codes::kCountryIDAtInstall); + int country_id = country_codes::GetCurrentCountryID(); if (country_id == old_country_id) { // User's locale did not change, just return. return; } - preferences->SetInteger(prefs::kCountryIDAtInstall, country_id); + preferences->SetInteger(country_codes::kCountryIDAtInstall, country_id); // If the current search engine is managed by policy then we can't set the // default search engine, which is required by UpdateSearchEngine(). This // isn't a problem as long as the default search engine is enforced via
diff --git a/ios/chrome/browser/signin/about_signin_internals_factory.cc b/ios/chrome/browser/signin/about_signin_internals_factory.cc index e3d9e8bf..707190f9 100644 --- a/ios/chrome/browser/signin/about_signin_internals_factory.cc +++ b/ios/chrome/browser/signin/about_signin_internals_factory.cc
@@ -14,6 +14,7 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/signin/account_tracker_service_factory.h" #include "ios/chrome/browser/signin/gaia_cookie_manager_service_factory.h" +#include "ios/chrome/browser/signin/identity_manager_factory.h" #include "ios/chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "ios/chrome/browser/signin/signin_client_factory.h" #include "ios/chrome/browser/signin/signin_error_controller_factory.h" @@ -28,6 +29,7 @@ DependsOn(AccountTrackerServiceFactory::GetInstance()); DependsOn(GaiaCookieManagerServiceFactory::GetInstance()); DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); + DependsOn(IdentityManagerFactory::GetInstance()); DependsOn(SigninClientFactory::GetInstance()); DependsOn(SigninErrorControllerFactory::GetInstance()); DependsOn(SigninManagerFactory::GetInstance()); @@ -56,6 +58,7 @@ ProfileOAuth2TokenServiceFactory::GetForBrowserState( chrome_browser_state), AccountTrackerServiceFactory::GetForBrowserState(chrome_browser_state), + IdentityManagerFactory::GetForBrowserState(chrome_browser_state), SigninManagerFactory::GetForBrowserState(chrome_browser_state), SigninErrorControllerFactory::GetForBrowserState(chrome_browser_state), GaiaCookieManagerServiceFactory::GetForBrowserState(chrome_browser_state),
diff --git a/ios/chrome/browser/signin/authentication_service.h b/ios/chrome/browser/signin/authentication_service.h index a5ad006..233295b3 100644 --- a/ios/chrome/browser/signin/authentication_service.h +++ b/ios/chrome/browser/signin/authentication_service.h
@@ -30,7 +30,6 @@ @class ChromeIdentity; class PrefService; class ProfileOAuth2TokenService; -class SigninManager; class SyncSetupService; // AuthenticationService is the Chrome interface to the iOS shared @@ -44,7 +43,6 @@ SyncSetupService* sync_setup_service, AccountTrackerService* account_tracker, identity::IdentityManager* identity_manager, - SigninManager* signin_manager, browser_sync::ProfileSyncService* sync_service); ~AuthenticationService() override; @@ -204,7 +202,6 @@ SyncSetupService* sync_setup_service_ = nullptr; AccountTrackerService* account_tracker_ = nullptr; identity::IdentityManager* identity_manager_ = nullptr; - SigninManager* signin_manager_ = nullptr; browser_sync::ProfileSyncService* sync_service_ = nullptr; // Whether Initialized has been called.
diff --git a/ios/chrome/browser/signin/authentication_service.mm b/ios/chrome/browser/signin/authentication_service.mm index 02aea3d..db7108fd 100644 --- a/ios/chrome/browser/signin/authentication_service.mm +++ b/ios/chrome/browser/signin/authentication_service.mm
@@ -17,7 +17,6 @@ #include "components/prefs/pref_service.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_manager.h" #include "components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h" #include "components/sync/driver/sync_service.h" #include "google_apis/gaia/gaia_auth_util.h" @@ -32,6 +31,7 @@ #import "ios/public/provider/chrome/browser/signin/chrome_identity.h" #include "ios/public/provider/chrome/browser/signin/chrome_identity_service.h" #import "services/identity/public/cpp/identity_manager.h" +#import "services/identity/public/cpp/primary_account_mutator.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -71,14 +71,12 @@ SyncSetupService* sync_setup_service, AccountTrackerService* account_tracker, identity::IdentityManager* identity_manager, - SigninManager* signin_manager, browser_sync::ProfileSyncService* sync_service) : pref_service_(pref_service), token_service_(token_service), sync_setup_service_(sync_setup_service), account_tracker_(account_tracker), identity_manager_(identity_manager), - signin_manager_(signin_manager), sync_service_(sync_service), identity_service_observer_(this), weak_pointer_factory_(this) { @@ -86,7 +84,6 @@ DCHECK(sync_setup_service_); DCHECK(account_tracker_); DCHECK(identity_manager_); - DCHECK(signin_manager_); DCHECK(sync_service_); token_service_->AddObserver(this); } @@ -349,11 +346,9 @@ sync_setup_service_->PrepareForFirstSyncSetup(); // Update the SigninManager with the new logged in identity. - std::string new_authenticated_username = - account_tracker_->GetAccountInfo(new_authenticated_account_id).email; - // TODO(crbug.com/889902): Remove the SigninManager usage once the - // alternative API for this call is available. - signin_manager_->OnExternalSigninCompleted(new_authenticated_username); + auto* account_mutator = identity_manager_->GetPrimaryAccountMutator(); + DCHECK(account_mutator); + account_mutator->SetPrimaryAccount(new_authenticated_account_id); // Reload all credentials to match the desktop model. Exclude all the // accounts ids that are the primary account ids on other profiles.
diff --git a/ios/chrome/browser/signin/authentication_service_factory.mm b/ios/chrome/browser/signin/authentication_service_factory.mm index e9701f74..8a96878 100644 --- a/ios/chrome/browser/signin/authentication_service_factory.mm +++ b/ios/chrome/browser/signin/authentication_service_factory.mm
@@ -15,7 +15,6 @@ #import "ios/chrome/browser/signin/authentication_service_delegate.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" #include "ios/chrome/browser/signin/profile_oauth2_token_service_factory.h" -#include "ios/chrome/browser/signin/signin_manager_factory.h" #include "ios/chrome/browser/sync/profile_sync_service_factory.h" #include "ios/chrome/browser/sync/sync_setup_service_factory.h" @@ -56,7 +55,6 @@ DependsOn(ios::AccountTrackerServiceFactory::GetInstance()); DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); DependsOn(IdentityManagerFactory::GetInstance()); - DependsOn(ios::SigninManagerFactory::GetInstance()); DependsOn(SyncSetupServiceFactory::GetInstance()); DependsOn(ProfileSyncServiceFactory::GetInstance()); } @@ -74,7 +72,6 @@ SyncSetupServiceFactory::GetForBrowserState(browser_state), ios::AccountTrackerServiceFactory::GetForBrowserState(browser_state), IdentityManagerFactory::GetForBrowserState(browser_state), - ios::SigninManagerFactory::GetForBrowserState(browser_state), ProfileSyncServiceFactory::GetForBrowserState(browser_state)); }
diff --git a/ios/chrome/browser/signin/authentication_service_fake.h b/ios/chrome/browser/signin/authentication_service_fake.h index cb9c00c5..0fde8cb3 100644 --- a/ios/chrome/browser/signin/authentication_service_fake.h +++ b/ios/chrome/browser/signin/authentication_service_fake.h
@@ -48,7 +48,6 @@ SyncSetupService* sync_setup_service, AccountTrackerService* account_tracker, identity::IdentityManager* identity_manager, - SigninManager* signin_manager, browser_sync::ProfileSyncService* sync_service); __strong ChromeIdentity* authenticated_identity_;
diff --git a/ios/chrome/browser/signin/authentication_service_fake.mm b/ios/chrome/browser/signin/authentication_service_fake.mm index bad488b..3c7e808 100644 --- a/ios/chrome/browser/signin/authentication_service_fake.mm +++ b/ios/chrome/browser/signin/authentication_service_fake.mm
@@ -13,7 +13,6 @@ #import "ios/chrome/browser/signin/authentication_service_factory.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" #include "ios/chrome/browser/signin/profile_oauth2_token_service_factory.h" -#include "ios/chrome/browser/signin/signin_manager_factory.h" #include "ios/chrome/browser/sync/profile_sync_service_factory.h" #include "ios/chrome/browser/sync/sync_setup_service_factory.h" #import "ios/public/provider/chrome/browser/signin/chrome_identity.h" @@ -28,14 +27,12 @@ SyncSetupService* sync_setup_service, AccountTrackerService* account_tracker, identity::IdentityManager* identity_manager, - SigninManager* signin_manager, browser_sync::ProfileSyncService* sync_service) : AuthenticationService(pref_service, token_service, sync_setup_service, account_tracker, identity_manager, - signin_manager, sync_service), have_accounts_changed_(false) {} @@ -85,7 +82,6 @@ SyncSetupServiceFactory::GetForBrowserState(browser_state), ios::AccountTrackerServiceFactory::GetForBrowserState(browser_state), IdentityManagerFactory::GetForBrowserState(browser_state), - ios::SigninManagerFactory::GetForBrowserState(browser_state), ProfileSyncServiceFactory::GetForBrowserState(browser_state))); service->Initialize(std::make_unique<AuthenticationServiceDelegateFake>()); return service;
diff --git a/ios/chrome/browser/signin/authentication_service_unittest.mm b/ios/chrome/browser/signin/authentication_service_unittest.mm index 7b258f3..b57ab409 100644 --- a/ios/chrome/browser/signin/authentication_service_unittest.mm +++ b/ios/chrome/browser/signin/authentication_service_unittest.mm
@@ -11,7 +11,6 @@ #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_registry_simple.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" -#include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_pref_names.h" #include "components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h" #include "components/sync_preferences/pref_service_mock_factory.h" @@ -33,7 +32,6 @@ #include "ios/chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "ios/chrome/browser/signin/signin_client_factory.h" #include "ios/chrome/browser/signin/signin_error_controller_factory.h" -#include "ios/chrome/browser/signin/signin_manager_factory.h" #include "ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.h" #include "ios/chrome/browser/sync/profile_sync_service_factory.h" #include "ios/chrome/browser/sync/sync_setup_service_factory.h" @@ -182,7 +180,6 @@ ios::AccountTrackerServiceFactory::GetForBrowserState( browser_state_.get()), IdentityManagerFactory::GetForBrowserState(browser_state_.get()), - ios::SigninManagerFactory::GetForBrowserState(browser_state_.get()), ProfileSyncServiceFactory::GetForBrowserState(browser_state_.get())); authentication_service_->Initialize( std::make_unique<AuthenticationServiceDelegateFake>());
diff --git a/ios/chrome/browser/tabs/tab_helper_util.mm b/ios/chrome/browser/tabs/tab_helper_util.mm index 7415f83..3a56099 100644 --- a/ios/chrome/browser/tabs/tab_helper_util.mm +++ b/ios/chrome/browser/tabs/tab_helper_util.mm
@@ -51,7 +51,6 @@ #import "ios/chrome/browser/web/load_timing_tab_helper.h" #import "ios/chrome/browser/web/network_activity_indicator_tab_helper.h" #import "ios/chrome/browser/web/page_placeholder_tab_helper.h" -#import "ios/chrome/browser/web/repost_form_tab_helper.h" #import "ios/chrome/browser/web/tab_id_tab_helper.h" #import "ios/public/provider/chrome/browser/chrome_browser_provider.h" #import "ios/web/public/web_state/web_state.h"
diff --git a/ios/chrome/browser/ui/BUILD.gn b/ios/chrome/browser/ui/BUILD.gn index 2ce5acc..aaa768a 100644 --- a/ios/chrome/browser/ui/BUILD.gn +++ b/ios/chrome/browser/ui/BUILD.gn
@@ -31,7 +31,6 @@ "//base:i18n", "//components/sessions", "//ios/chrome/browser", - "//ios/chrome/browser/store_kit", "//ios/chrome/browser/ui/commands", "//ios/web", "//ui/base", @@ -101,7 +100,6 @@ "//ios/chrome/browser/search_engines", "//ios/chrome/browser/sessions", "//ios/chrome/browser/snapshots", - "//ios/chrome/browser/store_kit", "//ios/chrome/browser/tabs", "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/activity_services", @@ -279,7 +277,6 @@ "//ios/chrome/app:tests_hook", "//ios/chrome/app/strings", "//ios/chrome/browser", - "//ios/chrome/browser/app_launcher", "//ios/chrome/browser/autofill:autofill_internal", "//ios/chrome/browser/bookmarks", "//ios/chrome/browser/browser_state", @@ -303,14 +300,12 @@ "//ios/chrome/browser/signin", "//ios/chrome/browser/snapshots", "//ios/chrome/browser/ssl", - "//ios/chrome/browser/store_kit", "//ios/chrome/browser/tabs", "//ios/chrome/browser/translate", "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/activity_services:coordinator", "//ios/chrome/browser/ui/activity_services/requirements", "//ios/chrome/browser/ui/alert_coordinator", - "//ios/chrome/browser/ui/app_launcher", "//ios/chrome/browser/ui/autofill:autofill", "//ios/chrome/browser/ui/autofill/manual_fill", "//ios/chrome/browser/ui/bookmarks", @@ -415,7 +410,6 @@ "MobileCoreServices.framework", "Photos.framework", "QuartzCore.framework", - "StoreKit.framework", "UIKit.framework", "WebKit.framework", ] @@ -490,7 +484,6 @@ "//ios/chrome/browser/autocomplete", "//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/search_engines", - "//ios/chrome/browser/store_kit", "//ios/chrome/browser/tabs", "//ios/chrome/browser/tabs:tabs_internal", "//ios/chrome/browser/ui/commands",
diff --git a/ios/chrome/browser/ui/app_launcher/app_launcher_coordinator.h b/ios/chrome/browser/ui/app_launcher/app_launcher_coordinator.h index 324dd52b..0b24be90 100644 --- a/ios/chrome/browser/ui/app_launcher/app_launcher_coordinator.h +++ b/ios/chrome/browser/ui/app_launcher/app_launcher_coordinator.h
@@ -10,6 +10,7 @@ #import "ios/chrome/browser/app_launcher/app_launcher_tab_helper_delegate.h" // A coordinator that handles UI related to launching apps. +// TODO(crbug.com/906541) : Convert to ChromeCoordinator subclass. @interface AppLauncherCoordinator : NSObject<AppLauncherTabHelperDelegate> // Initializes the coordinator with the |baseViewController|, from which to
diff --git a/ios/chrome/browser/ui/autofill/cells/BUILD.gn b/ios/chrome/browser/ui/autofill/cells/BUILD.gn index 98ee66ce..4c19165 100644 --- a/ios/chrome/browser/ui/autofill/cells/BUILD.gn +++ b/ios/chrome/browser/ui/autofill/cells/BUILD.gn
@@ -4,10 +4,10 @@ source_set("cells") { sources = [ - "autofill_edit_item.h", - "autofill_edit_item.mm", "cvc_item.h", "cvc_item.mm", + "legacy_autofill_edit_item.h", + "legacy_autofill_edit_item.mm", "status_item.h", "status_item.mm", ] @@ -36,8 +36,8 @@ source_set("unit_tests") { testonly = true sources = [ - "autofill_edit_item_unittest.mm", "cvc_item_unittest.mm", + "legacy_autofill_edit_item_unittest.mm", "status_item_unittest.mm", ]
diff --git a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h b/ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.h similarity index 83% rename from ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h rename to ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.h index 1094cee4..e243d92 100644 --- a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h +++ b/ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_UI_AUTOFILL_CELLS_AUTOFILL_EDIT_ITEM_H_ -#define IOS_CHROME_BROWSER_UI_AUTOFILL_CELLS_AUTOFILL_EDIT_ITEM_H_ +#ifndef IOS_CHROME_BROWSER_UI_AUTOFILL_CELLS_LEGACY_AUTOFILL_EDIT_ITEM_H_ +#define IOS_CHROME_BROWSER_UI_AUTOFILL_CELLS_LEGACY_AUTOFILL_EDIT_ITEM_H_ #import <UIKit/UIKit.h> @@ -12,9 +12,9 @@ #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" -// Item to represent and configure an AutofillEditItem. It features a label and -// a text field. -@interface AutofillEditItem : CollectionViewItem +// Item to represent and configure an LegacyAutofillEditItem. It features a +// label and a text field. +@interface LegacyAutofillEditItem : CollectionViewItem // TODO(crbug.com/891299) remove when all collection and table views are fixed // for dynamic types. @@ -59,9 +59,9 @@ @end -// AutofillEditCell implements an MDCCollectionViewCell subclass containing a -// label and a text field. -@interface AutofillEditCell : MDCCollectionViewCell +// LegacyAutofillEditCell implements an MDCCollectionViewCell subclass +// containing a label and a text field. +@interface LegacyAutofillEditCell : MDCCollectionViewCell // Label at the leading edge of the cell. It displays the item's textFieldName. @property(nonatomic, strong) UILabel* textLabel; @@ -75,4 +75,4 @@ @end -#endif // IOS_CHROME_BROWSER_UI_AUTOFILL_CELLS_AUTOFILL_EDIT_ITEM_H_ +#endif // IOS_CHROME_BROWSER_UI_AUTOFILL_CELLS_LEGACY_AUTOFILL_EDIT_ITEM_H_
diff --git a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm b/ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.mm similarity index 96% rename from ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm rename to ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.mm index 2826d2ae..a17a9cef 100644 --- a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item.mm +++ b/ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_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/autofill/cells/autofill_edit_item.h" +#import "ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.h" #include "ios/chrome/browser/ui/collection_view/cells/collection_view_cell_constants.h" #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" @@ -27,14 +27,14 @@ const CGFloat kLabelAndFieldGap = 5; } // namespace -@interface AutofillEditCell () +@interface LegacyAutofillEditCell () // Updates the cell's fonts and colors for the given |cellStyle| and uses // dynamic font types if they are available (iOS 11+). - (void)updateForStyle:(CollectionViewCellStyle)cellStyle withFontScaling:(BOOL)withFontScaling; @end -@implementation AutofillEditItem +@implementation LegacyAutofillEditItem @synthesize cellStyle = _cellStyle; @synthesize textFieldName = _textFieldName; @@ -52,7 +52,7 @@ - (instancetype)initWithType:(NSInteger)type { self = [super initWithType:type]; if (self) { - self.cellClass = [AutofillEditCell class]; + self.cellClass = [LegacyAutofillEditCell class]; _cellStyle = CollectionViewCellStyle::kMaterial; _returnKeyType = UIReturnKeyNext; _keyboardType = UIKeyboardTypeDefault; @@ -63,7 +63,7 @@ #pragma mark CollectionViewItem -- (void)configureCell:(AutofillEditCell*)cell { +- (void)configureCell:(LegacyAutofillEditCell*)cell { [super configureCell:cell]; // Update fonts and colors before changing anything else. @@ -99,7 +99,7 @@ @end -@implementation AutofillEditCell { +@implementation LegacyAutofillEditCell { NSLayoutConstraint* _iconHeightConstraint; NSLayoutConstraint* _iconWidthConstraint; NSLayoutConstraint* _textFieldTrailingConstraint;
diff --git a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item_unittest.mm b/ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item_unittest.mm similarity index 74% rename from ios/chrome/browser/ui/autofill/cells/autofill_edit_item_unittest.mm rename to ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item_unittest.mm index ed34ad3..84141b8 100644 --- a/ios/chrome/browser/ui/autofill/cells/autofill_edit_item_unittest.mm +++ b/ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_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/autofill/cells/autofill_edit_item.h" +#import "ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" @@ -14,12 +14,13 @@ namespace { -using AutofillEditItemTest = PlatformTest; +using LegacyAutofillEditItemTest = PlatformTest; // Tests that the label and text field are set properly after a call to // |configureCell:|. -TEST_F(AutofillEditItemTest, ConfigureCell) { - AutofillEditItem* item = [[AutofillEditItem alloc] initWithType:0]; +TEST_F(LegacyAutofillEditItemTest, ConfigureCell) { + LegacyAutofillEditItem* item = + [[LegacyAutofillEditItem alloc] initWithType:0]; NSString* name = @"Name"; NSString* value = @"Value"; BOOL enabled = NO; @@ -29,9 +30,9 @@ item.textFieldEnabled = enabled; id cell = [[[item cellClass] alloc] init]; - ASSERT_TRUE([cell isMemberOfClass:[AutofillEditCell class]]); + ASSERT_TRUE([cell isMemberOfClass:[LegacyAutofillEditCell class]]); - AutofillEditCell* autofillEditCell = cell; + LegacyAutofillEditCell* autofillEditCell = cell; EXPECT_EQ(0U, autofillEditCell.textLabel.text.length); EXPECT_EQ(0U, autofillEditCell.textField.text.length); EXPECT_TRUE(autofillEditCell.textField.enabled);
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.mm b/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.mm index 83a603f..542ce60 100644 --- a/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.mm +++ b/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.mm
@@ -120,10 +120,13 @@ new autofill::PersonalDataManagerObserverBridge(self)); personalDataManager->AddObserver(_personalDataManagerObserver.get()); + // TODO:(crbug.com/845472) Add earl grey test to verify the credit card + // button is hidden when local cards are saved and then + // kAutofillCreditCardEnabled is changed to disabled. _manualFillAccessoryViewController.creditCardButtonHidden = - personalDataManager->GetCreditCardsToSuggest(true).empty(); + personalDataManager->GetCreditCards().empty(); - _manualFillAccessoryViewController.creditCardButtonHidden = + _manualFillAccessoryViewController.addressButtonHidden = personalDataManager->GetProfilesToSuggest().empty(); } else { _manualFillAccessoryViewController.creditCardButtonHidden = YES; @@ -270,7 +273,7 @@ DCHECK(personalDataManager); self.manualFillAccessoryViewController.creditCardButtonHidden = - personalDataManager->GetCreditCardsToSuggest(true).empty(); + personalDataManager->GetCreditCards().empty(); self.manualFillAccessoryViewController.addressButtonHidden = personalDataManager->GetProfilesToSuggest().empty();
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.mm b/ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.mm index 8c8edf3..b15e96ae 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.mm
@@ -101,7 +101,6 @@ [[TableViewPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting]; - presentationController.position = TablePresentationPositionLeading; return presentationController; } @@ -118,7 +117,6 @@ TableViewAnimator* animator = [[TableViewAnimator alloc] init]; animator.presenting = YES; - animator.direction = TableAnimatorDirectionFromLeading; return animator; }
diff --git a/ios/chrome/browser/ui/browser_view_controller.h b/ios/chrome/browser/ui/browser_view_controller.h index 02fcbb4..0251cab3 100644 --- a/ios/chrome/browser/ui/browser_view_controller.h +++ b/ios/chrome/browser/ui/browser_view_controller.h
@@ -6,7 +6,6 @@ #define IOS_CHROME_BROWSER_UI_BROWSER_VIEW_CONTROLLER_H_ #import <MessageUI/MessageUI.h> -#import <StoreKit/StoreKit.h> #import <UIKit/UIKit.h> #import "base/ios/block_types.h"
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 67ec1b9..d96ce9af1 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -51,8 +51,6 @@ #include "components/signin/ios/browser/active_state_manager.h" #include "components/strings/grit/components_strings.h" #include "ios/chrome/app/tests_hook.h" -#import "ios/chrome/browser/app_launcher/app_launcher_abuse_detector.h" -#import "ios/chrome/browser/app_launcher/app_launcher_tab_helper.h" #import "ios/chrome/browser/autofill/autofill_tab_helper.h" #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" @@ -96,8 +94,6 @@ #import "ios/chrome/browser/snapshots/snapshot_tab_helper.h" #import "ios/chrome/browser/ssl/captive_portal_detector_tab_helper.h" #import "ios/chrome/browser/ssl/captive_portal_detector_tab_helper_delegate.h" -#import "ios/chrome/browser/store_kit/store_kit_coordinator.h" -#import "ios/chrome/browser/store_kit/store_kit_tab_helper.h" #import "ios/chrome/browser/tabs/legacy_tab_helper.h" #import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_dialog_delegate.h" @@ -111,8 +107,6 @@ #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/alert_coordinator/repost_form_coordinator.h" -#import "ios/chrome/browser/ui/app_launcher/app_launcher_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" @@ -220,7 +214,6 @@ #import "ios/chrome/browser/web/page_placeholder_tab_helper.h" #include "ios/chrome/browser/web/print_tab_helper.h" #import "ios/chrome/browser/web/repost_form_tab_helper.h" -#import "ios/chrome/browser/web/repost_form_tab_helper_delegate.h" #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" @@ -426,7 +419,6 @@ PageInfoPresentation, PasswordControllerDelegate, PreloadControllerDelegate, - RepostFormTabHelperDelegate, SadTabCoordinatorDelegate, SideSwipeControllerDelegate, SnapshotGeneratorDelegate, @@ -534,9 +526,6 @@ // Coordinator for Page Info UI. PageInfoLegacyCoordinator* _pageInfoCoordinator; - // Coordinator for displaying Repost Form dialog. - RepostFormCoordinator* _repostFormCoordinator; - ToolbarCoordinatorAdaptor* _toolbarCoordinatorAdaptor; // The toolbar UI updater for the toolbar managed by |_toolbarCoordinator|. @@ -557,18 +546,12 @@ // A map associating webStates with their NTP coordinators. std::map<web::WebState*, NewTabPageCoordinator*> _ntpCoordinatorsForWebStates; - // Coordinator for presenting SKStoreProductViewController. - StoreKitCoordinator* _storeKitCoordinator; - // Coordinator for the language selection UI. LanguageSelectionCoordinator* _languageSelectionCoordinator; // Coordinator for the PassKit UI presentation. PassKitCoordinator* _passKitCoordinator; - // Coordinator for UI related to launching external apps. - AppLauncherCoordinator* _appLauncherCoordinator; - // Fake status bar view used to blend the toolbar into the status bar. UIView* _fakeStatusBarView; @@ -923,9 +906,6 @@ [[ToolbarCoordinatorAdaptor alloc] initWithDispatcher:self.dispatcher]; self.toolbarInterface = _toolbarCoordinatorAdaptor; - _storeKitCoordinator = - [[StoreKitCoordinator alloc] initWithBaseViewController:self]; - _languageSelectionCoordinator = [[LanguageSelectionCoordinator alloc] initWithBaseViewController:self]; _languageSelectionCoordinator.presenter = @@ -945,9 +925,6 @@ _downloadManagerCoordinator.presenter = [[VerticalAnimationContainer alloc] init]; - _appLauncherCoordinator = - [[AppLauncherCoordinator alloc] initWithBaseViewController:self]; - _javaScriptDialogPresenter.reset( new JavaScriptDialogPresenterImpl(_dialogPresenter)); _webStateDelegate.reset(new web::WebStateDelegateBridge(self)); @@ -2848,22 +2825,15 @@ // Install the proper CRWWebController delegates. tab.webController.nativeProvider = self; tab.webController.swipeRecognizerProvider = self.sideSwipeController; - StoreKitTabHelper* tabHelper = StoreKitTabHelper::FromWebState(tab.webState); - if (tabHelper) - tabHelper->SetLauncher(_storeKitCoordinator); tab.webState->SetDelegate(_webStateDelegate.get()); // BrowserViewController owns the coordinator that displays the Sad Tab. if (!SadTabTabHelper::FromWebState(tab.webState)) { SadTabTabHelper::CreateForWebState(tab.webState, _sadTabCoordinator); } PrintTabHelper::CreateForWebState(tab.webState, self); - RepostFormTabHelper::CreateForWebState(tab.webState, self); NetExportTabHelper::CreateForWebState(tab.webState, self); CaptivePortalDetectorTabHelper::CreateForWebState(tab.webState, self); PassKitTabHelper::CreateForWebState(tab.webState, _passKitCoordinator); - AppLauncherTabHelper::CreateForWebState( - tab.webState, [[AppLauncherAbuseDetector alloc] init], - _appLauncherCoordinator); // DownloadManagerTabHelper cannot function without delegate. DCHECK(_downloadManagerCoordinator); @@ -2912,9 +2882,6 @@ } tab.webController.nativeProvider = nil; tab.webController.swipeRecognizerProvider = nil; - StoreKitTabHelper* tabHelper = StoreKitTabHelper::FromWebState(tab.webState); - if (tabHelper) - tabHelper->SetLauncher(nil); tab.webState->SetDelegate(nullptr); if (AccountConsistencyService* accountConsistencyService = ios::AccountConsistencyServiceFactory::GetForBrowserState( @@ -5266,25 +5233,6 @@ [self.dispatcher printTab]; } -#pragma mark - RepostFormTabHelperDelegate - -- (void)repostFormTabHelper:(RepostFormTabHelper*)helper - presentRepostFormDialogForWebState:(web::WebState*)webState - dialogAtPoint:(CGPoint)location - completionHandler:(void (^)(BOOL))completion { - _repostFormCoordinator = - [[RepostFormCoordinator alloc] initWithBaseViewController:self - dialogLocation:location - webState:webState - completionHandler:completion]; - [_repostFormCoordinator start]; -} - -- (void)repostFormTabHelperDismissRepostFormDialog: - (RepostFormTabHelper*)helper { - _repostFormCoordinator = nil; -} - #pragma mark - TabStripPresentation - (BOOL)isTabStripFullyVisible {
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn index 3bfc942..d67b35b 100644 --- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -158,12 +158,14 @@ "//components/strings", "//ios/chrome/app/strings", "//ios/chrome/browser/ui", + "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/content_suggestions/cells:cells_ui", "//ios/chrome/browser/ui/location_bar:constants", "//ios/chrome/browser/ui/ntp", "//ios/chrome/browser/ui/toolbar/public", "//ios/third_party/material_components_ios", + "//ios/web/public", "//ui/base", ] configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm index ac9ca5f1..26e1b7dd 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm
@@ -11,10 +11,12 @@ #import "ios/chrome/browser/ui/location_bar/location_bar_constants.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_utils.h" +#include "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/browser/ui/util/dynamic_type_util.h" #include "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #include "ios/chrome/grit/ios_strings.h" +#include "ios/web/public/features.h" #include "ui/base/l10n/l10n_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -112,6 +114,12 @@ CGFloat doodleTopMargin(BOOL toolbarPresent, CGFloat topInset) { if (!IsCompactWidth() && !IsCompactHeight()) return kDoodleTopMarginRegularXRegular; + if (base::FeatureList::IsEnabled( + web::features::kBrowserContainerFullscreen) && + base::FeatureList::IsEnabled(web::features::kOutOfWebFullscreen) && + !base::FeatureList::IsEnabled(kBrowserContainerContainsNTP)) { + topInset = StatusBarHeight(); + } return topInset + kDoodleTopMarginOther + AlignValueToPixel(kDoodleScaledTopMarginOther * SystemSuggestedFontSizeMultiplier());
diff --git a/ios/chrome/browser/ui/download/BUILD.gn b/ios/chrome/browser/ui/download/BUILD.gn index 919d404..8744f8a0 100644 --- a/ios/chrome/browser/ui/download/BUILD.gn +++ b/ios/chrome/browser/ui/download/BUILD.gn
@@ -54,7 +54,10 @@ "//ui/base", "//ui/gfx", ] - libs = [ "UIKit.framework" ] + libs = [ + "StoreKit.framework", + "UIKit.framework", + ] } source_set("unit_tests") { @@ -75,7 +78,6 @@ "//ios/chrome/browser/download", "//ios/chrome/browser/download:test_support", "//ios/chrome/browser/infobars", - "//ios/chrome/browser/store_kit", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web:test_support", "//ios/chrome/browser/web_state_list:test_support", @@ -90,6 +92,12 @@ "//third_party/ocmock:ocmock", "//ui/base", ] + libs = [ + "MobileCoreServices.framework", + "PassKit.framework", + "StoreKit.framework", + "UIKit.framework", + ] } source_set("eg_tests") {
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm index bd7abab..ceac577 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm
@@ -170,6 +170,10 @@ // Verifies that the toolbar properly appears/disappears when scrolling up/down // on a PDF that is long in length and wide in width. - (void)testLongPDFScroll { + // TODO(crbug.com/904694): This test is failing on iOS11. + if (!base::ios::IsRunningOnIOS12OrLater()) + EARL_GREY_TEST_DISABLED(@"Disabled on iOS 11."); + // TODO(crbug.com/714329): Re-enable this test on devices. #if !TARGET_IPHONE_SIMULATOR EARL_GREY_TEST_DISABLED(@"Test disabled on device.");
diff --git a/ios/chrome/browser/ui/main/BUILD.gn b/ios/chrome/browser/ui/main/BUILD.gn index 7ca2843..55575660 100644 --- a/ios/chrome/browser/ui/main/BUILD.gn +++ b/ios/chrome/browser/ui/main/BUILD.gn
@@ -19,14 +19,18 @@ "//base", "//ios/chrome/app/resources:launchscreen_xib", "//ios/chrome/browser", + "//ios/chrome/browser/app_launcher", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/browsing_data", "//ios/chrome/browser/crash_report:crash_report_internal", "//ios/chrome/browser/device_sharing", "//ios/chrome/browser/sessions", "//ios/chrome/browser/sessions:serialisation", + "//ios/chrome/browser/store_kit", "//ios/chrome/browser/tabs", "//ios/chrome/browser/tabs:tabs_internal", + "//ios/chrome/browser/ui/alert_coordinator", + "//ios/chrome/browser/ui/app_launcher", "//ios/chrome/browser/ui/authentication/consent_bump", "//ios/chrome/browser/ui/autofill", "//ios/chrome/browser/ui/commands", @@ -35,6 +39,9 @@ "//ios/chrome/browser/ui/reading_list", "//ios/chrome/browser/ui/recent_tabs", "//ios/chrome/browser/ui/snackbar", + "//ios/chrome/browser/web", + "//ios/chrome/browser/web:tab_helper_delegates", + "//ios/chrome/browser/web_state_list", "//ios/public/provider/chrome/browser", ] public_deps = [
diff --git a/ios/chrome/browser/ui/main/browser_coordinator.mm b/ios/chrome/browser/ui/main/browser_coordinator.mm index 07902c8..c1e6246b 100644 --- a/ios/chrome/browser/ui/main/browser_coordinator.mm +++ b/ios/chrome/browser/ui/main/browser_coordinator.mm
@@ -4,6 +4,15 @@ #import "ios/chrome/browser/ui/main/browser_coordinator.h" +#include <memory> + +#include "base/scoped_observer.h" +#import "ios/chrome/browser/app_launcher/app_launcher_abuse_detector.h" +#import "ios/chrome/browser/app_launcher/app_launcher_tab_helper.h" +#import "ios/chrome/browser/store_kit/store_kit_coordinator.h" +#import "ios/chrome/browser/store_kit/store_kit_tab_helper.h" +#import "ios/chrome/browser/ui/alert_coordinator/repost_form_coordinator.h" +#import "ios/chrome/browser/ui/app_launcher/app_launcher_coordinator.h" #import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_coordinator.h" #import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_coordinator_delegate.h" #import "ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.h" @@ -16,13 +25,19 @@ #import "ios/chrome/browser/ui/reading_list/reading_list_coordinator.h" #import "ios/chrome/browser/ui/recent_tabs/recent_tabs_coordinator.h" #import "ios/chrome/browser/ui/snackbar/snackbar_coordinator.h" +#import "ios/chrome/browser/web/repost_form_tab_helper.h" +#import "ios/chrome/browser/web/repost_form_tab_helper_delegate.h" +#include "ios/chrome/browser/web_state_list/web_state_list.h" +#import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif @interface BrowserCoordinator ()<ConsentBumpCoordinatorDelegate, - FormInputAccessoryCoordinatorDelegate> + FormInputAccessoryCoordinatorDelegate, + RepostFormTabHelperDelegate, + WebStateListObserving> // Handles command dispatching. @property(nonatomic, strong) CommandDispatcher* dispatcher; @@ -31,6 +46,9 @@ // Child Coordinators, listed in alphabetical order. // ================================================= +// Coordinator for UI related to launching external apps. +@property(nonatomic, strong) AppLauncherCoordinator* appLauncherCoordinator; + // Coordinator to ask the user for the new consent. @property(nonatomic, strong) ConsentBumpCoordinator* consentBumpCoordinator; @@ -48,20 +66,35 @@ // Coordinator for Recent Tabs. @property(nonatomic, strong) RecentTabsCoordinator* recentTabsCoordinator; +// Coordinator for displaying Repost Form dialog. +@property(nonatomic, strong) RepostFormCoordinator* repostFormCoordinator; + // Coordinator for displaying snackbars. @property(nonatomic, strong) SnackbarCoordinator* snackbarCoordinator; +// Coordinator for presenting SKStoreProductViewController. +@property(nonatomic, strong) StoreKitCoordinator* storeKitCoordinator; + @end -@implementation BrowserCoordinator +@implementation BrowserCoordinator { + // Observers for WebStateList. + std::unique_ptr<WebStateListObserverBridge> _webStateListObserverBridge; + std::unique_ptr<ScopedObserver<WebStateList, WebStateListObserver>> + _scopedWebStateListObserver; +} + @synthesize dispatcher = _dispatcher; // Child coordinators +@synthesize appLauncherCoordinator = _appLauncherCoordinator; @synthesize consentBumpCoordinator = _consentBumpCoordinator; @synthesize formInputAccessoryCoordinator = _formInputAccessoryCoordinator; @synthesize qrScannerCoordinator = _qrScannerCoordinator; @synthesize readingListCoordinator = _readingListCoordinator; @synthesize recentTabsCoordinator = _recentTabsCoordinator; +@synthesize repostFormCoordinator = _repostFormCoordinator; @synthesize snackbarCoordinator = _snackbarCoordinator; +@synthesize storeKitCoordinator = _storeKitCoordinator; #pragma mark - ChromeCoordinator @@ -74,11 +107,15 @@ [self.dispatcher startDispatchingToTarget:self forProtocol:@protocol(BrowserCoordinatorCommands)]; + [self installDelegatesForAllWebStates]; + [self addWebStateListObserver]; [super start]; } - (void)stop { [super stop]; + [self removeWebStateListObserver]; + [self uninstallDelegatesForAllWebStates]; [self.dispatcher stopDispatchingToTarget:self]; [self stopChildCoordinators]; [self destroyViewController]; @@ -92,7 +129,7 @@ BrowserViewControllerDependencyFactory* factory = [[BrowserViewControllerDependencyFactory alloc] initWithBrowserState:self.browserState - webStateList:[self.tabModel webStateList]]; + webStateList:self.tabModel.webStateList]; _viewController = [[BrowserViewController alloc] initWithTabModel:self.tabModel browserState:self.browserState @@ -114,6 +151,9 @@ // coordinators. DCHECK(self.dispatcher); + self.appLauncherCoordinator = [[AppLauncherCoordinator alloc] + initWithBaseViewController:self.viewController]; + /* ConsentBumpCoordinator is created and started by a BrowserCommand */ self.formInputAccessoryCoordinator = [[FormInputAccessoryCoordinator alloc] @@ -131,13 +171,22 @@ /* RecentTabsCoordinator is created and started by a BrowserCommand */ + /* RepostFormCoordinator is created and started by a delegate method */ + self.snackbarCoordinator = [[SnackbarCoordinator alloc] init]; self.snackbarCoordinator.dispatcher = self.dispatcher; [self.snackbarCoordinator start]; + + self.storeKitCoordinator = [[StoreKitCoordinator alloc] + initWithBaseViewController:self.viewController]; } // Stops child coordinators. - (void)stopChildCoordinators { + // TODO(crbug.com/906541) : AppLauncherCoordinator is not a subclass of + // ChromeCoordinator, and does not have a |-stop| method. + self.appLauncherCoordinator = nil; + [self.consentBumpCoordinator stop]; self.consentBumpCoordinator = nil; @@ -153,8 +202,14 @@ [self.recentTabsCoordinator stop]; self.recentTabsCoordinator = nil; + [self.repostFormCoordinator stop]; + self.repostFormCoordinator = nil; + [self.snackbarCoordinator stop]; self.snackbarCoordinator = nil; + + [self.storeKitCoordinator stop]; + self.storeKitCoordinator = nil; } #pragma mark - BrowserCoordinatorCommands @@ -245,4 +300,106 @@ showCreditCardSettingsFromViewController:self.viewController]; } +#pragma mark - RepostFormTabHelperDelegate + +- (void)repostFormTabHelper:(RepostFormTabHelper*)helper + presentRepostFormDialogForWebState:(web::WebState*)webState + dialogAtPoint:(CGPoint)location + completionHandler:(void (^)(BOOL))completion { + self.repostFormCoordinator = [[RepostFormCoordinator alloc] + initWithBaseViewController:self.viewController + dialogLocation:location + webState:webState + completionHandler:completion]; + [self.repostFormCoordinator start]; +} + +- (void)repostFormTabHelperDismissRepostFormDialog: + (RepostFormTabHelper*)helper { + [self.repostFormCoordinator stop]; + self.repostFormCoordinator = nil; +} + +// TODO(crbug.com/906525) : Move WebStateListObserving out of +// BrowserCoordinator. +#pragma mark - WebStateListObserving + +- (void)webStateList:(WebStateList*)webStateList + didInsertWebState:(web::WebState*)webState + atIndex:(int)index + activating:(BOOL)activating { + [self installDelegatesForWebState:webState]; +} + +- (void)webStateList:(WebStateList*)webStateList + didReplaceWebState:(web::WebState*)oldWebState + withWebState:(web::WebState*)newWebState + atIndex:(int)index { + [self uninstallDelegatesForWebState:oldWebState]; + [self installDelegatesForWebState:newWebState]; +} + +- (void)webStateList:(WebStateList*)webStateList + didDetachWebState:(web::WebState*)webState + atIndex:(int)index { + [self uninstallDelegatesForWebState:webState]; +} + +// TODO(crbug.com/906525) : Move out of BrowserCoordinator along with +// WebStateListObserving. +#pragma mark - Private WebState management methods + +// Adds observer for WebStateList. +- (void)addWebStateListObserver { + _webStateListObserverBridge = + std::make_unique<WebStateListObserverBridge>(self); + _scopedWebStateListObserver = + std::make_unique<ScopedObserver<WebStateList, WebStateListObserver>>( + _webStateListObserverBridge.get()); + _scopedWebStateListObserver->Add(self.tabModel.webStateList); +} + +// Removes observer for WebStateList. +- (void)removeWebStateListObserver { + _scopedWebStateListObserver.reset(); + _webStateListObserverBridge.reset(); +} + +// Installs delegates for each WebState in WebStateList. +- (void)installDelegatesForAllWebStates { + for (int i = 0; i < self.tabModel.webStateList->count(); i++) { + web::WebState* webState = self.tabModel.webStateList->GetWebStateAt(i); + [self installDelegatesForWebState:webState]; + } +} + +// Uninstalls delegates for each WebState in WebStateList. +- (void)uninstallDelegatesForAllWebStates { + for (int i = 0; i < self.tabModel.webStateList->count(); i++) { + web::WebState* webState = self.tabModel.webStateList->GetWebStateAt(i); + [self uninstallDelegatesForWebState:webState]; + } +} + +// Install delegates for |webState|. +- (void)installDelegatesForWebState:(web::WebState*)webState { + AppLauncherTabHelper::CreateForWebState( + webState, [[AppLauncherAbuseDetector alloc] init], + self.appLauncherCoordinator); + + RepostFormTabHelper::CreateForWebState(webState, self); + + if (StoreKitTabHelper::FromWebState(webState)) { + StoreKitTabHelper::FromWebState(webState)->SetLauncher( + self.storeKitCoordinator); + } +} + +// Uninstalls delegates for |webState|. +- (void)uninstallDelegatesForWebState:(web::WebState*)webState { + if (StoreKitTabHelper::FromWebState(webState)) { + StoreKitTabHelper::FromWebState(webState)->SetLauncher(nil); + } +} + @end
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm index a8cae9b1..4f18f08 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
@@ -7,6 +7,7 @@ #include <memory> #include "base/ios/ios_util.h" +#include "base/metrics/histogram_macros.h" #import "ios/chrome/browser/ui/omnibox/image_retriever.h" #import "ios/chrome/browser/ui/omnibox/omnibox_util.h" #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_row.h" @@ -77,6 +78,10 @@ // this is enabled with |shortcutsEnabled|). Lazily instantiated. @property(nonatomic, strong) UITableViewCell* shortcutsCell; +// Time the view appeared on screen. Used to record a metric of how long this +// view controller was on screen. +@property(nonatomic, assign) base::TimeTicks viewAppearanceTime; + @end @implementation OmniboxPopupViewController @@ -208,6 +213,19 @@ completion:nil]; } +#pragma mark - View lifecycle + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + self.viewAppearanceTime = base::TimeTicks::Now(); +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + UMA_HISTOGRAM_MEDIUM_TIMES("MobileOmnibox.PopupOpenDuration", + base::TimeTicks::Now() - self.viewAppearanceTime); +} + #pragma mark - Properties accessors - (void)setIncognito:(BOOL)incognito {
diff --git a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_consumer.h b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_consumer.h index 4ece3fb..b57a417 100644 --- a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_consumer.h +++ b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_consumer.h
@@ -15,8 +15,8 @@ // Called immediately when the shortcuts are available for the first time. - (void)mostVisitedShortcutsAvailable: (NSArray<ShortcutsMostVisitedItem*>*)items; -// Called when the favicon of a given item has changed or reloaded. -- (void)faviconChangedForItem:(ShortcutsMostVisitedItem*)item; +// Called when the favicon of a given URL has changed or reloaded. +- (void)faviconChangedForURL:(const GURL&)url; // Called when the reading list badge count changes. - (void)readingListBadgeUpdatedWithCount:(NSInteger)count;
diff --git a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.mm b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.mm index 5dd8557..9ad61ae 100644 --- a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.mm +++ b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.mm
@@ -95,7 +95,7 @@ fetchFaviconAttributesForURL:item.URL completion:^(FaviconAttributes* attributes) { item.attributes = attributes; - [weakSelf.consumer faviconChangedForItem:item]; + [weakSelf.consumer faviconChangedForURL:item.URL]; }]; }
diff --git a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller.mm b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller.mm index 594bab4..e3d212d 100644 --- a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller.mm +++ b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller.mm
@@ -5,6 +5,9 @@ #import "ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller.h" #include "base/logging.h" +#include "base/mac/foundation_util.h" +#include "base/metrics/user_metrics.h" +#include "base/metrics/user_metrics_action.h" #import "ios/chrome/browser/ui/ntp_tile_views/ntp_most_visited_tile_view.h" #import "ios/chrome/browser/ui/ntp_tile_views/ntp_shortcut_tile_view.h" #import "ios/chrome/browser/ui/ntp_tile_views/ntp_tile_constants.h" @@ -13,6 +16,7 @@ #import "ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller_delegate.h" #import "ios/chrome/common/favicon/favicon_view.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" +#include "url/gurl.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -120,17 +124,23 @@ } } -- (void)faviconChangedForItem:(ShortcutsMostVisitedItem*)item { +- (void)faviconChangedForURL:(const GURL&)URL { if (!self.viewLoaded) { return; } - NSUInteger i = [self.displayedMostVisitedItems indexOfObject:item]; - if (i == NSNotFound) { - return; + + for (ShortcutsMostVisitedItem* item in self.displayedMostVisitedItems) { + if (item.URL == URL) { + NSUInteger i = [self.displayedMostVisitedItems indexOfObject:item]; + NSIndexPath* indexPath = + [NSIndexPath indexPathForItem:i inSection:kMostVisitedSection]; + MostVisitedShortcutCell* cell = + base::mac::ObjCCastStrict<MostVisitedShortcutCell>( + [self.collectionView cellForItemAtIndexPath:indexPath]); + [self configureMostVisitedCell:cell + withItem:self.displayedMostVisitedItems[i]]; + } } - [self.collectionView reloadItemsAtIndexPaths:@[ - [NSIndexPath indexPathForItem:i inSection:kMostVisitedSection] - ]]; } - (void)readingListBadgeUpdatedWithCount:(NSInteger)count { @@ -227,6 +237,8 @@ self.displayedMostVisitedItems[indexPath.item]; DCHECK(item); [self.commandHandler openMostVisitedItem:item]; + base::RecordAction( + base::UserMetricsAction("MobileOmniboxShortcutsOpenMostVisitedItem")); } if (indexPath.section == kCollectionShortcutSection) { @@ -234,15 +246,23 @@ switch (type) { case NTPCollectionShortcutTypeBookmark: [self.commandHandler openBookmarks]; + base::RecordAction( + base::UserMetricsAction("MobileOmniboxShortcutsOpenBookmarks")); break; case NTPCollectionShortcutTypeRecentTabs: [self.commandHandler openRecentTabs]; + base::RecordAction( + base::UserMetricsAction("MobileOmniboxShortcutsOpenRecentTabs")); break; case NTPCollectionShortcutTypeReadingList: [self.commandHandler openReadingList]; + base::RecordAction( + base::UserMetricsAction("MobileOmniboxShortcutsOpenReadingList")); break; case NTPCollectionShortcutTypeHistory: [self.commandHandler openHistory]; + base::RecordAction( + base::UserMetricsAction("MobileOmniboxShortcutsOpenHistory")); break; } }
diff --git a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm index c9a82e10..5f4c428 100644 --- a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm +++ b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm
@@ -9,7 +9,7 @@ #include "base/strings/sys_string_conversions.h" #include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/ui/autofill/autofill_edit_accessory_view.h" -#import "ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h" +#import "ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.h" #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item.h" @@ -40,10 +40,12 @@ const CGFloat kFooterCellHorizontalPadding = 16; -// Returns the AutofillEditCell that is the parent view of the |textField|. -AutofillEditCell* AutofillEditCellForTextField(UITextField* textField) { +// Returns the LegacyAutofillEditCell that is the parent view of the +// |textField|. +LegacyAutofillEditCell* AutofillEditCellForTextField(UITextField* textField) { for (UIView* view = textField; view; view = [view superview]) { - AutofillEditCell* cell = base::mac::ObjCCast<AutofillEditCell>(view); + LegacyAutofillEditCell* cell = + base::mac::ObjCCast<LegacyAutofillEditCell>(view); if (cell) return cell; } @@ -101,7 +103,7 @@ UIPickerViewDelegate, UITextFieldDelegate> { // The currently focused cell. May be nil. - __weak AutofillEditCell* _currentEditingCell; + __weak LegacyAutofillEditCell* _currentEditingCell; AutofillEditAccessoryView* _accessoryView; } @@ -133,7 +135,7 @@ // Returns the text field with the given offset relative to the currently // focused text field. May return nil. -- (AutofillEditCell*)nextTextFieldWithOffset:(NSInteger)offset; +- (LegacyAutofillEditCell*)nextTextFieldWithOffset:(NSInteger)offset; // Enables or disables the accessory view's previous and next buttons depending // on whether there is a text field before and after the currently focused text @@ -304,8 +306,8 @@ [model addSectionWithIdentifier:sectionIdentifier]; switch (field.fieldType) { case EditorFieldTypeTextField: { - AutofillEditItem* item = - [[AutofillEditItem alloc] initWithType:ItemTypeTextField]; + LegacyAutofillEditItem* item = + [[LegacyAutofillEditItem alloc] initWithType:ItemTypeTextField]; item.useScaledFont = YES; item.textFieldName = field.label; item.textFieldEnabled = field.enabled; @@ -390,8 +392,8 @@ - (void)setOptions:(NSArray<NSArray<NSString*>*>*)options forEditorField:(EditorField*)field { DCHECK(field.fieldType == EditorFieldTypeTextField); - AutofillEditItem* item = - base::mac::ObjCCastStrict<AutofillEditItem>(field.item); + LegacyAutofillEditItem* item = + base::mac::ObjCCastStrict<LegacyAutofillEditItem>(field.item); item.textFieldEnabled = field.enabled; item.textFieldValue = field.value; @@ -457,7 +459,7 @@ - (BOOL)textFieldShouldReturn:(UITextField*)textField { DCHECK([_currentEditingCell textField] == textField); - AutofillEditCell* nextCell = [self nextTextFieldWithOffset:1]; + LegacyAutofillEditCell* nextCell = [self nextTextFieldWithOffset:1]; if (nextCell) [self nextPressed]; else @@ -499,8 +501,8 @@ // Get the icon that identifies the field value and reload the cell if the // icon changes. - AutofillEditItem* item = - base::mac::ObjCCastStrict<AutofillEditItem>(field.item); + LegacyAutofillEditItem* item = + base::mac::ObjCCastStrict<LegacyAutofillEditItem>(field.item); UIImage* oldIcon = item.identifyingIcon; item.identifyingIcon = [_dataSource iconIdentifyingEditorField:field]; if (item.identifyingIcon != oldIcon) { @@ -518,13 +520,13 @@ #pragma mark - AutofillEditAccessoryDelegate - (void)nextPressed { - AutofillEditCell* nextCell = [self nextTextFieldWithOffset:1]; + LegacyAutofillEditCell* nextCell = [self nextTextFieldWithOffset:1]; if (nextCell) [nextCell.textField becomeFirstResponder]; } - (void)previousPressed { - AutofillEditCell* previousCell = [self nextTextFieldWithOffset:-1]; + LegacyAutofillEditCell* previousCell = [self nextTextFieldWithOffset:-1]; if (previousCell) [previousCell.textField becomeFirstResponder]; } @@ -601,8 +603,8 @@ [self.collectionViewModel itemAtIndexPath:indexPath]; switch (item.type) { case ItemTypeTextField: { - AutofillEditCell* autofillEditCell = - base::mac::ObjCCast<AutofillEditCell>(cell); + LegacyAutofillEditCell* autofillEditCell = + base::mac::ObjCCast<LegacyAutofillEditCell>(cell); autofillEditCell.textField.delegate = self; autofillEditCell.textField.clearButtonMode = UITextFieldViewModeNever; SetUILabelScaledFont(autofillEditCell.textLabel, @@ -679,8 +681,8 @@ id cell = [collectionView cellForItemAtIndexPath:indexPath]; // |cell| may be nil if the cell is not visible. if (cell) { - AutofillEditCell* autofillEditCell = - base::mac::ObjCCastStrict<AutofillEditCell>(cell); + LegacyAutofillEditCell* autofillEditCell = + base::mac::ObjCCastStrict<LegacyAutofillEditCell>(cell); [autofillEditCell.textField becomeFirstResponder]; } } @@ -750,7 +752,7 @@ return nil; } -- (AutofillEditCell*)nextTextFieldWithOffset:(NSInteger)offset { +- (LegacyAutofillEditCell*)nextTextFieldWithOffset:(NSInteger)offset { UICollectionView* collectionView = [self collectionView]; NSIndexPath* currentCellPath = [self indexPathForCurrentTextField]; DCHECK(currentCellPath); @@ -758,7 +760,7 @@ [self indexPathWithSectionOffset:offset fromPath:currentCellPath]; while (nextCellPath) { id nextCell = [collectionView cellForItemAtIndexPath:nextCellPath]; - if ([nextCell isKindOfClass:[AutofillEditCell class]]) + if ([nextCell isKindOfClass:[LegacyAutofillEditCell class]]) return nextCell; nextCellPath = [self indexPathWithSectionOffset:offset fromPath:nextCellPath]; @@ -767,10 +769,10 @@ } - (void)updateAccessoryViewButtonsStates { - AutofillEditCell* previousCell = [self nextTextFieldWithOffset:-1]; + LegacyAutofillEditCell* previousCell = [self nextTextFieldWithOffset:-1]; [[_accessoryView previousButton] setEnabled:previousCell != nil]; - AutofillEditCell* nextCell = [self nextTextFieldWithOffset:1]; + LegacyAutofillEditCell* nextCell = [self nextTextFieldWithOffset:1]; [[_accessoryView nextButton] setEnabled:nextCell != nil]; } @@ -823,8 +825,8 @@ id cell = [[self collectionView] cellForItemAtIndexPath:indexPath]; // |cell| may be nil if the cell is not visible. if (cell) { - AutofillEditCell* autofillEditCell = - base::mac::ObjCCastStrict<AutofillEditCell>(cell); + LegacyAutofillEditCell* autofillEditCell = + base::mac::ObjCCastStrict<LegacyAutofillEditCell>(cell); [autofillEditCell.textField becomeFirstResponder]; } }
diff --git a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_unittest.mm b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_unittest.mm index 2c29a04..706270d 100644 --- a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller_unittest.mm
@@ -7,7 +7,7 @@ #include "base/mac/foundation_util.h" #include "base/memory/ptr_util.h" #import "ios/chrome/browser/ui/autofill/autofill_ui_type.h" -#import "ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h" +#import "ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.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" @@ -127,10 +127,10 @@ id item = GetCollectionViewItem(0, 0); EXPECT_TRUE([item isMemberOfClass:[CollectionViewTextItem class]]); - // The next section has one item of the type AutofillEditItem. + // The next section has one item of the type LegacyAutofillEditItem. ASSERT_EQ(1U, static_cast<unsigned int>(NumberOfItemsInSection(1))); item = GetCollectionViewItem(1, 0); - EXPECT_TRUE([item isMemberOfClass:[AutofillEditItem class]]); + EXPECT_TRUE([item isMemberOfClass:[LegacyAutofillEditItem class]]); // The next section has one item of the type PaymentsSelectorEditItem. ASSERT_EQ(1U, static_cast<unsigned int>(NumberOfItemsInSection(2)));
diff --git a/ios/chrome/browser/ui/payments/payment_request_editor_field.h b/ios/chrome/browser/ui/payments/payment_request_editor_field.h index f62ff55..82a5d950 100644 --- a/ios/chrome/browser/ui/payments/payment_request_editor_field.h +++ b/ios/chrome/browser/ui/payments/payment_request_editor_field.h
@@ -46,7 +46,7 @@ UITextAutocapitalizationType autoCapitalizationType; // The associated CollectionViewItem instance. May be nil. @property(nonatomic, strong) CollectionViewItem* item; -// The section identifier for the associated AutofillEditItem. +// The section identifier for the associated LegacyAutofillEditItem. @property(nonatomic, assign) NSInteger sectionIdentifier; // Whether the field has been modified or not. @property(nonatomic, getter=isPristine) BOOL pristine;
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn index c8ba8cc..45be7a2c 100644 --- a/ios/chrome/browser/ui/settings/BUILD.gn +++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -67,15 +67,15 @@ "password_details_collection_view_controller_delegate.h", "password_exporter.h", "password_exporter.mm", - "privacy_collection_view_controller.h", - "privacy_collection_view_controller.mm", + "privacy_table_view_controller.h", + "privacy_table_view_controller.mm", "reauthentication_module.h", "reauthentication_module.mm", "reauthentication_protocol.h", "save_passwords_collection_view_controller.h", "save_passwords_collection_view_controller.mm", - "search_engine_settings_collection_view_controller.h", - "search_engine_settings_collection_view_controller.mm", + "search_engine_table_view_controller.h", + "search_engine_table_view_controller.mm", "settings_collection_view_controller.h", "settings_collection_view_controller.mm", "settings_navigation_controller.h", @@ -254,7 +254,6 @@ "//ios/chrome/browser/prefs:browser_prefs", "//ios/chrome/browser/signin", "//ios/chrome/browser/signin:test_support", - "//ios/chrome/browser/store_kit", "//ios/chrome/browser/sync", "//ios/chrome/browser/sync:test_support", "//ios/chrome/browser/ui/collection_view:test_support", @@ -282,10 +281,10 @@ "import_data_collection_view_controller_unittest.mm", "password_details_collection_view_controller_unittest.mm", "password_exporter_unittest.mm", - "privacy_collection_view_controller_unittest.mm", + "privacy_table_view_controller_unittest.mm", "reauthentication_module_unittest.mm", "save_passwords_collection_view_controller_unittest.mm", - "search_engine_settings_collection_view_controller_unittest.mm", + "search_engine_table_view_controller_unittest.mm", "settings_navigation_controller_unittest.mm", "settings_root_collection_view_controller_unittest.mm", "settings_root_table_view_controller_unittest.mm",
diff --git a/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm b/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm index b30293b9..1d6a6e5b 100644 --- a/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm
@@ -19,7 +19,7 @@ #include "ios/chrome/browser/application_context.h" #import "ios/chrome/browser/ui/autofill/autofill_ui_type.h" #import "ios/chrome/browser/ui/autofill/autofill_ui_type_util.h" -#import "ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h" +#import "ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.h" #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h" @@ -117,8 +117,9 @@ for (NSInteger itemIndex = 0; itemIndex < itemCount; ++itemIndex) { NSIndexPath* path = [NSIndexPath indexPathForItem:itemIndex inSection:section]; - AutofillEditItem* item = base::mac::ObjCCastStrict<AutofillEditItem>( - [model itemAtIndexPath:path]); + LegacyAutofillEditItem* item = + base::mac::ObjCCastStrict<LegacyAutofillEditItem>( + [model itemAtIndexPath:path]); _creditCard.SetInfo(autofill::AutofillType(AutofillTypeFromAutofillUIType( item.autofillUIType)), base::SysNSStringToUTF16(item.textFieldValue), @@ -143,8 +144,8 @@ BOOL isEditing = self.editor.editing; [model addSectionWithIdentifier:SectionIdentifierFields]; - AutofillEditItem* cardholderNameitem = - [[AutofillEditItem alloc] initWithType:ItemTypeCardholderName]; + LegacyAutofillEditItem* cardholderNameitem = + [[LegacyAutofillEditItem alloc] initWithType:ItemTypeCardholderName]; cardholderNameitem.cellStyle = CollectionViewCellStyle::kUIKit; cardholderNameitem.textFieldName = l10n_util::GetNSString(IDS_IOS_AUTOFILL_CARDHOLDER); @@ -156,8 +157,8 @@ toSectionWithIdentifier:SectionIdentifierFields]; // Card number (PAN). - AutofillEditItem* cardNumberItem = - [[AutofillEditItem alloc] initWithType:ItemTypeCardNumber]; + LegacyAutofillEditItem* cardNumberItem = + [[LegacyAutofillEditItem alloc] initWithType:ItemTypeCardNumber]; cardNumberItem.cellStyle = CollectionViewCellStyle::kUIKit; cardNumberItem.textFieldName = l10n_util::GetNSString(IDS_IOS_AUTOFILL_CARD_NUMBER); @@ -176,8 +177,8 @@ toSectionWithIdentifier:SectionIdentifierFields]; // Expiration month. - AutofillEditItem* expirationMonthItem = - [[AutofillEditItem alloc] initWithType:ItemTypeExpirationMonth]; + LegacyAutofillEditItem* expirationMonthItem = + [[LegacyAutofillEditItem alloc] initWithType:ItemTypeExpirationMonth]; expirationMonthItem.cellStyle = CollectionViewCellStyle::kUIKit; expirationMonthItem.textFieldName = l10n_util::GetNSString(IDS_IOS_AUTOFILL_EXP_MONTH); @@ -190,8 +191,8 @@ toSectionWithIdentifier:SectionIdentifierFields]; // Expiration year. - AutofillEditItem* expirationYearItem = - [[AutofillEditItem alloc] initWithType:ItemTypeExpirationYear]; + LegacyAutofillEditItem* expirationYearItem = + [[LegacyAutofillEditItem alloc] initWithType:ItemTypeExpirationYear]; expirationYearItem.cellStyle = CollectionViewCellStyle::kUIKit; expirationYearItem.textFieldName = l10n_util::GetNSString(IDS_IOS_AUTOFILL_EXP_YEAR); @@ -227,8 +228,9 @@ // Find the respective item for the text field. NSIndexPath* indexPath = [self indexPathForCurrentTextField]; DCHECK(indexPath); - AutofillEditItem* item = base::mac::ObjCCastStrict<AutofillEditItem>( - [self.collectionViewModel itemAtIndexPath:indexPath]); + LegacyAutofillEditItem* item = + base::mac::ObjCCastStrict<LegacyAutofillEditItem>( + [self.collectionViewModel itemAtIndexPath:indexPath]); // If the user is typing in the credit card number field, update the card type // icon (e.g. "Visa") to reflect the number being typed. @@ -271,7 +273,8 @@ NSInteger itemType = [self.collectionViewModel itemTypeForIndexPath:indexPath]; - AutofillEditCell* textFieldCell = base::mac::ObjCCast<AutofillEditCell>(cell); + LegacyAutofillEditCell* textFieldCell = + base::mac::ObjCCast<LegacyAutofillEditCell>(cell); textFieldCell.textField.delegate = self; switch (itemType) { case ItemTypeCardholderName:
diff --git a/ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller.mm b/ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller.mm index fb72c0d..e519c30 100644 --- a/ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller.mm
@@ -7,7 +7,7 @@ #include "base/logging.h" #import "base/mac/foundation_util.h" #import "ios/chrome/browser/ui/autofill/autofill_edit_accessory_view.h" -#import "ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h" +#import "ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.h" #import "ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller+protected.h" #import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h" @@ -17,10 +17,11 @@ namespace { -AutofillEditCell* AutofillEditCellForTextField(UITextField* textField) { - AutofillEditCell* settingsCell = nil; +LegacyAutofillEditCell* AutofillEditCellForTextField(UITextField* textField) { + LegacyAutofillEditCell* settingsCell = nil; for (UIView* view = textField; view; view = [view superview]) { - AutofillEditCell* cell = base::mac::ObjCCast<AutofillEditCell>(view); + LegacyAutofillEditCell* cell = + base::mac::ObjCCast<LegacyAutofillEditCell>(view); if (cell) { settingsCell = cell; break; @@ -36,7 +37,7 @@ @interface AutofillEditCollectionViewController ()< AutofillEditAccessoryDelegate> { - AutofillEditCell* _currentEditingCell; + LegacyAutofillEditCell* _currentEditingCell; AutofillEditAccessoryView* _accessoryView; } @end @@ -106,14 +107,14 @@ #pragma mark - UITextFieldDelegate - (void)textFieldDidBeginEditing:(UITextField*)textField { - AutofillEditCell* cell = AutofillEditCellForTextField(textField); + LegacyAutofillEditCell* cell = AutofillEditCellForTextField(textField); _currentEditingCell = cell; [textField setInputAccessoryView:_accessoryView]; [self updateAccessoryViewButtonState]; } - (void)textFieldDidEndEditing:(UITextField*)textField { - AutofillEditCell* cell = AutofillEditCellForTextField(textField); + LegacyAutofillEditCell* cell = AutofillEditCellForTextField(textField); DCHECK(_currentEditingCell == cell); [textField setInputAccessoryView:nil]; _currentEditingCell = nil; @@ -156,8 +157,9 @@ if (!nextCellPath) { [[_currentEditingCell textField] resignFirstResponder]; } else { - AutofillEditCell* nextCell = base::mac::ObjCCastStrict<AutofillEditCell>( - [collectionView cellForItemAtIndexPath:nextCellPath]); + LegacyAutofillEditCell* nextCell = + base::mac::ObjCCastStrict<LegacyAutofillEditCell>( + [collectionView cellForItemAtIndexPath:nextCellPath]); [nextCell.textField becomeFirstResponder]; } }
diff --git a/ios/chrome/browser/ui/settings/autofill_profile_edit_collection_view_controller.mm b/ios/chrome/browser/ui/settings/autofill_profile_edit_collection_view_controller.mm index 1e90faa..ce3a1b9 100644 --- a/ios/chrome/browser/ui/settings/autofill_profile_edit_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/autofill_profile_edit_collection_view_controller.mm
@@ -14,7 +14,7 @@ #include "ios/chrome/browser/application_context.h" #import "ios/chrome/browser/ui/autofill/autofill_ui_type.h" #import "ios/chrome/browser/ui/autofill/autofill_ui_type_util.h" -#import "ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h" +#import "ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.h" #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" #include "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h" @@ -149,8 +149,9 @@ for (NSInteger itemIndex = 0; itemIndex < itemCount; ++itemIndex) { NSIndexPath* path = [NSIndexPath indexPathForItem:itemIndex inSection:section]; - AutofillEditItem* item = base::mac::ObjCCastStrict<AutofillEditItem>( - [model itemAtIndexPath:path]); + LegacyAutofillEditItem* item = + base::mac::ObjCCastStrict<LegacyAutofillEditItem>( + [model itemAtIndexPath:path]); autofill::ServerFieldType serverFieldType = AutofillTypeFromAutofillUIType(item.autofillUIType); if (item.autofillUIType == AutofillUITypeProfileHomeAddressCountry) { @@ -183,8 +184,8 @@ [model addSectionWithIdentifier:SectionIdentifierFields]; for (size_t i = 0; i < base::size(kFieldsToDisplay); ++i) { const AutofillFieldDisplayInfo& field = kFieldsToDisplay[i]; - AutofillEditItem* item = - [[AutofillEditItem alloc] initWithType:ItemTypeField]; + LegacyAutofillEditItem* item = + [[LegacyAutofillEditItem alloc] initWithType:ItemTypeField]; item.cellStyle = CollectionViewCellStyle::kUIKit; item.textFieldName = l10n_util::GetNSString(field.displayStringID); item.textFieldValue = base::SysUTF16ToNSString(_autofillProfile.GetInfo( @@ -220,8 +221,8 @@ UICollectionViewCell* cell = [super collectionView:collectionView cellForItemAtIndexPath:indexPath]; - AutofillEditCell* textFieldCell = - base::mac::ObjCCastStrict<AutofillEditCell>(cell); + LegacyAutofillEditCell* textFieldCell = + base::mac::ObjCCastStrict<LegacyAutofillEditCell>(cell); textFieldCell.accessibilityIdentifier = textFieldCell.textLabel.text; textFieldCell.textField.delegate = self; return textFieldCell; @@ -234,8 +235,8 @@ if (self.editor.editing) { UICollectionViewCell* cell = [self.collectionView cellForItemAtIndexPath:indexPath]; - AutofillEditCell* textFieldCell = - base::mac::ObjCCastStrict<AutofillEditCell>(cell); + LegacyAutofillEditCell* textFieldCell = + base::mac::ObjCCastStrict<LegacyAutofillEditCell>(cell); [textFieldCell.textField becomeFirstResponder]; } return [super collectionView:collectionView
diff --git a/ios/chrome/browser/ui/settings/google_services_settings_egtest.mm b/ios/chrome/browser/ui/settings/google_services_settings_egtest.mm index 9bb32d2..bee7945 100644 --- a/ios/chrome/browser/ui/settings/google_services_settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/google_services_settings_egtest.mm
@@ -147,10 +147,8 @@ // Tests that "Activity and Interactions" switch should be disabled when the // "History" sync is off. - (void)testActivityAndInteractionsDisabledWithHistoryDisabled { -// TODO(crbug.com/906680): Re-enable this test when it's fixed. -#if TARGET_IPHONE_SIMULATOR + // TODO(crbug.com/906680): Re-enable this test when it's fixed. EARL_GREY_TEST_DISABLED(@"Test disabled on simulators."); -#endif [SigninEarlGreyUI signinWithIdentity:[SigninEarlGreyUtils fakeIdentity1]]; [self resetUnifiedConsent];
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 bba7250..4291228 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
@@ -15,8 +15,8 @@ #import "ios/chrome/browser/ui/authentication/signin_promo_view_configurator.h" #import "ios/chrome/browser/ui/authentication/signin_promo_view_delegate.h" #import "ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h" -#import "ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h" #import "ios/chrome/browser/ui/autofill/cells/cvc_item.h" +#import "ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.h" #import "ios/chrome/browser/ui/autofill/cells/status_item.h" #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_account_item.h" @@ -721,8 +721,8 @@ } - (CollectionViewItem*)autofillEditItem { - AutofillEditItem* item = - [[AutofillEditItem alloc] initWithType:ItemTypeAutofillDynamicHeight]; + LegacyAutofillEditItem* item = [[LegacyAutofillEditItem alloc] + initWithType:ItemTypeAutofillDynamicHeight]; item.cellStyle = CollectionViewCellStyle::kUIKit; item.textFieldName = @"Required Card Number"; item.textFieldValue = @"4111111111111111"; @@ -732,8 +732,8 @@ } - (CollectionViewItem*)autofillEditItemWithIcon { - AutofillEditItem* item = - [[AutofillEditItem alloc] initWithType:ItemTypeAutofillDynamicHeight]; + LegacyAutofillEditItem* item = [[LegacyAutofillEditItem alloc] + initWithType:ItemTypeAutofillDynamicHeight]; item.cellStyle = CollectionViewCellStyle::kUIKit; item.textFieldName = @"Card Number"; item.textFieldValue = @"4111111111111111";
diff --git a/ios/chrome/browser/ui/settings/privacy_collection_view_controller.h b/ios/chrome/browser/ui/settings/privacy_collection_view_controller.h deleted file mode 100644 index 73a0faa..0000000 --- a/ios/chrome/browser/ui/settings/privacy_collection_view_controller.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRIVACY_COLLECTION_VIEW_CONTROLLER_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_PRIVACY_COLLECTION_VIEW_CONTROLLER_H_ - -#import "ios/chrome/browser/ui/settings/settings_root_collection_view_controller.h" - -namespace ios { -class ChromeBrowserState; -} // namespace ios - -// The accessibility identifier of the privacy settings collection view. -extern NSString* const kPrivacyCollectionViewId; - -@interface PrivacyCollectionViewController - : SettingsRootCollectionViewController - -// |browserState| cannot be nil -- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState - NS_DESIGNATED_INITIALIZER; - -- (instancetype)initWithLayout:(UICollectionViewLayout*)layout - style:(CollectionViewControllerStyle)style - NS_UNAVAILABLE; - -- (instancetype)init NS_UNAVAILABLE; - -@end - -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRIVACY_COLLECTION_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/privacy_table_view_controller.h b/ios/chrome/browser/ui/settings/privacy_table_view_controller.h new file mode 100644 index 0000000..6e6a2fc8 --- /dev/null +++ b/ios/chrome/browser/ui/settings/privacy_table_view_controller.h
@@ -0,0 +1,30 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PRIVACY_TABLE_VIEW_CONTROLLER_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_PRIVACY_TABLE_VIEW_CONTROLLER_H_ + +#import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h" + +namespace ios { +class ChromeBrowserState; +} // namespace ios + +// The accessibility identifier of the privacy settings collection view. +extern NSString* const kPrivacyTableViewId; + +@interface PrivacyTableViewController : SettingsRootTableViewController + +// |browserState| cannot be nil +- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState + NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithTableViewStyle:(UITableViewStyle)style + appBarStyle: + (ChromeTableViewControllerStyle)appBarStyle + NS_UNAVAILABLE; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PRIVACY_TABLE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/privacy_collection_view_controller.mm b/ios/chrome/browser/ui/settings/privacy_table_view_controller.mm similarity index 64% rename from ios/chrome/browser/ui/settings/privacy_collection_view_controller.mm rename to ios/chrome/browser/ui/settings/privacy_table_view_controller.mm index cf8da0d..8e780c6 100644 --- a/ios/chrome/browser/ui/settings/privacy_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/privacy_table_view_controller.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/privacy_collection_view_controller.h" +#import "ios/chrome/browser/ui/settings/privacy_table_view_controller.h" #include "base/logging.h" #import "base/mac/foundation_util.h" @@ -23,23 +23,22 @@ #include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/experimental_flags.h" #include "ios/chrome/browser/pref_names.h" -#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h" -#import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h" -#import "ios/chrome/browser/ui/collection_view/collection_view_model.h" #import "ios/chrome/browser/ui/settings/accounts_collection_view_controller.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/settings_text_item.h" +#import "ios/chrome/browser/ui/settings/cells/settings_cells_constants.h" +#import "ios/chrome/browser/ui/settings/cells/settings_detail_item.h" +#import "ios/chrome/browser/ui/settings/cells/settings_switch_item.h" #import "ios/chrome/browser/ui/settings/clear_browsing_data_collection_view_controller.h" #import "ios/chrome/browser/ui/settings/dataplan_usage_table_view_controller.h" #import "ios/chrome/browser/ui/settings/handoff_table_view_controller.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/chrome/browser/ui/settings/settings_utils.h" #import "ios/chrome/browser/ui/settings/utils/pref_backed_boolean.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_link_header_footer_item.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h" #include "ios/chrome/browser/ui/util/ui_util.h" #include "ios/chrome/grit/ios_chromium_strings.h" #include "ios/chrome/grit/ios_strings.h" -#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" #include "url/gurl.h" @@ -48,14 +47,13 @@ #error "This file requires ARC support." #endif -NSString* const kPrivacyCollectionViewId = @"kPrivacyCollectionViewId"; +NSString* const kPrivacyTableViewId = @"kPrivacyTableViewId"; namespace { typedef NS_ENUM(NSInteger, SectionIdentifier) { SectionIdentifierOtherDevices = kSectionIdentifierEnumZero, SectionIdentifierWebServices, - SectionIdentifierWebServicesFooter, SectionIdentifierCanMakePayment, SectionIdentifierClearBrowsingData, }; @@ -64,21 +62,21 @@ ItemTypeOtherDevicesHeader = kItemTypeEnumZero, ItemTypeOtherDevicesHandoff, ItemTypeWebServicesHeader, - ItemTypeWebServicesFooter, ItemTypeWebServicesShowSuggestions, ItemTypeWebServicesSendUsageData, + ItemTypeWebServicesFooter, ItemTypeCanMakePaymentSwitch, ItemTypeClearBrowsingDataClear, }; } // namespace -@interface PrivacyCollectionViewController ()<BooleanObserver, - PrefObserverDelegate> { +@interface PrivacyTableViewController ()<BooleanObserver, + PrefObserverDelegate> { ios::ChromeBrowserState* _browserState; // weak PrefBackedBoolean* _suggestionsEnabled; // The item related to the switch for the show suggestions setting. - LegacySettingsSwitchItem* _showSuggestionsItem; + SettingsSwitchItem* _showSuggestionsItem; // Pref observer to track changes to prefs. std::unique_ptr<PrefObserverBridge> _prefObserverBridge; @@ -87,34 +85,25 @@ PrefChangeRegistrar _prefChangeRegistrarApplicationContext; // Updatable Items - LegacySettingsDetailItem* _handoffDetailItem; - LegacySettingsDetailItem* _sendUsageDetailItem; + SettingsDetailItem* _handoffDetailItem; + SettingsDetailItem* _sendUsageDetailItem; } -// Initialization methods for various model items. -- (CollectionViewItem*)handoffDetailItem; -- (LegacySettingsSwitchItem*)showSuggestionsSwitchItem; -- (CollectionViewItem*)showSuggestionsFooterItem; -- (CollectionViewItem*)clearBrowsingDetailItem; -- (CollectionViewItem*)canMakePaymentItem; -- (CollectionViewItem*)sendUsageDetailItem; - @end -@implementation PrivacyCollectionViewController +@implementation PrivacyTableViewController #pragma mark - Initialization - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState { DCHECK(browserState); - UICollectionViewLayout* layout = [[MDCCollectionViewFlowLayout alloc] init]; self = - [super initWithLayout:layout style:CollectionViewControllerStyleAppBar]; + [super initWithTableViewStyle:UITableViewStyleGrouped + appBarStyle:ChromeTableViewControllerStyleWithAppBar]; if (self) { _browserState = browserState; self.title = l10n_util::GetNSString(IDS_OPTIONS_ADVANCED_SECTION_TITLE_PRIVACY); - self.collectionViewAccessibilityIdentifier = kPrivacyCollectionViewId; if (!unified_consent::IsUnifiedConsentFeatureEnabled()) { // When unified consent flag is enabled, the suggestion setting is // available in the "Google Services and sync" settings. @@ -140,28 +129,33 @@ _prefObserverBridge->ObserveChangesForPreference( prefs::kMetricsReportingWifiOnly, &_prefChangeRegistrarApplicationContext); - - // TODO(crbug.com/764578): -loadModel should not be called from - // initializer. A possible fix is to move this call to -viewDidLoad. - [self loadModel]; } return self; } -#pragma mark - SettingsRootCollectionViewController +#pragma mark - UIViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.tableView.accessibilityIdentifier = kPrivacyTableViewId; + + [self loadModel]; +} + +#pragma mark - ChromeTableViewController - (void)loadModel { [super loadModel]; - CollectionViewModel* model = self.collectionViewModel; + TableViewModel* model = self.tableViewModel; // Other Devices Section [model addSectionWithIdentifier:SectionIdentifierOtherDevices]; - SettingsTextItem* otherDevicesHeader = - [[SettingsTextItem alloc] initWithType:ItemTypeOtherDevicesHeader]; + TableViewTextHeaderFooterItem* otherDevicesHeader = + [[TableViewTextHeaderFooterItem alloc] + initWithType:ItemTypeOtherDevicesHeader]; otherDevicesHeader.text = l10n_util::GetNSString(IDS_IOS_OPTIONS_CONTINUITY_LABEL); - otherDevicesHeader.textColor = [[MDCPalette greyPalette] tint500]; [model setHeader:otherDevicesHeader forSectionWithIdentifier:SectionIdentifierOtherDevices]; [model addItem:[self handoffDetailItem] @@ -172,11 +166,11 @@ // Otherwise the metrics reporting and show suggestions feature are // available in the Google services settings. [model addSectionWithIdentifier:SectionIdentifierWebServices]; - SettingsTextItem* webServicesHeader = - [[SettingsTextItem alloc] initWithType:ItemTypeWebServicesHeader]; + TableViewTextHeaderFooterItem* webServicesHeader = + [[TableViewTextHeaderFooterItem alloc] + initWithType:ItemTypeWebServicesHeader]; webServicesHeader.text = l10n_util::GetNSString(IDS_IOS_OPTIONS_WEB_SERVICES_LABEL); - webServicesHeader.textColor = [[MDCPalette greyPalette] tint500]; [model setHeader:webServicesHeader forSectionWithIdentifier:SectionIdentifierWebServices]; // When unified consent flag is enabled, the show suggestions feature and @@ -187,10 +181,8 @@ toSectionWithIdentifier:SectionIdentifierWebServices]; [model addItem:[self sendUsageDetailItem] toSectionWithIdentifier:SectionIdentifierWebServices]; - // Footer Section - [model addSectionWithIdentifier:SectionIdentifierWebServicesFooter]; - [model addItem:[self showSuggestionsFooterItem] - toSectionWithIdentifier:SectionIdentifierWebServicesFooter]; + [model setFooter:[self showSuggestionsFooterItem] + forSectionWithIdentifier:SectionIdentifierWebServices]; } // CanMakePayment Section @@ -206,7 +198,7 @@ #pragma mark - Model Objects -- (CollectionViewItem*)handoffDetailItem { +- (TableViewItem*)handoffDetailItem { NSString* detailText = _browserState->GetPrefs()->GetBoolean(prefs::kIosHandoffToOtherDevices) ? l10n_util::GetNSString(IDS_IOS_SETTING_ON) @@ -219,10 +211,9 @@ return _handoffDetailItem; } -- (LegacySettingsSwitchItem*)showSuggestionsSwitchItem { - LegacySettingsSwitchItem* showSuggestionsSwitchItem = - [[LegacySettingsSwitchItem alloc] - initWithType:ItemTypeWebServicesShowSuggestions]; +- (SettingsSwitchItem*)showSuggestionsSwitchItem { + SettingsSwitchItem* showSuggestionsSwitchItem = [[SettingsSwitchItem alloc] + initWithType:ItemTypeWebServicesShowSuggestions]; showSuggestionsSwitchItem.text = l10n_util::GetNSString(IDS_IOS_OPTIONS_SEARCH_URL_SUGGESTIONS); showSuggestionsSwitchItem.on = [_suggestionsEnabled value]; @@ -230,30 +221,28 @@ return showSuggestionsSwitchItem; } -- (CollectionViewItem*)showSuggestionsFooterItem { - CollectionViewFooterItem* showSuggestionsFooterItem = - [[CollectionViewFooterItem alloc] initWithType:ItemTypeWebServicesFooter]; - showSuggestionsFooterItem.cellStyle = CollectionViewCellStyle::kUIKit; +- (TableViewHeaderFooterItem*)showSuggestionsFooterItem { + TableViewLinkHeaderFooterItem* showSuggestionsFooterItem = + [[TableViewLinkHeaderFooterItem alloc] + initWithType:ItemTypeWebServicesFooter]; showSuggestionsFooterItem.text = l10n_util::GetNSString(IDS_IOS_OPTIONS_PRIVACY_FOOTER); showSuggestionsFooterItem.linkURL = google_util::AppendGoogleLocaleParam( GURL(kPrivacyLearnMoreURL), GetApplicationContext()->GetApplicationLocale()); - showSuggestionsFooterItem.linkDelegate = self; return showSuggestionsFooterItem; } -- (CollectionViewItem*)clearBrowsingDetailItem { +- (TableViewItem*)clearBrowsingDetailItem { return [self detailItemWithType:ItemTypeClearBrowsingDataClear titleId:IDS_IOS_CLEAR_BROWSING_DATA_TITLE detailText:nil]; } -- (CollectionViewItem*)canMakePaymentItem { - LegacySettingsSwitchItem* canMakePaymentItem = - [[LegacySettingsSwitchItem alloc] - initWithType:ItemTypeCanMakePaymentSwitch]; +- (TableViewItem*)canMakePaymentItem { + SettingsSwitchItem* canMakePaymentItem = + [[SettingsSwitchItem alloc] initWithType:ItemTypeCanMakePaymentSwitch]; canMakePaymentItem.text = l10n_util::GetNSString(IDS_SETTINGS_CAN_MAKE_PAYMENT_TOGGLE_LABEL); canMakePaymentItem.on = [self isCanMakePaymentEnabled]; @@ -270,7 +259,7 @@ isEnabled); } -- (CollectionViewItem*)sendUsageDetailItem { +- (TableViewItem*)sendUsageDetailItem { NSString* detailText = [DataplanUsageTableViewController currentLabelForPreference:GetApplicationContext()->GetLocalState() basePref:metrics::prefs::kMetricsReportingEnabled @@ -283,52 +272,63 @@ return _sendUsageDetailItem; } -- (LegacySettingsDetailItem*)detailItemWithType:(NSInteger)type - titleId:(NSInteger)titleId - detailText:(NSString*)detailText { - LegacySettingsDetailItem* detailItem = - [[LegacySettingsDetailItem alloc] initWithType:type]; +- (SettingsDetailItem*)detailItemWithType:(NSInteger)type + titleId:(NSInteger)titleId + detailText:(NSString*)detailText { + SettingsDetailItem* detailItem = + [[SettingsDetailItem alloc] initWithType:type]; detailItem.text = l10n_util::GetNSString(titleId); detailItem.detailText = detailText; - detailItem.accessoryType = MDCCollectionViewCellAccessoryDisclosureIndicator; + detailItem.accessoryType = UITableViewCellAccessoryDisclosureIndicator; detailItem.accessibilityTraits |= UIAccessibilityTraitButton; return detailItem; } -#pragma mark UICollectionViewDataSource +#pragma mark - UITableViewDataSource -- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView - cellForItemAtIndexPath:(NSIndexPath*)indexPath { - UICollectionViewCell* cell = - [super collectionView:collectionView cellForItemAtIndexPath:indexPath]; +- (UITableViewCell*)tableView:(UITableView*)tableView + cellForRowAtIndexPath:(NSIndexPath*)indexPath { + UITableViewCell* cell = + [super tableView:tableView cellForRowAtIndexPath:indexPath]; - NSInteger itemType = - [self.collectionViewModel itemTypeForIndexPath:indexPath]; + NSInteger itemType = [self.tableViewModel itemTypeForIndexPath:indexPath]; if (itemType == ItemTypeWebServicesShowSuggestions) { - LegacySettingsSwitchCell* switchCell = - base::mac::ObjCCastStrict<LegacySettingsSwitchCell>(cell); + SettingsSwitchCell* switchCell = + base::mac::ObjCCastStrict<SettingsSwitchCell>(cell); [switchCell.switchView addTarget:self action:@selector(showSuggestionsToggled:) forControlEvents:UIControlEventValueChanged]; } else if (itemType == ItemTypeCanMakePaymentSwitch) { - LegacySettingsSwitchCell* switchCell = - base::mac::ObjCCastStrict<LegacySettingsSwitchCell>(cell); + SettingsSwitchCell* switchCell = + base::mac::ObjCCastStrict<SettingsSwitchCell>(cell); [switchCell.switchView addTarget:self action:@selector(canMakePaymentSwitchChanged:) forControlEvents:UIControlEventValueChanged]; } - return cell; } -#pragma mark UICollectionViewDelegate -- (void)collectionView:(UICollectionView*)collectionView - didSelectItemAtIndexPath:(NSIndexPath*)indexPath { - [super collectionView:collectionView didSelectItemAtIndexPath:indexPath]; - NSInteger itemType = - [self.collectionViewModel itemTypeForIndexPath:indexPath]; +#pragma mark - UITableViewDelegate + +- (UIView*)tableView:(UITableView*)tableView + viewForFooterInSection:(NSInteger)section { + UIView* footerView = + [super tableView:tableView viewForFooterInSection:section]; + if (SectionIdentifierWebServices == + [self.tableViewModel sectionIdentifierForSection:section]) { + TableViewLinkHeaderFooterView* footer = + base::mac::ObjCCastStrict<TableViewLinkHeaderFooterView>(footerView); + footer.delegate = self; + } + return footerView; +} + +- (void)tableView:(UITableView*)tableView + didSelectRowAtIndexPath:(NSIndexPath*)indexPath { + [super tableView:tableView didSelectRowAtIndexPath:indexPath]; + NSInteger itemType = [self.tableViewModel itemTypeForIndexPath:indexPath]; // Items that push a new view controller. UIViewController<SettingsRootViewControlling>* controller; @@ -360,59 +360,8 @@ controller.dispatcher = self.dispatcher; [self.navigationController pushViewController:controller animated:YES]; } -} -#pragma mark MDCCollectionViewStylingDelegate - -- (BOOL)collectionView:(UICollectionView*)collectionView - shouldHideItemBackgroundAtIndexPath:(NSIndexPath*)indexPath { - NSInteger sectionIdentifier = - [self.collectionViewModel sectionIdentifierForSection:indexPath.section]; - - if (sectionIdentifier == SectionIdentifierWebServicesFooter) { - return YES; - } - return NO; -} - -- (BOOL)collectionView:(UICollectionView*)collectionView - hidesInkViewAtIndexPath:(NSIndexPath*)indexPath { - NSInteger type = [self.collectionViewModel itemTypeForIndexPath:indexPath]; - switch (type) { - case ItemTypeWebServicesFooter: - case ItemTypeWebServicesShowSuggestions: - case ItemTypeCanMakePaymentSwitch: - return YES; - default: - return NO; - } -} - -- (CGFloat)collectionView:(UICollectionView*)collectionView - cellHeightAtIndexPath:(NSIndexPath*)indexPath { - CollectionViewItem* item = - [self.collectionViewModel itemAtIndexPath:indexPath]; - - if (item.type == ItemTypeWebServicesFooter || - item.type == ItemTypeCanMakePaymentSwitch) { - return [MDCCollectionViewCell - cr_preferredHeightForWidth:CGRectGetWidth(collectionView.bounds) - forItem:item]; - } - - return MDCCellDefaultOneLineHeight; -} - -- (MDCCollectionViewCellStyle)collectionView:(UICollectionView*)collectionView - cellStyleForSection:(NSInteger)section { - NSInteger sectionIdentifier = - [self.collectionViewModel sectionIdentifierForSection:section]; - - if (sectionIdentifier == SectionIdentifierWebServicesFooter) { - return MDCCollectionViewCellStyleDefault; - } - - return self.styler.cellStyle; + [tableView deselectRowAtIndexPath:indexPath animated:YES]; } #pragma mark - BooleanObserver @@ -430,16 +379,16 @@ #pragma mark - Actions - (void)showSuggestionsToggled:(UISwitch*)sender { - NSIndexPath* switchPath = [self.collectionViewModel + NSIndexPath* switchPath = [self.tableViewModel indexPathForItemType:ItemTypeWebServicesShowSuggestions sectionIdentifier:SectionIdentifierWebServices]; - LegacySettingsSwitchItem* switchItem = - base::mac::ObjCCastStrict<LegacySettingsSwitchItem>( - [self.collectionViewModel itemAtIndexPath:switchPath]); - LegacySettingsSwitchCell* switchCell = - base::mac::ObjCCastStrict<LegacySettingsSwitchCell>( - [self.collectionView cellForItemAtIndexPath:switchPath]); + SettingsSwitchItem* switchItem = + base::mac::ObjCCastStrict<SettingsSwitchItem>( + [self.tableViewModel itemAtIndexPath:switchPath]); + SettingsSwitchCell* switchCell = + base::mac::ObjCCastStrict<SettingsSwitchCell>( + [self.tableView cellForRowAtIndexPath:switchPath]); if (switchCell.switchView.isOn) { base::RecordAction(base::UserMetricsAction( @@ -456,16 +405,16 @@ } - (void)canMakePaymentSwitchChanged:(UISwitch*)sender { - NSIndexPath* switchPath = [self.collectionViewModel + NSIndexPath* switchPath = [self.tableViewModel indexPathForItemType:ItemTypeCanMakePaymentSwitch sectionIdentifier:SectionIdentifierCanMakePayment]; - LegacySettingsSwitchItem* switchItem = - base::mac::ObjCCastStrict<LegacySettingsSwitchItem>( - [self.collectionViewModel itemAtIndexPath:switchPath]); - LegacySettingsSwitchCell* switchCell = - base::mac::ObjCCastStrict<LegacySettingsSwitchCell>( - [self.collectionView cellForItemAtIndexPath:switchPath]); + SettingsSwitchItem* switchItem = + base::mac::ObjCCastStrict<SettingsSwitchItem>( + [self.tableViewModel itemAtIndexPath:switchPath]); + SettingsSwitchCell* switchCell = + base::mac::ObjCCastStrict<SettingsSwitchCell>( + [self.tableView cellForRowAtIndexPath:switchPath]); DCHECK_EQ(switchCell.switchView, sender); switchItem.on = sender.isOn;
diff --git a/ios/chrome/browser/ui/settings/privacy_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/privacy_table_view_controller_unittest.mm similarity index 67% rename from ios/chrome/browser/ui/settings/privacy_collection_view_controller_unittest.mm rename to ios/chrome/browser/ui/settings/privacy_table_view_controller_unittest.mm index 71605a0..dd2fb3a4 100644 --- a/ios/chrome/browser/ui/settings/privacy_collection_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/privacy_table_view_controller_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/privacy_collection_view_controller.h" +#import "ios/chrome/browser/ui/settings/privacy_table_view_controller.h" #include <memory> @@ -20,7 +20,7 @@ #include "ios/chrome/browser/experimental_flags.h" #include "ios/chrome/browser/pref_names.h" #include "ios/chrome/browser/prefs/browser_prefs.h" -#import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h" +#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h" #include "ios/chrome/grit/ios_chromium_strings.h" #include "ios/chrome/grit/ios_strings.h" #include "ios/chrome/test/ios_chrome_scoped_testing_local_state.h" @@ -36,11 +36,10 @@ NSString* const kSpdyProxyEnabled = @"SpdyProxyEnabled"; -class PrivacyCollectionViewControllerTest - : public CollectionViewControllerTest { +class PrivacyTableViewControllerTest : public ChromeTableViewControllerTest { protected: void SetUp() override { - CollectionViewControllerTest::SetUp(); + ChromeTableViewControllerTest::SetUp(); TestChromeBrowserState::Builder test_cbs_builder; test_cbs_builder.SetPrefService(CreatePrefService()); chrome_browser_state_ = test_cbs_builder.Build(); @@ -65,7 +64,7 @@ [[NSUserDefaults standardUserDefaults] removeObjectForKey:kSpdyProxyEnabled]; } - CollectionViewControllerTest::TearDown(); + ChromeTableViewControllerTest::TearDown(); } // Makes a PrefService to be used by the test. @@ -77,8 +76,8 @@ return factory.CreateSyncable(registry.get()); } - CollectionViewController* InstantiateController() override { - return [[PrivacyCollectionViewController alloc] + ChromeTableViewController* InstantiateController() override { + return [[PrivacyTableViewController alloc] initWithBrowserState:chrome_browser_state_.get()]; } @@ -88,52 +87,42 @@ NSString* initialValueForSpdyProxyEnabled_; }; -// Tests PrivacyCollectionViewController is set up with all appropriate items +// Tests PrivacyTableViewController is set up with all appropriate items // and sections. -TEST_F(PrivacyCollectionViewControllerTest, TestModel) { +TEST_F(PrivacyTableViewControllerTest, TestModel) { CheckController(); - EXPECT_EQ(5, NumberOfSections()); + EXPECT_EQ(4, NumberOfSections()); - int sectionIndex = 0; - EXPECT_EQ(1, NumberOfItemsInSection(sectionIndex)); - CheckSectionHeaderWithId(IDS_IOS_OPTIONS_CONTINUITY_LABEL, sectionIndex); + // Sections[0]. + EXPECT_EQ(1, NumberOfItemsInSection(0)); + CheckSectionHeaderWithId(IDS_IOS_OPTIONS_CONTINUITY_LABEL, 0); NSString* handoffSubtitle = chrome_browser_state_->GetPrefs()->GetBoolean( prefs::kIosHandoffToOtherDevices) ? l10n_util::GetNSString(IDS_IOS_SETTING_ON) : l10n_util::GetNSString(IDS_IOS_SETTING_OFF); - CheckTextCellTitleAndSubtitle( + CheckTextCellTextAndDetailText( l10n_util::GetNSString(IDS_IOS_OPTIONS_ENABLE_HANDOFF_TO_OTHER_DEVICES), - handoffSubtitle, sectionIndex, 0); + handoffSubtitle, 0, 0); - ++sectionIndex; - NSInteger expectedRows = 2; - - EXPECT_EQ(expectedRows, NumberOfItemsInSection(sectionIndex)); - - CheckSectionHeaderWithId(IDS_IOS_OPTIONS_WEB_SERVICES_LABEL, sectionIndex); - int row = 0; - - CheckSwitchCellStateAndTitleWithId( - YES, IDS_IOS_OPTIONS_SEARCH_URL_SUGGESTIONS, sectionIndex, row++); - + // Sections[1]. + EXPECT_EQ(2, NumberOfItemsInSection(1)); + CheckSectionHeaderWithId(IDS_IOS_OPTIONS_WEB_SERVICES_LABEL, 1); + CheckSwitchCellStateAndTextWithId(YES, IDS_IOS_OPTIONS_SEARCH_URL_SUGGESTIONS, + 1, 0); CheckDetailItemTextWithIds(IDS_IOS_OPTIONS_SEND_USAGE_DATA, - IDS_IOS_OPTIONS_DATA_USAGE_NEVER, sectionIndex, - row++); + IDS_IOS_OPTIONS_DATA_USAGE_NEVER, 1, 1); + CheckSectionFooterWithId(IDS_IOS_OPTIONS_PRIVACY_FOOTER, 1); - sectionIndex++; - EXPECT_EQ(1, NumberOfItemsInSection(sectionIndex)); - CheckSectionFooterWithId(IDS_IOS_OPTIONS_PRIVACY_FOOTER, sectionIndex); + // Sections[2]. + EXPECT_EQ(1, NumberOfItemsInSection(2)); + CheckSwitchCellStateAndText( + NO, l10n_util::GetNSString(IDS_SETTINGS_CAN_MAKE_PAYMENT_TOGGLE_LABEL), 2, + 0); - sectionIndex++; - EXPECT_EQ(1, NumberOfItemsInSection(sectionIndex)); - CheckSwitchCellStateAndTitle( - NO, l10n_util::GetNSString(IDS_SETTINGS_CAN_MAKE_PAYMENT_TOGGLE_LABEL), - sectionIndex, 0); - - sectionIndex++; - EXPECT_EQ(1, NumberOfItemsInSection(sectionIndex)); - CheckTextCellTitle(l10n_util::GetNSString(IDS_IOS_CLEAR_BROWSING_DATA_TITLE), - sectionIndex, 0); + // Sections[3]. + EXPECT_EQ(1, NumberOfItemsInSection(3)); + CheckTextCellText(l10n_util::GetNSString(IDS_IOS_CLEAR_BROWSING_DATA_TITLE), + 3, 0); } } // namespace
diff --git a/ios/chrome/browser/ui/settings/search_engine_settings_collection_view_controller.h b/ios/chrome/browser/ui/settings/search_engine_settings_collection_view_controller.h deleted file mode 100644 index a1115ae1..0000000 --- a/ios/chrome/browser/ui/settings/search_engine_settings_collection_view_controller.h +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_SEARCH_ENGINE_SETTINGS_COLLECTION_VIEW_CONTROLLER_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_SEARCH_ENGINE_SETTINGS_COLLECTION_VIEW_CONTROLLER_H_ - -#import "ios/chrome/browser/ui/settings/settings_root_collection_view_controller.h" - -namespace ios { -class ChromeBrowserState; -} // namespace ios - -// This class is the table view for the Search Engine settings. -@interface SearchEngineSettingsCollectionViewController - : SettingsRootCollectionViewController - -// The designated initializer. |browserState| must not be nil. -- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState - NS_DESIGNATED_INITIALIZER; - -- (instancetype)initWithLayout:(UICollectionViewLayout*)layout - style:(CollectionViewControllerStyle)style - NS_UNAVAILABLE; - -@end - -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_SEARCH_ENGINE_SETTINGS_COLLECTION_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/search_engine_table_view_controller.h b/ios/chrome/browser/ui/settings/search_engine_table_view_controller.h new file mode 100644 index 0000000..f4a4484 --- /dev/null +++ b/ios/chrome/browser/ui/settings/search_engine_table_view_controller.h
@@ -0,0 +1,27 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_SEARCH_ENGINE_TABLE_VIEW_CONTROLLER_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_SEARCH_ENGINE_TABLE_VIEW_CONTROLLER_H_ + +#import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h" + +namespace ios { +class ChromeBrowserState; +} // namespace ios + +// This class is the table view for the Search Engine settings. +@interface SearchEngineTableViewController : SettingsRootTableViewController + +// The designated initializer. |browserState| must not be nil. +- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState + NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithTableViewStyle:(UITableViewStyle)style + appBarStyle: + (ChromeTableViewControllerStyle)appBarStyle + NS_UNAVAILABLE; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_SEARCH_ENGINE_TABLE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/search_engine_settings_collection_view_controller.mm b/ios/chrome/browser/ui/settings/search_engine_table_view_controller.mm similarity index 75% rename from ios/chrome/browser/ui/settings/search_engine_settings_collection_view_controller.mm rename to ios/chrome/browser/ui/settings/search_engine_table_view_controller.mm index c970d27a..afa731b 100644 --- a/ios/chrome/browser/ui/settings/search_engine_settings_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/search_engine_table_view_controller.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/search_engine_settings_collection_view_controller.h" +#import "ios/chrome/browser/ui/settings/search_engine_table_view_controller.h" #include <memory> @@ -14,11 +14,9 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/search_engines/search_engine_observer_bridge.h" #include "ios/chrome/browser/search_engines/template_url_service_factory.h" -#import "ios/chrome/browser/ui/collection_view/collection_view_model.h" -#import "ios/chrome/browser/ui/settings/cells/settings_text_item.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_text_header_footer_item.h" #include "ios/chrome/grit/ios_strings.h" -#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h" -#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h" #include "ui/base/l10n/l10n_util_mac.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -45,11 +43,10 @@ } // namespace -@interface SearchEngineSettingsCollectionViewController ()< - SearchEngineObserving> +@interface SearchEngineTableViewController ()<SearchEngineObserving> @end -@implementation SearchEngineSettingsCollectionViewController { +@implementation SearchEngineTableViewController { TemplateURLService* _templateURLService; // weak std::unique_ptr<SearchEngineObserverBridge> _observer; // Prevent unnecessary notifications when we write to the setting. @@ -67,9 +64,9 @@ - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState { DCHECK(browserState); - UICollectionViewLayout* layout = [[MDCCollectionViewFlowLayout alloc] init]; self = - [super initWithLayout:layout style:CollectionViewControllerStyleAppBar]; + [super initWithTableViewStyle:UITableViewStyleGrouped + appBarStyle:ChromeTableViewControllerStyleWithAppBar]; if (self) { _templateURLService = ios::TemplateURLServiceFactory::GetForBrowserState(browserState); @@ -77,17 +74,23 @@ std::make_unique<SearchEngineObserverBridge>(self, _templateURLService); _templateURLService->Load(); [self setTitle:l10n_util::GetNSString(IDS_IOS_SEARCH_ENGINE_SETTING_TITLE)]; - [self setCollectionViewAccessibilityIdentifier:@"Search Engine"]; - // TODO(crbug.com/764578): -loadModel should not be called from - // initializer. A possible fix is to move this call to -viewDidLoad. - [self loadModel]; } return self; } +#pragma mark - UIViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + [self loadModel]; +} + +#pragma mark - ChromeTableViewController + - (void)loadModel { [super loadModel]; - CollectionViewModel* model = self.collectionViewModel; + TableViewModel* model = self.tableViewModel; [self loadSearchEngines]; // Add prior search engines. @@ -95,11 +98,12 @@ [model addSectionWithIdentifier:SectionIdentifierPriorSearchEngines]; for (TemplateURL* url : _priorSearchEngines) { - SettingsTextItem* engine = [[SettingsTextItem alloc] + TableViewDetailTextItem* engine = [[TableViewDetailTextItem alloc] initWithType:ItemTypePriorSearchEnginesEngine]; - [engine setText:base::SysUTF16ToNSString(url->short_name())]; + engine.text = base::SysUTF16ToNSString(url->short_name()); + engine.detailText = base::SysUTF16ToNSString(url->keyword()); if (url == _templateURLService->GetDefaultSearchProvider()) { - [engine setAccessoryType:MDCCollectionViewCellAccessoryCheckmark]; + [engine setAccessoryType:UITableViewCellAccessoryCheckmark]; } [model addItem:engine toSectionWithIdentifier:SectionIdentifierPriorSearchEngines]; @@ -110,20 +114,21 @@ if (_customSearchEngines.size() > 0) { [model addSectionWithIdentifier:SectionIdentifierCustomSearchEngines]; - SettingsTextItem* header = [[SettingsTextItem alloc] - initWithType:ItemTypeCustomSearchEnginesEngineHeader]; + TableViewTextHeaderFooterItem* header = + [[TableViewTextHeaderFooterItem alloc] + initWithType:ItemTypeCustomSearchEnginesEngineHeader]; header.text = l10n_util::GetNSString( IDS_IOS_SEARCH_ENGINE_SETTING_CUSTOM_SECTION_HEADER); - header.textColor = [[MDCPalette greyPalette] tint500]; [model setHeader:header forSectionWithIdentifier:SectionIdentifierCustomSearchEngines]; for (TemplateURL* url : _customSearchEngines) { - SettingsTextItem* engine = [[SettingsTextItem alloc] + TableViewDetailTextItem* engine = [[TableViewDetailTextItem alloc] initWithType:ItemTypeCustomSearchEnginesEngine]; - [engine setText:base::SysUTF16ToNSString(url->short_name())]; + engine.text = base::SysUTF16ToNSString(url->short_name()); + engine.detailText = base::SysUTF16ToNSString(url->keyword()); if (url == _templateURLService->GetDefaultSearchProvider()) { - [engine setAccessoryType:MDCCollectionViewCellAccessoryCheckmark]; + [engine setAccessoryType:UITableViewCellAccessoryCheckmark]; } [model addItem:engine toSectionWithIdentifier:SectionIdentifierCustomSearchEngines]; @@ -131,25 +136,24 @@ } } -#pragma mark UICollectionViewDelegate +#pragma mark UITableViewDelegate -- (void)collectionView:(UICollectionView*)collectionView - didSelectItemAtIndexPath:(NSIndexPath*)indexPath { - [super collectionView:collectionView didSelectItemAtIndexPath:indexPath]; - CollectionViewModel* model = self.collectionViewModel; +- (void)tableView:(UITableView*)tableView + didSelectRowAtIndexPath:(NSIndexPath*)indexPath { + [super tableView:tableView didSelectRowAtIndexPath:indexPath]; + TableViewModel* model = self.tableViewModel; // Only handle taps on search engine items. - CollectionViewItem* selectedItem = [model itemAtIndexPath:indexPath]; + TableViewItem* selectedItem = [model itemAtIndexPath:indexPath]; if (selectedItem.type != ItemTypePriorSearchEnginesEngine && selectedItem.type != ItemTypeCustomSearchEnginesEngine) { return; } // Do nothing if the tapped engine was already the default. - SettingsTextItem* selectedTextItem = - base::mac::ObjCCastStrict<SettingsTextItem>(selectedItem); - if (selectedTextItem.accessoryType == - MDCCollectionViewCellAccessoryCheckmark) { + TableViewDetailTextItem* selectedTextItem = + base::mac::ObjCCastStrict<TableViewDetailTextItem>(selectedItem); + if (selectedTextItem.accessoryType == UITableViewCellAccessoryCheckmark) { return; } @@ -158,42 +162,42 @@ // Iterate through the engines and remove the checkmark from any that have it. if ([model hasSectionForSectionIdentifier:SectionIdentifierPriorSearchEngines]) { - for (CollectionViewItem* item in + for (TableViewItem* item in [model itemsInSectionWithIdentifier: SectionIdentifierPriorSearchEngines]) { if (item.type != ItemTypePriorSearchEnginesEngine) { continue; } - SettingsTextItem* textItem = - base::mac::ObjCCastStrict<SettingsTextItem>(item); - if (textItem.accessoryType == MDCCollectionViewCellAccessoryCheckmark) { - textItem.accessoryType = MDCCollectionViewCellAccessoryNone; + TableViewDetailTextItem* textItem = + base::mac::ObjCCastStrict<TableViewDetailTextItem>(item); + if (textItem.accessoryType == UITableViewCellAccessoryCheckmark) { + textItem.accessoryType = UITableViewCellAccessoryNone; [modifiedItems addObject:textItem]; } } } if ([model hasSectionForSectionIdentifier: SectionIdentifierCustomSearchEngines]) { - for (CollectionViewItem* item in + for (TableViewItem* item in [model itemsInSectionWithIdentifier: SectionIdentifierCustomSearchEngines]) { if (item.type != ItemTypeCustomSearchEnginesEngine) { continue; } - SettingsTextItem* textItem = - base::mac::ObjCCastStrict<SettingsTextItem>(item); - if (textItem.accessoryType == MDCCollectionViewCellAccessoryCheckmark) { - textItem.accessoryType = MDCCollectionViewCellAccessoryNone; + TableViewDetailTextItem* textItem = + base::mac::ObjCCastStrict<TableViewDetailTextItem>(item); + if (textItem.accessoryType == UITableViewCellAccessoryCheckmark) { + textItem.accessoryType = UITableViewCellAccessoryNone; [modifiedItems addObject:textItem]; } } } // Show the checkmark on the new default engine. - SettingsTextItem* newDefaultEngine = - base::mac::ObjCCastStrict<SettingsTextItem>( + TableViewDetailTextItem* newDefaultEngine = + base::mac::ObjCCastStrict<TableViewDetailTextItem>( [model itemAtIndexPath:indexPath]); - newDefaultEngine.accessoryType = MDCCollectionViewCellAccessoryCheckmark; + newDefaultEngine.accessoryType = UITableViewCellAccessoryCheckmark; [modifiedItems addObject:newDefaultEngine]; // Set the new engine as the default. @@ -205,6 +209,7 @@ [model indexInItemTypeForIndexPath:indexPath]]; [self reconfigureCellsForItems:modifiedItems]; + [tableView deselectRowAtIndexPath:indexPath animated:YES]; } #pragma mark Internal methods
diff --git a/ios/chrome/browser/ui/settings/search_engine_settings_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/search_engine_table_view_controller_unittest.mm similarity index 60% rename from ios/chrome/browser/ui/settings/search_engine_settings_collection_view_controller_unittest.mm rename to ios/chrome/browser/ui/settings/search_engine_table_view_controller_unittest.mm index 9400c2b..beefa3f 100644 --- a/ios/chrome/browser/ui/settings/search_engine_settings_collection_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/search_engine_table_view_controller_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/search_engine_settings_collection_view_controller.h" +#import "ios/chrome/browser/ui/settings/search_engine_table_view_controller.h" #include <memory> @@ -17,9 +17,8 @@ #include "components/sync_preferences/testing_pref_service_syncable.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #include "ios/chrome/browser/search_engines/template_url_service_factory.h" -#import "ios/chrome/browser/ui/collection_view/collection_view_controller_test.h" -#import "ios/chrome/browser/ui/settings/cells/settings_text_item.h" -#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.h" +#import "ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h" #include "ios/web/public/test/test_web_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" @@ -36,11 +35,11 @@ const char kUmaSelectDefaultSearchEngine[] = "Search.iOS.SelectDefaultSearchEngine"; -class SearchEngineSettingsCollectionViewControllerTest - : public CollectionViewControllerTest { +class SearchEngineTableViewControllerTest + : public ChromeTableViewControllerTest { protected: void SetUp() override { - CollectionViewControllerTest::SetUp(); + ChromeTableViewControllerTest::SetUp(); TestChromeBrowserState::Builder test_cbs_builder; test_cbs_builder.AddTestingFactory( ios::TemplateURLServiceFactory::GetInstance(), @@ -52,18 +51,20 @@ template_url_service_->Load(); } - CollectionViewController* InstantiateController() override { - return [[SearchEngineSettingsCollectionViewController alloc] + ChromeTableViewController* InstantiateController() override { + return [[SearchEngineTableViewController alloc] initWithBrowserState:chrome_browser_state_.get()]; } // Adds a prepopulated search engine to TemplateURLService. TemplateURL* AddPriorSearchEngine(const std::string& short_name, + const std::string& keyword, int prepopulate_id, bool set_default) { TemplateURLData data; data.SetShortName(base::ASCIIToUTF16(short_name)); data.SetURL("https://chromium.test/index.php?q={searchTerms}"); + data.SetKeyword(base::ASCIIToUTF16(keyword)); data.prepopulate_id = prepopulate_id; TemplateURL* url = template_url_service_->Add(std::make_unique<TemplateURL>(data)); @@ -74,11 +75,13 @@ // Adds a custom search engine to TemplateURLService. TemplateURL* AddCustomSearchEngine(const std::string& short_name, + const std::string& keyword, base::Time last_visited_time, bool set_default) { TemplateURLData data; data.SetShortName(base::ASCIIToUTF16(short_name)); data.SetURL("https://chromium.test/index.php?q={searchTerms}"); + data.SetKeyword(base::ASCIIToUTF16(keyword)); data.last_visited = last_visited_time; TemplateURL* url = template_url_service_->Add(std::make_unique<TemplateURL>(data)); @@ -87,13 +90,14 @@ return url; } - // Checks if a text cell in the CollectionView has a check mark. + // Checks if a text cell in the TableView has a check mark. void CheckTextCellChecked(bool expect_checked, int section, int item) { - SettingsTextItem* text_item = base::mac::ObjCCastStrict<SettingsTextItem>( - GetCollectionViewItem(section, item)); + TableViewDetailTextItem* text_item = + base::mac::ObjCCastStrict<TableViewDetailTextItem>( + GetTableViewItem(section, item)); ASSERT_TRUE(text_item); - EXPECT_EQ(expect_checked ? MDCCollectionViewCellAccessoryCheckmark - : MDCCollectionViewCellAccessoryNone, + EXPECT_EQ(expect_checked ? UITableViewCellAccessoryCheckmark + : UITableViewCellAccessoryNone, text_item.accessoryType); } @@ -104,7 +108,7 @@ }; // Tests that no items are shown if TemplateURLService is empty. -TEST_F(SearchEngineSettingsCollectionViewControllerTest, TestNoUrl) { +TEST_F(SearchEngineTableViewControllerTest, TestNoUrl) { CreateController(); CheckController(); EXPECT_EQ(0, NumberOfSections()); @@ -112,110 +116,119 @@ // Tests that items are displayed correctly when TemplateURLService is filled // and a prepopulated search engine is selected as default. -TEST_F(SearchEngineSettingsCollectionViewControllerTest, +TEST_F(SearchEngineTableViewControllerTest, TestUrlsLoadedWithPrepopulatedSearchEngineAsDefault) { - AddPriorSearchEngine("prepopulated-3", 3, false); - AddPriorSearchEngine("prepopulated-1", 1, false); - AddPriorSearchEngine("prepopulated-2", 2, true); + AddPriorSearchEngine("prepopulated-3", "p3.com", 3, false); + AddPriorSearchEngine("prepopulated-1", "p1.com", 1, false); + AddPriorSearchEngine("prepopulated-2", "p2.com", 2, true); - AddCustomSearchEngine( - "custom-4", base::Time::Now() - base::TimeDelta::FromDays(10), false); - AddCustomSearchEngine( - "custom-1", base::Time::Now() - base::TimeDelta::FromSeconds(10), false); - AddCustomSearchEngine( - "custom-3", base::Time::Now() - base::TimeDelta::FromHours(10), false); - AddCustomSearchEngine( - "custom-2", base::Time::Now() - base::TimeDelta::FromMinutes(10), false); + AddCustomSearchEngine("custom-4", "c4.com", + base::Time::Now() - base::TimeDelta::FromDays(10), + false); + AddCustomSearchEngine("custom-1", "c1.com", + base::Time::Now() - base::TimeDelta::FromSeconds(10), + false); + AddCustomSearchEngine("custom-3", "c3.com", + base::Time::Now() - base::TimeDelta::FromHours(10), + false); + AddCustomSearchEngine("custom-2", "c2.com", + base::Time::Now() - base::TimeDelta::FromMinutes(10), + false); CreateController(); CheckController(); ASSERT_EQ(2, NumberOfSections()); ASSERT_EQ(3, NumberOfItemsInSection(0)); - CheckTextCellTitle(@"prepopulated-1", 0, 0); + CheckTextCellTextAndDetailText(@"prepopulated-1", @"p1.com", 0, 0); CheckTextCellChecked(false, 0, 0); - CheckTextCellTitle(@"prepopulated-2", 0, 1); + CheckTextCellTextAndDetailText(@"prepopulated-2", @"p2.com", 0, 1); CheckTextCellChecked(true, 0, 1); - CheckTextCellTitle(@"prepopulated-3", 0, 2); + CheckTextCellTextAndDetailText(@"prepopulated-3", @"p3.com", 0, 2); CheckTextCellChecked(false, 0, 2); ASSERT_EQ(3, NumberOfItemsInSection(1)); - CheckTextCellTitle(@"custom-1", 1, 0); + CheckTextCellTextAndDetailText(@"custom-1", @"c1.com", 1, 0); CheckTextCellChecked(false, 1, 0); - CheckTextCellTitle(@"custom-2", 1, 1); + CheckTextCellTextAndDetailText(@"custom-2", @"c2.com", 1, 1); CheckTextCellChecked(false, 1, 1); - CheckTextCellTitle(@"custom-3", 1, 2); + CheckTextCellTextAndDetailText(@"custom-3", @"c3.com", 1, 2); CheckTextCellChecked(false, 1, 2); } // Tests that items are displayed correctly when TemplateURLService is filled // and a custom search engine is selected as default. -TEST_F(SearchEngineSettingsCollectionViewControllerTest, +TEST_F(SearchEngineTableViewControllerTest, TestUrlsLoadedWithCustomSearchEngineAsDefault) { - AddPriorSearchEngine("prepopulated-3", 3, false); - AddPriorSearchEngine("prepopulated-1", 1, false); - AddPriorSearchEngine("prepopulated-2", 2, false); + AddPriorSearchEngine("prepopulated-3", "p3.com", 3, false); + AddPriorSearchEngine("prepopulated-1", "p1.com", 1, false); + AddPriorSearchEngine("prepopulated-2", "p2.com", 2, false); - AddCustomSearchEngine( - "custom-4", base::Time::Now() - base::TimeDelta::FromDays(10), false); - AddCustomSearchEngine( - "custom-1", base::Time::Now() - base::TimeDelta::FromSeconds(10), false); - AddCustomSearchEngine( - "custom-3", base::Time::Now() - base::TimeDelta::FromHours(10), false); - AddCustomSearchEngine( - "custom-2", base::Time::Now() - base::TimeDelta::FromMinutes(10), true); + AddCustomSearchEngine("custom-4", "c4.com", + base::Time::Now() - base::TimeDelta::FromDays(10), + false); + AddCustomSearchEngine("custom-1", "c1.com", + base::Time::Now() - base::TimeDelta::FromSeconds(10), + false); + AddCustomSearchEngine("custom-3", "c3.com", + base::Time::Now() - base::TimeDelta::FromHours(10), + false); + AddCustomSearchEngine("custom-2", "c2.com", + base::Time::Now() - base::TimeDelta::FromMinutes(10), + true); CreateController(); CheckController(); ASSERT_EQ(2, NumberOfSections()); ASSERT_EQ(4, NumberOfItemsInSection(0)); - CheckTextCellTitle(@"prepopulated-1", 0, 0); + CheckTextCellTextAndDetailText(@"prepopulated-1", @"p1.com", 0, 0); CheckTextCellChecked(false, 0, 0); - CheckTextCellTitle(@"prepopulated-2", 0, 1); + CheckTextCellTextAndDetailText(@"prepopulated-2", @"p2.com", 0, 1); CheckTextCellChecked(false, 0, 1); - CheckTextCellTitle(@"prepopulated-3", 0, 2); + CheckTextCellTextAndDetailText(@"prepopulated-3", @"p3.com", 0, 2); CheckTextCellChecked(false, 0, 2); - CheckTextCellTitle(@"custom-2", 0, 3); + CheckTextCellTextAndDetailText(@"custom-2", @"c2.com", 0, 3); CheckTextCellChecked(true, 0, 3); ASSERT_EQ(2, NumberOfItemsInSection(1)); - CheckTextCellTitle(@"custom-1", 1, 0); + CheckTextCellTextAndDetailText(@"custom-1", @"c1.com", 1, 0); CheckTextCellChecked(false, 1, 0); - CheckTextCellTitle(@"custom-3", 1, 1); + CheckTextCellTextAndDetailText(@"custom-3", @"c3.com", 1, 1); CheckTextCellChecked(false, 1, 1); } // Tests that when TemplateURLService add or remove TemplateURLs, or update // default search engine, the controller will update the displayed items. -TEST_F(SearchEngineSettingsCollectionViewControllerTest, - TestUrlModifiedByService) { - TemplateURL* url_p1 = AddPriorSearchEngine("prepopulated-1", 1, true); +TEST_F(SearchEngineTableViewControllerTest, TestUrlModifiedByService) { + TemplateURL* url_p1 = + AddPriorSearchEngine("prepopulated-1", "p1.com", 1, true); CreateController(); CheckController(); ASSERT_EQ(1, NumberOfSections()); ASSERT_EQ(1, NumberOfItemsInSection(0)); - CheckTextCellTitle(@"prepopulated-1", 0, 0); + CheckTextCellTextAndDetailText(@"prepopulated-1", @"p1.com", 0, 0); CheckTextCellChecked(true, 0, 0); - TemplateURL* url_p2 = AddPriorSearchEngine("prepopulated-2", 2, false); + TemplateURL* url_p2 = + AddPriorSearchEngine("prepopulated-2", "p2.com", 2, false); ASSERT_EQ(1, NumberOfSections()); ASSERT_EQ(2, NumberOfItemsInSection(0)); - CheckTextCellTitle(@"prepopulated-1", 0, 0); + CheckTextCellTextAndDetailText(@"prepopulated-1", @"p1.com", 0, 0); CheckTextCellChecked(true, 0, 0); - CheckTextCellTitle(@"prepopulated-2", 0, 1); + CheckTextCellTextAndDetailText(@"prepopulated-2", @"p2.com", 0, 1); CheckTextCellChecked(false, 0, 1); template_url_service_->SetUserSelectedDefaultSearchProvider(url_p2); ASSERT_EQ(1, NumberOfSections()); ASSERT_EQ(2, NumberOfItemsInSection(0)); - CheckTextCellTitle(@"prepopulated-1", 0, 0); + CheckTextCellTextAndDetailText(@"prepopulated-1", @"p1.com", 0, 0); CheckTextCellChecked(false, 0, 0); - CheckTextCellTitle(@"prepopulated-2", 0, 1); + CheckTextCellTextAndDetailText(@"prepopulated-2", @"p2.com", 0, 1); CheckTextCellChecked(true, 0, 1); template_url_service_->SetUserSelectedDefaultSearchProvider(url_p1); @@ -223,13 +236,13 @@ ASSERT_EQ(1, NumberOfSections()); ASSERT_EQ(1, NumberOfItemsInSection(0)); - CheckTextCellTitle(@"prepopulated-1", 0, 0); + CheckTextCellTextAndDetailText(@"prepopulated-1", @"p1.com", 0, 0); CheckTextCellChecked(true, 0, 0); } // Tests that when user change default search engine, all items can be displayed // correctly and the change can be synced to the prefs. -TEST_F(SearchEngineSettingsCollectionViewControllerTest, TestChangeProvider) { +TEST_F(SearchEngineTableViewControllerTest, TestChangeProvider) { // This test also needs to test the UMA, so load some real prepopulated search // engines to ensure the SearchEngineType is logged correctly. Don't use any // literal symbol(e.g. "google" or "AOL") from @@ -256,32 +269,35 @@ // Also add some custom search engines. TemplateURL* url_c1 = - AddCustomSearchEngine("custom-1", base::Time::Now(), false); - AddCustomSearchEngine( - "custom-2", base::Time::Now() - base::TimeDelta::FromSeconds(10), false); + AddCustomSearchEngine("custom-1", "c1.com", base::Time::Now(), false); + AddCustomSearchEngine("custom-2", "c2.com", + base::Time::Now() - base::TimeDelta::FromSeconds(10), + false); CreateController(); CheckController(); // Choose url_p1 as default. - [controller() collectionView:[controller() collectionView] - didSelectItemAtIndexPath:[NSIndexPath indexPathForRow:url_p1_index - inSection:0]]; + [controller() tableView:[controller() tableView] + didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:url_p1_index + inSection:0]]; ASSERT_EQ(2, NumberOfSections()); // Check first list. ASSERT_EQ(2, NumberOfItemsInSection(0)); - CheckTextCellTitle(base::SysUTF16ToNSString(url_p1->short_name()), 0, - url_p1_index); + CheckTextCellTextAndDetailText(base::SysUTF16ToNSString(url_p1->short_name()), + base::SysUTF16ToNSString(url_p1->keyword()), 0, + url_p1_index); CheckTextCellChecked(true, 0, url_p1_index); - CheckTextCellTitle(base::SysUTF16ToNSString(url_p2->short_name()), 0, - url_p2_index); + CheckTextCellTextAndDetailText(base::SysUTF16ToNSString(url_p2->short_name()), + base::SysUTF16ToNSString(url_p2->keyword()), 0, + url_p2_index); CheckTextCellChecked(false, 0, url_p2_index); // Check second list. ASSERT_EQ(2, NumberOfItemsInSection(1)); - CheckTextCellTitle(@"custom-1", 1, 0); + CheckTextCellTextAndDetailText(@"custom-1", @"c1.com", 1, 0); CheckTextCellChecked(false, 1, 0); - CheckTextCellTitle(@"custom-2", 1, 1); + CheckTextCellTextAndDetailText(@"custom-2", @"c2.com", 1, 1); CheckTextCellChecked(false, 1, 1); // Check default search engine. EXPECT_EQ(url_p1, template_url_service_->GetDefaultSearchProvider()); @@ -291,24 +307,26 @@ url_p1->GetEngineType(template_url_service_->search_terms_data()), 1); // Choose url_p2 as default. - [controller() collectionView:[controller() collectionView] - didSelectItemAtIndexPath:[NSIndexPath indexPathForRow:url_p2_index - inSection:0]]; + [controller() tableView:[controller() tableView] + didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:url_p2_index + inSection:0]]; ASSERT_EQ(2, NumberOfSections()); // Check first list. ASSERT_EQ(2, NumberOfItemsInSection(0)); - CheckTextCellTitle(base::SysUTF16ToNSString(url_p1->short_name()), 0, - url_p1_index); + CheckTextCellTextAndDetailText(base::SysUTF16ToNSString(url_p1->short_name()), + base::SysUTF16ToNSString(url_p1->keyword()), 0, + url_p1_index); CheckTextCellChecked(false, 0, url_p1_index); - CheckTextCellTitle(base::SysUTF16ToNSString(url_p2->short_name()), 0, - url_p2_index); + CheckTextCellTextAndDetailText(base::SysUTF16ToNSString(url_p2->short_name()), + base::SysUTF16ToNSString(url_p2->keyword()), 0, + url_p2_index); CheckTextCellChecked(true, 0, url_p2_index); // Check second list. ASSERT_EQ(2, NumberOfItemsInSection(1)); - CheckTextCellTitle(@"custom-1", 1, 0); + CheckTextCellTextAndDetailText(@"custom-1", @"c1.com", 1, 0); CheckTextCellChecked(false, 1, 0); - CheckTextCellTitle(@"custom-2", 1, 1); + CheckTextCellTextAndDetailText(@"custom-2", @"c2.com", 1, 1); CheckTextCellChecked(false, 1, 1); // Check default search engine. EXPECT_EQ(url_p2, template_url_service_->GetDefaultSearchProvider()); @@ -322,23 +340,25 @@ histogram_tester_.ExpectTotalCount(kUmaSelectDefaultSearchEngine, 2); // Choose url_c1 as default. - [controller() collectionView:[controller() collectionView] - didSelectItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]]; + [controller() tableView:[controller() tableView] + didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]]; ASSERT_EQ(2, NumberOfSections()); // Check first list. ASSERT_EQ(2, NumberOfItemsInSection(0)); - CheckTextCellTitle(base::SysUTF16ToNSString(url_p1->short_name()), 0, - url_p1_index); + CheckTextCellTextAndDetailText(base::SysUTF16ToNSString(url_p1->short_name()), + base::SysUTF16ToNSString(url_p1->keyword()), 0, + url_p1_index); CheckTextCellChecked(false, 0, url_p1_index); - CheckTextCellTitle(base::SysUTF16ToNSString(url_p2->short_name()), 0, - url_p2_index); + CheckTextCellTextAndDetailText(base::SysUTF16ToNSString(url_p2->short_name()), + base::SysUTF16ToNSString(url_p2->keyword()), 0, + url_p2_index); CheckTextCellChecked(false, 0, url_p2_index); // Check second list. ASSERT_EQ(2, NumberOfItemsInSection(1)); - CheckTextCellTitle(@"custom-1", 1, 0); + CheckTextCellTextAndDetailText(@"custom-1", @"c1.com", 1, 0); CheckTextCellChecked(true, 1, 0); - CheckTextCellTitle(@"custom-2", 1, 1); + CheckTextCellTextAndDetailText(@"custom-2", @"c2.com", 1, 1); CheckTextCellChecked(false, 1, 1); // Check default search engine. EXPECT_EQ(url_c1, template_url_service_->GetDefaultSearchProvider());
diff --git a/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm b/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm index 08c457b..40e3c32 100644 --- a/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_collection_view_controller.mm
@@ -54,9 +54,9 @@ #import "ios/chrome/browser/ui/settings/content_settings_table_view_controller.h" #import "ios/chrome/browser/ui/settings/google_services_settings_coordinator.h" #import "ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.h" -#import "ios/chrome/browser/ui/settings/privacy_collection_view_controller.h" +#import "ios/chrome/browser/ui/settings/privacy_table_view_controller.h" #import "ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.h" -#import "ios/chrome/browser/ui/settings/search_engine_settings_collection_view_controller.h" +#import "ios/chrome/browser/ui/settings/search_engine_table_view_controller.h" #import "ios/chrome/browser/ui/settings/sync_utils/sync_util.h" #import "ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.h" #import "ios/chrome/browser/ui/settings/utils/pref_backed_boolean.h" @@ -855,7 +855,7 @@ [self showSyncGoogleService]; break; case ItemTypeSearchEngine: - controller = [[SearchEngineSettingsCollectionViewController alloc] + controller = [[SearchEngineTableViewController alloc] initWithBrowserState:_browserState]; break; case ItemTypeSavedPasswords: @@ -875,7 +875,7 @@ initWithPrefs:_browserState->GetPrefs()]; break; case ItemTypePrivacy: - controller = [[PrivacyCollectionViewController alloc] + controller = [[PrivacyTableViewController alloc] initWithBrowserState:_browserState]; break; case ItemTypeContentSettings:
diff --git a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h index 5fcbf66..796a4d6 100644 --- a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h +++ b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h
@@ -29,6 +29,10 @@ // using shouldHideDoneButton to know if it should display the edit button. - (void)updateEditButton; +// Reloads the table view model with |loadModel| and then reloads the +// table view data. +- (void)reloadData; + @end // Subclasses of SettingsRootTableViewController should implement the
diff --git a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm index 926a5a6..54d7047d 100644 --- a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm
@@ -47,6 +47,11 @@ } } +- (void)reloadData { + [self loadModel]; + [self.tableView reloadData]; +} + #pragma mark - Property - (UIBarButtonItem*)deleteButton {
diff --git a/ios/chrome/browser/ui/tab_grid/BUILD.gn b/ios/chrome/browser/ui/tab_grid/BUILD.gn index 6322727..120c145 100644 --- a/ios/chrome/browser/ui/tab_grid/BUILD.gn +++ b/ios/chrome/browser/ui/tab_grid/BUILD.gn
@@ -78,7 +78,6 @@ "resources:new_tab_toolbar_button_incognito", "resources:page_control_assets", "//base", - "//base:i18n", "//ios/chrome/app/strings", "//ios/chrome/browser", "//ios/chrome/browser/crash_report",
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_bottom_toolbar.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_bottom_toolbar.mm index 3bd0e3fd..ca77b26 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_bottom_toolbar.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_bottom_toolbar.mm
@@ -4,7 +4,6 @@ #import "ios/chrome/browser/ui/tab_grid/tab_grid_bottom_toolbar.h" -#include "base/i18n/rtl.h" #import "ios/chrome/browser/ui/tab_grid/tab_grid_constants.h" #import "ios/chrome/browser/ui/tab_grid/tab_grid_new_tab_button.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.mm index 7bdff40..c8cbcb3 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.mm
@@ -4,7 +4,6 @@ #import "ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.h" -#include "base/i18n/rtl.h" #import "ios/chrome/browser/ui/tab_grid/tab_grid_constants.h" #import "ios/chrome/browser/ui/tab_grid/tab_grid_page_control.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
diff --git a/ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h b/ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h index 6c6f398..c814b4d5 100644 --- a/ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h +++ b/ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h
@@ -52,12 +52,12 @@ // Verifies that the title matches the l10n string for |expected_title_id|. void CheckTitleWithId(int expected_title_id); - // Verifies that the section title at |section| matches the |expected_title|. - void CheckSectionHeader(NSString* expected_title, int section); + // Verifies that the section header at |section| matches the |expected_text|. + void CheckSectionHeader(NSString* expected_text, int section); - // Verifies that the section title at |section| matches the l10n string for - // |expected_title_id|. - void CheckSectionHeaderWithId(int expected_title_id, int section); + // Verifies that the section header at |section| matches the l10n string for + // |expected_text_id|. + void CheckSectionHeaderWithId(int expected_text_id, int section); // Verifies that the section footer at |section| matches the |expected_text|. void CheckSectionFooter(NSString* expected_text, int section);
diff --git a/ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.mm b/ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.mm index 6e2a7a6..3c88a96 100644 --- a/ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.mm +++ b/ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.mm
@@ -86,30 +86,32 @@ CheckTitle(l10n_util::GetNSString(expected_title_id)); } -void ChromeTableViewControllerTest::CheckSectionHeader(NSString* expected_title, +void ChromeTableViewControllerTest::CheckSectionHeader(NSString* expected_text, int section) { TableViewHeaderFooterItem* header = [[controller_ tableViewModel] headerForSection:section]; ASSERT_TRUE([header respondsToSelector:@selector(text)]); - EXPECT_NSEQ(expected_title, [(id)header text]); + EXPECT_NSEQ(expected_text, [(id)header text]); } void ChromeTableViewControllerTest::CheckSectionHeaderWithId( - int expected_title_id, + int expected_text_id, int section) { - CheckSectionHeader(l10n_util::GetNSString(expected_title_id), section); + CheckSectionHeader(l10n_util::GetNSString(expected_text_id), section); } void ChromeTableViewControllerTest::CheckSectionFooter(NSString* expected_text, int section) { - // TODO(crbug.com/894791): Implement this. - NOTREACHED(); + TableViewHeaderFooterItem* footer = + [[controller_ tableViewModel] footerForSection:section]; + ASSERT_TRUE([footer respondsToSelector:@selector(text)]); + EXPECT_NSEQ(expected_text, [(id)footer text]); } void ChromeTableViewControllerTest::CheckSectionFooterWithId( int expected_text_id, int section) { - return CheckSectionFooter(l10n_util::GetNSString(expected_text_id), section); + CheckSectionFooter(l10n_util::GetNSString(expected_text_id), section); } void ChromeTableViewControllerTest::CheckTextCellText(NSString* expected_text,
diff --git a/ios/chrome/browser/ui/util/ui_util.mm b/ios/chrome/browser/ui/util/ui_util.mm index d74a754d..5c59be8 100644 --- a/ios/chrome/browser/ui/util/ui_util.mm +++ b/ios/chrome/browser/ui/util/ui_util.mm
@@ -81,7 +81,8 @@ CGFloat StatusBarHeight() { if (base::FeatureList::IsEnabled( web::features::kBrowserContainerFullscreen) && - base::FeatureList::IsEnabled(web::features::kOutOfWebFullscreen)) { + base::FeatureList::IsEnabled(web::features::kOutOfWebFullscreen) && + base::FeatureList::IsEnabled(kBrowserContainerContainsNTP)) { DCHECK(!base::ios::IsRunningOnIOS11OrLater()); }
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm index e8a1359..2326a36 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
@@ -10,7 +10,7 @@ #import "ios/chrome/browser/ui/popup_menu/popup_menu_constants.h" #import "ios/chrome/browser/ui/settings/accounts_collection_view_controller.h" #import "ios/chrome/browser/ui/settings/clear_browsing_data_ui_constants.h" -#import "ios/chrome/browser/ui/settings/privacy_collection_view_controller.h" +#import "ios/chrome/browser/ui/settings/privacy_table_view_controller.h" #import "ios/chrome/browser/ui/settings/settings_collection_view_controller.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_url_item.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" @@ -143,7 +143,7 @@ grey_allOf(buttonMatcher, grey_interactable(), nil); [[[EarlGrey selectElementWithMatcher:interactableButtonMatcher] usingSearchAction:ScrollDown() - onElementWithMatcher:grey_accessibilityID(kPrivacyCollectionViewId)] + onElementWithMatcher:grey_accessibilityID(kPrivacyTableViewId)] performAction:grey_tap()]; }
diff --git a/ios/showcase/payments/sc_payments_editor_coordinator.mm b/ios/showcase/payments/sc_payments_editor_coordinator.mm index 50c5ff9..773b55c 100644 --- a/ios/showcase/payments/sc_payments_editor_coordinator.mm +++ b/ios/showcase/payments/sc_payments_editor_coordinator.mm
@@ -8,7 +8,7 @@ #include "base/strings/utf_string_conversions.h" #import "ios/chrome/browser/ui/autofill/autofill_ui_type.h" #import "ios/chrome/browser/ui/autofill/autofill_ui_type_util.h" -#import "ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h" +#import "ios/chrome/browser/ui/autofill/cells/legacy_autofill_edit_item.h" #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h" #import "ios/chrome/browser/ui/payments/cells/payments_text_item.h" #import "ios/chrome/browser/ui/payments/payment_request_edit_consumer.h"
diff --git a/ios/web_view/internal/autofill/cwv_autofill_controller.mm b/ios/web_view/internal/autofill/cwv_autofill_controller.mm index e5b2ddfc..8d146e4 100644 --- a/ios/web_view/internal/autofill/cwv_autofill_controller.mm +++ b/ios/web_view/internal/autofill/cwv_autofill_controller.mm
@@ -202,6 +202,7 @@ : nonPasswordSuggestions); } }; + // Fetch password suggestion first. [_passwordController fetchSuggestionsForFormWithName:formName @@ -213,6 +214,7 @@ passwordSuggestions = suggestions; resultHandler(); }]; + [self fetchNonPasswordSuggestionsForFormWithName:formName fieldIdentifier:fieldIdentifier fieldType:fieldType
diff --git a/ios/web_view/internal/autofill/cwv_autofill_suggestion_internal.h b/ios/web_view/internal/autofill/cwv_autofill_suggestion_internal.h index 0431423..0d79f638 100644 --- a/ios/web_view/internal/autofill/cwv_autofill_suggestion_internal.h +++ b/ios/web_view/internal/autofill/cwv_autofill_suggestion_internal.h
@@ -23,9 +23,6 @@ // The internal autofill form suggestion. @property(nonatomic, readonly) FormSuggestion* formSuggestion; -// YES if this is a password autofill suggestion. -@property(nonatomic, readonly) BOOL isPasswordSuggestion; - @end NS_ASSUME_NONNULL_END
diff --git a/ios/web_view/internal/autofill/cwv_autofill_suggestion_unittest.mm b/ios/web_view/internal/autofill/cwv_autofill_suggestion_unittest.mm index 1e00471..8944b27 100644 --- a/ios/web_view/internal/autofill/cwv_autofill_suggestion_unittest.mm +++ b/ios/web_view/internal/autofill/cwv_autofill_suggestion_unittest.mm
@@ -41,6 +41,7 @@ EXPECT_NSEQ(formSuggestion.displayDescription, suggestion.displayDescription); EXPECT_NSEQ(formSuggestion.value, suggestion.value); EXPECT_EQ(formSuggestion, suggestion.formSuggestion); + EXPECT_FALSE(suggestion.isPasswordSuggestion); } } // namespace ios_web_view
diff --git a/ios/web_view/internal/cwv_preferences.mm b/ios/web_view/internal/cwv_preferences.mm index 3458e52a..3c6f86b 100644 --- a/ios/web_view/internal/cwv_preferences.mm +++ b/ios/web_view/internal/cwv_preferences.mm
@@ -4,13 +4,17 @@ #import "ios/web_view/internal/cwv_preferences_internal.h" -#include "components/autofill/core/common/autofill_prefs.h" #include "components/prefs/pref_service.h" #include "components/translate/core/browser/translate_pref_names.h" #include "components/translate/core/browser/translate_prefs.h" #include "ios/web_view/cwv_web_view_features.h" #include "ios/web_view/internal/pref_names.h" +#if BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL) +#include "components/autofill/core/common/autofill_prefs.h" +#include "components/password_manager/core/common/password_manager_pref_names.h" +#endif // BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL) + #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif @@ -63,6 +67,16 @@ return autofill::prefs::IsCreditCardAutofillEnabled(_prefService); } +- (void)setPasswordAutofillEnabled:(BOOL)enabled { + _prefService->SetBoolean(password_manager::prefs::kCredentialsEnableService, + enabled); +} + +- (BOOL)isPasswordAutofillEnabled { + return _prefService->GetBoolean( + password_manager::prefs::kCredentialsEnableService); +} + #endif // BUILDFLAG(IOS_WEB_VIEW_ENABLE_AUTOFILL) @end
diff --git a/ios/web_view/internal/passwords/web_view_password_manager_client.h b/ios/web_view/internal/passwords/web_view_password_manager_client.h index 50a30d65..844338e 100644 --- a/ios/web_view/internal/passwords/web_view_password_manager_client.h +++ b/ios/web_view/internal/passwords/web_view_password_manager_client.h
@@ -97,7 +97,7 @@ void PromptUserToEnableAutosignin() override; password_manager::PasswordManager* GetPasswordManager() override; - id<CWVPasswordManagerClientDelegate> delegate_; // (weak) + __weak id<CWVPasswordManagerClientDelegate> delegate_; // The preference associated with // password_manager::prefs::kCredentialsEnableService.
diff --git a/ios/web_view/internal/passwords/web_view_password_manager_driver.h b/ios/web_view/internal/passwords/web_view_password_manager_driver.h index 91acd1f..e55060b 100644 --- a/ios/web_view/internal/passwords/web_view_password_manager_driver.h +++ b/ios/web_view/internal/passwords/web_view_password_manager_driver.h
@@ -67,7 +67,7 @@ bool IsMainFrame() const override; private: - id<CWVPasswordManagerDriverDelegate> delegate_; // (weak) + __weak id<CWVPasswordManagerDriverDelegate> delegate_; DISALLOW_COPY_AND_ASSIGN(WebViewPasswordManagerDriver); };
diff --git a/ios/web_view/internal/sync/web_view_sync_client.mm b/ios/web_view/internal/sync/web_view_sync_client.mm index 64979b3..45b9d05 100644 --- a/ios/web_view/internal/sync/web_view_sync_client.mm +++ b/ios/web_view/internal/sync/web_view_sync_client.mm
@@ -48,12 +48,12 @@ namespace { syncer::ModelTypeSet GetDisabledTypes() { - // Only want autofill and passwords. + // Only want credit card autofill for now. + // TODO(crbug.com/906910): Remove syncer::AUTOFILL_PROFILE and + // syncer::PASSWORDS as well once they are ready. syncer::ModelTypeSet disabled_types = syncer::UserTypes(); - disabled_types.Remove(syncer::AUTOFILL_PROFILE); disabled_types.Remove(syncer::AUTOFILL_WALLET_DATA); disabled_types.Remove(syncer::AUTOFILL_WALLET_METADATA); - disabled_types.Remove(syncer::PASSWORDS); return disabled_types; } } // namespace
diff --git a/ios/web_view/public/cwv_autofill_controller.h b/ios/web_view/public/cwv_autofill_controller.h index baaddc9..475c804b 100644 --- a/ios/web_view/public/cwv_autofill_controller.h +++ b/ios/web_view/public/cwv_autofill_controller.h
@@ -16,7 +16,7 @@ CWV_EXPORT // Exposes features that allow autofilling html forms. May include autofilling -// of single fields, address forms, or credit card forms. +// of single fields, address forms, credit card forms, or password forms. @interface CWVAutofillController : NSObject // Delegate to receive autofill callbacks.
diff --git a/ios/web_view/public/cwv_autofill_suggestion.h b/ios/web_view/public/cwv_autofill_suggestion.h index 52911ab9..2ddb089 100644 --- a/ios/web_view/public/cwv_autofill_suggestion.h +++ b/ios/web_view/public/cwv_autofill_suggestion.h
@@ -13,9 +13,9 @@ NS_ASSUME_NONNULL_BEGIN CWV_EXPORT -// Represents a suggestion for a form based off of a single field. -// In the case that this suggestion is created from a credit card or address -// profile, filling using a suggestion may fill more than one field at once. +// Represents a suggestion for an address, creditcard, or password form based +// off of a single field. Filling using a suggestion may fill more than one +// field at once. // Example: // If an address profile is: // John Doe @@ -60,6 +60,9 @@ // credit card network icon. @property(nonatomic, readonly, nullable) UIImage* icon; +// YES if this is a password autofill suggestion. +@property(nonatomic, readonly) BOOL isPasswordSuggestion; + - (instancetype)init NS_UNAVAILABLE; @end
diff --git a/ios/web_view/public/cwv_preferences.h b/ios/web_view/public/cwv_preferences.h index c944d4a..9eb9eea 100644 --- a/ios/web_view/public/cwv_preferences.h +++ b/ios/web_view/public/cwv_preferences.h
@@ -9,7 +9,8 @@ #import "cwv_export.h" -// Preferences for user settings. +// Preferences for user settings. The preferences are stored on the local +// storage. CWV_EXPORT @interface CWVPreferences : NSObject
diff --git a/ios/web_view/public/cwv_preferences_autofill.h b/ios/web_view/public/cwv_preferences_autofill.h index 28dc3fc..016e4ec 100644 --- a/ios/web_view/public/cwv_preferences_autofill.h +++ b/ios/web_view/public/cwv_preferences_autofill.h
@@ -23,6 +23,15 @@ @property(nonatomic, assign, getter=isCreditCardAutofillEnabled) BOOL creditCardAutofillEnabled; +// Whether or not CWVWebView allows saving passwords for autofill. Defaults to +// |YES|. When it is NO, it doesn't ask if you want to save passwords but will +// continue to fill passwords. +// +// TODO(crbug.com/905221): Preference should also control autofill behavior for +// the passwords. +@property(nonatomic, assign, getter=isPasswordAutofillEnabled) + BOOL passwordAutofillEnabled; + @end #endif // IOS_WEB_VIEW_PUBLIC_CWV_PREFERENCES_AUTOFILL_H_
diff --git a/media/base/video_frame_metadata.h b/media/base/video_frame_metadata.h index 7eb07376..45ae0eb 100644 --- a/media/base/video_frame_metadata.h +++ b/media/base/video_frame_metadata.h
@@ -111,9 +111,13 @@ // notified about its promotability to an overlay. WANTS_PROMOTION_HINT, - // Windows only: this video has protected content. + // This video frame comes from protected content. PROTECTED_VIDEO, + // Windows only: this video frame is protected by hardware. This option is + // valid if PROTECTED_VIDEO is also set to true. + HW_PROTECTED, + // Whether this frame was decoded in a power efficient way. POWER_EFFICIENT,
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index c4c3075..fc7eef4 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -459,7 +459,7 @@ if (client_ && IsInPictureInPicture() && !client_->IsInAutoPIP()) { delegate_->DidPictureInPictureSurfaceChange( delegate_id_, surface_id, pipeline_metadata_.natural_size, - true /* show_play_pause_button */); + ShouldShowPlayPauseButtonInPictureInPictureWindow()); } } @@ -852,7 +852,7 @@ // Picture-in-Picture mode. delegate_->DidPictureInPictureModeStart( delegate_id_, surface_id, pipeline_metadata_.natural_size, - std::move(callback), true /* show_play_pause_button */); + std::move(callback), ShouldShowPlayPauseButtonInPictureInPictureWindow()); } void WebMediaPlayerImpl::ExitPictureInPicture( @@ -3408,6 +3408,11 @@ WebMediaPlayer::DisplayType::kPictureInPicture; } +bool WebMediaPlayerImpl::ShouldShowPlayPauseButtonInPictureInPictureWindow() + const { + return Duration() != std::numeric_limits<double>::infinity(); +} + void WebMediaPlayerImpl::MaybeSetContainerName() { // MSE nor MediaPlayerRenderer provide container information. if (chunk_demuxer_ || using_media_player_renderer_)
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h index 2eca96f..1d67327a 100644 --- a/media/blink/webmediaplayer_impl.h +++ b/media/blink/webmediaplayer_impl.h
@@ -607,6 +607,11 @@ void SendBytesReceivedUpdate(); + // Returns whether the Picture-in-Picture window should contain a play/pause + // button. It will return false if video is "live", in other words if duration + // is equals to Infinity. + bool ShouldShowPlayPauseButtonInPictureInPictureWindow() const; + blink::WebLocalFrame* const frame_; // The playback state last reported to |delegate_|, to avoid setting duplicate
diff --git a/media/blink/webmediaplayer_impl_unittest.cc b/media/blink/webmediaplayer_impl_unittest.cc index 63a42d67..8c5eb9b 100644 --- a/media/blink/webmediaplayer_impl_unittest.cc +++ b/media/blink/webmediaplayer_impl_unittest.cc
@@ -1524,6 +1524,50 @@ .Times(0); } +// Tests delegate methods are called with the appropriate play/pause button +// state when Picture-in-Picture is triggered and video duration is infinity. +TEST_F(WebMediaPlayerImplTest, + PictureInPictureTriggerWithInfiniteDurationCallback) { + base::test::ScopedFeatureList feature_list; + feature_list.InitFromCommandLine(kUseSurfaceLayerForVideo.name, ""); + + InitializeWebMediaPlayerImpl(); + SetDuration(kInfiniteDuration); + + EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer()); + EXPECT_CALL(*surface_layer_bridge_ptr_, GetSurfaceId()) + .WillRepeatedly(ReturnRef(surface_id_)); + EXPECT_CALL(*surface_layer_bridge_ptr_, GetLocalSurfaceIdAllocationTime()) + .WillRepeatedly(Return(base::TimeTicks())); + EXPECT_CALL(*compositor_, EnableSubmission(_, _, _, _, false, _)); + EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false)); + + PipelineMetadata metadata; + metadata.has_video = true; + OnMetadata(metadata); + + EXPECT_CALL(client_, DisplayType()) + .WillRepeatedly( + Return(blink::WebMediaPlayer::DisplayType::kPictureInPicture)); + EXPECT_CALL(delegate_, + DidPictureInPictureSurfaceChange( + delegate_.player_id(), surface_id_, GetNaturalSize(), false)) + .Times(2); + + wmpi_->OnSurfaceIdUpdated(surface_id_); + + EXPECT_CALL(delegate_, + DidPictureInPictureModeStart(delegate_.player_id(), surface_id_, + GetNaturalSize(), _, false)); + + wmpi_->EnterPictureInPicture(base::DoNothing()); + wmpi_->OnSurfaceIdUpdated(surface_id_); + + // Updating SurfaceId should NOT exit Picture-in-Picture. + EXPECT_CALL(delegate_, DidPictureInPictureModeEnd(delegate_.player_id(), _)) + .Times(0); +} + class WebMediaPlayerImplBackgroundBehaviorTest : public WebMediaPlayerImplTest, public ::testing::WithParamInterface<
diff --git a/media/cdm/cdm_adapter.cc b/media/cdm/cdm_adapter.cc index 2547eaa4..6e5469ca 100644 --- a/media/cdm/cdm_adapter.cc +++ b/media/cdm/cdm_adapter.cc
@@ -528,6 +528,7 @@ } pixel_aspect_ratio_ = config.GetPixelAspectRatio(); + is_video_encrypted_ = config.is_encrypted(); if (status == cdm::kDeferredInitialization) { DVLOG(1) << "Deferred initialization in " << __func__; @@ -608,6 +609,11 @@ return; } + if (is_video_encrypted_) { + decoded_frame->metadata()->SetBoolean(VideoFrameMetadata::PROTECTED_VIDEO, + true); + } + video_decode_cb.Run(Decryptor::kSuccess, decoded_frame); }
diff --git a/media/cdm/cdm_adapter.h b/media/cdm/cdm_adapter.h index eb26e03..d77296d3 100644 --- a/media/cdm/cdm_adapter.h +++ b/media/cdm/cdm_adapter.h
@@ -252,6 +252,9 @@ // Keep track of aspect ratio from the latest configuration. double pixel_aspect_ratio_ = 0.0; + // Whether the current video config is encrypted. + bool is_video_encrypted_ = false; + // Tracks whether an output protection query and a positive query result (no // unprotected external link) have been reported to UMA. bool uma_for_output_protection_query_reported_ = false;
diff --git a/media/gpu/video_decode_accelerator_unittest.cc b/media/gpu/video_decode_accelerator_unittest.cc index 2141c4f5..bc624e4 100644 --- a/media/gpu/video_decode_accelerator_unittest.cc +++ b/media/gpu/video_decode_accelerator_unittest.cc
@@ -1160,7 +1160,7 @@ prefix_output_yuv = GetTestDataFile(filepath); } } -#if defined(USE_VAAPI) +#if BUILDFLAG(USE_VAAPI) bool linear = false; #else bool linear = true;
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc index 481bec2..59b7019 100644 --- a/media/gpu/windows/d3d11_video_decoder.cc +++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -575,8 +575,10 @@ // that ALLOW_OVERLAY is required for encrypted video path. frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY, true); - if (is_encrypted_) + if (is_encrypted_) { frame->metadata()->SetBoolean(VideoFrameMetadata::PROTECTED_VIDEO, true); + frame->metadata()->SetBoolean(VideoFrameMetadata::HW_PROTECTED, true); + } frame->set_color_space(picture->get_colorspace().ToGfxColorSpace()); output_cb_.Run(frame);
diff --git a/media/learning/impl/BUILD.gn b/media/learning/impl/BUILD.gn index 62b8c2d..dca4a51 100644 --- a/media/learning/impl/BUILD.gn +++ b/media/learning/impl/BUILD.gn
@@ -7,14 +7,15 @@ visibility = [ "//media/learning/impl:unit_tests" ] sources = [ - "learner.h", "learning_session_impl.cc", "learning_session_impl.h", "learning_task_controller.h", "learning_task_controller_impl.cc", "learning_task_controller_impl.h", - "random_tree.cc", - "random_tree.h", + "model.h", + "random_tree_trainer.cc", + "random_tree_trainer.h", + "training_algorithm.h", ] defines = [ "IS_LEARNING_IMPL_IMPL" ] @@ -33,7 +34,7 @@ sources = [ "learning_session_impl_unittest.cc", - "random_tree_unittest.cc", + "random_tree_trainer_unittest.cc", ] deps = [
diff --git a/media/learning/impl/learner.h b/media/learning/impl/learner.h deleted file mode 100644 index dd4fcd83..0000000 --- a/media/learning/impl/learner.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MEDIA_LEARNING_IMPL_LEARNER_H_ -#define MEDIA_LEARNING_IMPL_LEARNER_H_ - -#include "base/component_export.h" -#include "base/values.h" -#include "media/learning/common/training_example.h" - -namespace media { -namespace learning { - -// Base class for a thing that takes examples of the form {features, target}, -// and trains a model to predict the target given the features. The target may -// be either nominal (classification) or numeric (regression), though this must -// be chosen in advance when creating the learner via LearnerFactory. -class COMPONENT_EXPORT(LEARNING_IMPL) Learner { - public: - virtual ~Learner() = default; - - // Tell the learner that |example| has been observed during training. - virtual void AddExample(const TrainingExample& example) = 0; -}; - -} // namespace learning -} // namespace media - -#endif // MEDIA_LEARNING_IMPL_LEARNER_H_
diff --git a/media/learning/impl/model.h b/media/learning/impl/model.h new file mode 100644 index 0000000..c8da352 --- /dev/null +++ b/media/learning/impl/model.h
@@ -0,0 +1,36 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_LEARNING_IMPL_MODEL_H_ +#define MEDIA_LEARNING_IMPL_MODEL_H_ + +#include <map> + +#include "base/component_export.h" +#include "media/learning/common/training_example.h" +#include "media/learning/impl/model.h" + +namespace media { +namespace learning { + +// One trained model, useful for making predictions. +// TODO(liberato): Provide an API for incremental update, for those models that +// can support it. +class COMPONENT_EXPORT(LEARNING_IMPL) Model { + public: + // [target value] == counts + // This is classification-centric. Not sure about the right interface for + // regressors. Mostly for testing. + using TargetDistribution = std::map<TargetValue, int>; + + virtual ~Model() = default; + + virtual TargetDistribution PredictDistribution( + const FeatureVector& instance) = 0; +}; + +} // namespace learning +} // namespace media + +#endif // MEDIA_LEARNING_IMPL_MODEL_H_
diff --git a/media/learning/impl/random_tree.cc b/media/learning/impl/random_tree_trainer.cc similarity index 67% rename from media/learning/impl/random_tree.cc rename to media/learning/impl/random_tree_trainer.cc index 2929a61..ffc1cb6 100644 --- a/media/learning/impl/random_tree.cc +++ b/media/learning/impl/random_tree_trainer.cc
@@ -2,37 +2,51 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "media/learning/impl/random_tree.h" +#include "media/learning/impl/random_tree_trainer.h" + +#include <math.h> + +#include "base/bind.h" +#include "base/logging.h" namespace media { namespace learning { -RandomTree::TreeNode::~TreeNode() = default; -RandomTree::Split::Split() = default; -RandomTree::Split::Split(int index) : split_index(index) {} -RandomTree::Split::Split(Split&& rhs) = default; -RandomTree::Split::~Split() = default; -RandomTree::Split& RandomTree::Split::operator=(Split&& rhs) = default; -RandomTree::Split::BranchInfo::BranchInfo() = default; -RandomTree::Split::BranchInfo::BranchInfo(const BranchInfo& rhs) = default; -RandomTree::Split::BranchInfo::~BranchInfo() = default; +// static +TrainingAlgorithmCB RandomTreeTrainer::GetTrainingAlgorithmCB() { + return base::BindRepeating( + [](const TrainingData& training_data) -> std::unique_ptr<Model> { + return RandomTreeTrainer().Train(training_data); + }); +} -struct InteriorNode : public RandomTree::TreeNode { +RandomTreeTrainer::Split::Split() = default; +RandomTreeTrainer::Split::Split(int index) : split_index(index) {} +RandomTreeTrainer::Split::Split(Split&& rhs) = default; +RandomTreeTrainer::Split::~Split() = default; +RandomTreeTrainer::Split& RandomTreeTrainer::Split::operator=(Split&& rhs) = + default; +RandomTreeTrainer::Split::BranchInfo::BranchInfo() = default; +RandomTreeTrainer::Split::BranchInfo::BranchInfo(const BranchInfo& rhs) = + default; +RandomTreeTrainer::Split::BranchInfo::~BranchInfo() = default; + +struct InteriorNode : public Model { InteriorNode(int split_index) : split_index_(split_index) {} - // TreeNode - TargetDistribution* ComputeDistribution( + // Model + Model::TargetDistribution PredictDistribution( const FeatureVector& features) override { auto iter = children_.find(features[split_index_]); // If we've never seen this feature value, then make no prediction. if (iter == children_.end()) - return nullptr; + return TargetDistribution(); - return iter->second->ComputeDistribution(features); + return iter->second->PredictDistribution(features); } // Add |child| has the node for feature value |v|. - void AddChild(FeatureValue v, std::unique_ptr<TreeNode> child) { + void AddChild(FeatureValue v, std::unique_ptr<Model> child) { DCHECK_EQ(children_.count(v), 0u); children_.emplace(v, std::move(child)); } @@ -40,44 +54,37 @@ private: // Feature value that we split on. int split_index_ = -1; - std::map<FeatureValue, std::unique_ptr<TreeNode>> children_; + std::map<FeatureValue, std::unique_ptr<Model>> children_; }; -struct LeafNode : public RandomTree::TreeNode { +struct LeafNode : public Model { LeafNode(const TrainingData& training_data) { for (const TrainingExample* example : training_data) distribution_[example->target_value]++; } // TreeNode - TargetDistribution* ComputeDistribution(const FeatureVector&) override { - return &distribution_; + Model::TargetDistribution PredictDistribution(const FeatureVector&) override { + return distribution_; } private: - TargetDistribution distribution_; + Model::TargetDistribution distribution_; }; -RandomTree::RandomTree() = default; +RandomTreeTrainer::RandomTreeTrainer() = default; -RandomTree::~RandomTree() = default; +RandomTreeTrainer::~RandomTreeTrainer() = default; -void RandomTree::Train(const TrainingData& training_data) { - root_ = nullptr; +std::unique_ptr<Model> RandomTreeTrainer::Train( + const TrainingData& training_data) { if (training_data.empty()) - return; + return std::make_unique<InteriorNode>(-1); - root_ = Build(training_data, FeatureSet()); + return Build(training_data, FeatureSet()); } -const RandomTree::TreeNode::TargetDistribution* -RandomTree::ComputeDistributionForTesting(const FeatureVector& instance) { - if (!root_) - return nullptr; - return root_->ComputeDistribution(instance); -} - -std::unique_ptr<RandomTree::TreeNode> RandomTree::Build( +std::unique_ptr<Model> RandomTreeTrainer::Build( const TrainingData& training_data, const FeatureSet& used_set) { DCHECK(training_data.size()); @@ -86,8 +93,7 @@ Split best_potential_split; // Select the feature subset to consider at this leaf. - // TODO(liberato): This should select a subset, which is why it's not merged - // with the loop below. + // TODO(liberato): subset. FeatureSet feature_candidates; for (size_t i = 0; i < training_data[0]->features.size(); i++) { if (used_set.find(i) != used_set.end()) @@ -127,8 +133,9 @@ return node; } -RandomTree::Split RandomTree::ConstructSplit(const TrainingData& training_data, - int index) { +RandomTreeTrainer::Split RandomTreeTrainer::ConstructSplit( + const TrainingData& training_data, + int index) { // We should not be given a training set of size 0, since there's no need to // check an empty split. DCHECK_GT(training_data.size(), 0u);
diff --git a/media/learning/impl/random_tree.h b/media/learning/impl/random_tree_trainer.h similarity index 80% rename from media/learning/impl/random_tree.h rename to media/learning/impl/random_tree_trainer.h index c83c2f8a..461947fc 100644 --- a/media/learning/impl/random_tree.h +++ b/media/learning/impl/random_tree_trainer.h
@@ -2,23 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MEDIA_LEARNING_IMPL_RANDOM_TREE_H_ -#define MEDIA_LEARNING_IMPL_RANDOM_TREE_H_ +#ifndef MEDIA_LEARNING_IMPL_RANDOM_TREE_TRAINER_H_ +#define MEDIA_LEARNING_IMPL_RANDOM_TREE_TRAINER_H_ #include <limits> #include <memory> #include <set> -#include <vector> -#include "base/callback.h" #include "base/component_export.h" #include "base/macros.h" -#include "media/learning/impl/learner.h" +#include "media/learning/impl/training_algorithm.h" namespace media { namespace learning { -// RandomTree decision tree classifier (doesn't handle regression currently). +// Trains RandomTree decision tree classifier (doesn't handle regression). // // Decision trees, including RandomTree, classify instances as follows. Each // non-leaf node is marked with a feature number |i|. The value of the |i|-th @@ -56,24 +54,15 @@ // TODO(liberato): Right now, it not-so-randomly selects from the entire set. // TODO(liberato): consider PRF or other simplified approximations. // TODO(liberato): separate Model and TrainingAlgorithm. This is the latter. -class COMPONENT_EXPORT(LEARNING_IMPL) RandomTree { +class COMPONENT_EXPORT(LEARNING_IMPL) RandomTreeTrainer { public: - struct TreeNode { - // [target value] == counts - using TargetDistribution = std::map<TargetValue, int>; - virtual ~TreeNode(); - virtual TargetDistribution* ComputeDistribution( - const FeatureVector& features) = 0; - }; + RandomTreeTrainer(); + ~RandomTreeTrainer(); - RandomTree(); - virtual ~RandomTree(); + // Return a callback that can be used to train a random tree. + static TrainingAlgorithmCB GetTrainingAlgorithmCB(); - // Train the tree. - void Train(const TrainingData& examples); - - const TreeNode::TargetDistribution* ComputeDistributionForTesting( - const FeatureVector& instance); + std::unique_ptr<Model> Train(const TrainingData& examples); private: // Set of feature indices. @@ -124,19 +113,16 @@ // Build this node from |training_data|. |used_set| is the set of features // that we already used higher in the tree. - std::unique_ptr<TreeNode> Build(const TrainingData& training_data, - const FeatureSet& used_set); + std::unique_ptr<Model> Build(const TrainingData& training_data, + const FeatureSet& used_set); // Compute and return a split of |training_data| on the |index|-th feature. Split ConstructSplit(const TrainingData& training_data, int index); - // Root of the random tree, or null. - std::unique_ptr<TreeNode> root_; - - DISALLOW_COPY_AND_ASSIGN(RandomTree); + DISALLOW_COPY_AND_ASSIGN(RandomTreeTrainer); }; } // namespace learning } // namespace media -#endif // MEDIA_LEARNING_IMPL_RANDOM_TREE_H_ +#endif // MEDIA_LEARNING_IMPL_RANDOM_TREE_TRAINER_H_
diff --git a/media/learning/impl/random_tree_trainer_unittest.cc b/media/learning/impl/random_tree_trainer_unittest.cc new file mode 100644 index 0000000..afaf4b0 --- /dev/null +++ b/media/learning/impl/random_tree_trainer_unittest.cc
@@ -0,0 +1,135 @@ +// 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/learning/impl/random_tree_trainer.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace media { +namespace learning { + +class RandomTreeTest : public testing::Test { + public: + RandomTreeTrainer trainer_; +}; + +TEST_F(RandomTreeTest, EmptyTrainingDataWorks) { + TrainingData empty; + std::unique_ptr<Model> model = trainer_.Train(empty); + EXPECT_NE(model.get(), nullptr); + EXPECT_EQ(model->PredictDistribution(FeatureVector()), + Model::TargetDistribution()); +} + +TEST_F(RandomTreeTest, UniformTrainingDataWorks) { + TrainingExample example({FeatureValue(123), FeatureValue(456)}, + TargetValue(789)); + TrainingData training_data; + const int n_examples = 10; + for (int i = 0; i < n_examples; i++) + training_data.push_back(&example); + std::unique_ptr<Model> model = trainer_.Train(training_data); + + // The tree should produce a distribution for one value (our target), which + // has |n_examples| counts. + Model::TargetDistribution distribution = + model->PredictDistribution(example.features); + EXPECT_EQ(distribution.size(), 1u); + EXPECT_EQ(distribution.find(example.target_value)->second, n_examples); +} + +TEST_F(RandomTreeTest, UniformTrainingDataWorksWithCallback) { + TrainingExample example({FeatureValue(123), FeatureValue(456)}, + TargetValue(789)); + TrainingData training_data; + const int n_examples = 10; + for (int i = 0; i < n_examples; i++) + training_data.push_back(&example); + + std::unique_ptr<Model> model = + RandomTreeTrainer::GetTrainingAlgorithmCB().Run(training_data); + + Model::TargetDistribution distribution = + model->PredictDistribution(example.features); + EXPECT_EQ(distribution.size(), 1u); + EXPECT_EQ(distribution.find(example.target_value)->second, n_examples); +} + +TEST_F(RandomTreeTest, SimpleSeparableTrainingData) { + TrainingExample example_1({FeatureValue(123)}, TargetValue(1)); + TrainingExample example_2({FeatureValue(456)}, TargetValue(2)); + TrainingData training_data({&example_1, &example_2}); + std::unique_ptr<Model> model = trainer_.Train(training_data); + + // Each value should have a distribution with one target value with one count. + Model::TargetDistribution distribution = + model->PredictDistribution(example_1.features); + EXPECT_NE(model.get(), nullptr); + EXPECT_EQ(distribution.size(), 1u); + EXPECT_EQ(distribution.find(example_1.target_value)->second, 1); + + distribution = model->PredictDistribution(example_2.features); + EXPECT_EQ(distribution.size(), 1u); + EXPECT_EQ(distribution.find(example_2.target_value)->second, 1); +} + +TEST_F(RandomTreeTest, ComplexSeparableTrainingData) { + // Build a four-feature training set that's completely separable, but one + // needs all four features to do it. + TrainingDataStorage training_data_storage; + for (int f1 = 0; f1 < 2; f1++) { + for (int f2 = 0; f2 < 2; f2++) { + for (int f3 = 0; f3 < 2; f3++) { + for (int f4 = 0; f4 < 2; f4++) { + training_data_storage.push_back( + TrainingExample({FeatureValue(f1), FeatureValue(f2), + FeatureValue(f3), FeatureValue(f4)}, + TargetValue(f1 * 1 + f2 * 2 + f3 * 4 + f4 * 8))); + } + } + } + } + + // Add two copies of each example. Note that we do this after fully + // constructing |training_data_storage|, since it may realloc. + TrainingData training_data; + for (auto& example : training_data_storage) { + training_data.push_back(&example); + training_data.push_back(&example); + } + + std::unique_ptr<Model> model = trainer_.Train(training_data); + EXPECT_NE(model.get(), nullptr); + + // Each example should have a distribution by itself, with two counts. + for (const TrainingExample* example : training_data) { + Model::TargetDistribution distribution = + model->PredictDistribution(example->features); + EXPECT_EQ(distribution.size(), 1u); + EXPECT_EQ(distribution.find(example->target_value)->second, 2); + } +} + +TEST_F(RandomTreeTest, UnseparableTrainingData) { + TrainingExample example_1({FeatureValue(123)}, TargetValue(1)); + TrainingExample example_2({FeatureValue(123)}, TargetValue(2)); + TrainingData training_data({&example_1, &example_2}); + std::unique_ptr<Model> model = trainer_.Train(training_data); + EXPECT_NE(model.get(), nullptr); + + // Each value should have a distribution with two targets with one count each. + Model::TargetDistribution distribution = + model->PredictDistribution(example_1.features); + EXPECT_EQ(distribution.size(), 2u); + EXPECT_EQ(distribution.find(example_1.target_value)->second, 1); + EXPECT_EQ(distribution.find(example_2.target_value)->second, 1); + + distribution = model->PredictDistribution(example_2.features); + EXPECT_EQ(distribution.size(), 2u); + EXPECT_EQ(distribution.find(example_1.target_value)->second, 1); + EXPECT_EQ(distribution.find(example_2.target_value)->second, 1); +} + +} // namespace learning +} // namespace media
diff --git a/media/learning/impl/random_tree_unittest.cc b/media/learning/impl/random_tree_unittest.cc deleted file mode 100644 index 0e8e9ec..0000000 --- a/media/learning/impl/random_tree_unittest.cc +++ /dev/null
@@ -1,119 +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 "media/learning/impl/random_tree.h" - -#include "testing/gtest/include/gtest/gtest.h" - -namespace media { -namespace learning { - -class RandomTreeTest : public testing::Test { - public: - RandomTree tree_; -}; - -TEST_F(RandomTreeTest, EmptyTrainingDataWorks) { - TrainingData empty; - tree_.Train(empty); - EXPECT_EQ(tree_.ComputeDistributionForTesting(FeatureVector()), nullptr); -} - -TEST_F(RandomTreeTest, UniformTrainingDataWorks) { - TrainingExample example({FeatureValue(123), FeatureValue(456)}, - TargetValue(789)); - TrainingData training_data; - const int n_examples = 10; - for (int i = 0; i < n_examples; i++) - training_data.push_back(&example); - tree_.Train(training_data); - - // The tree should produce a distribution for one value (our target), which - // has |n_examples| counts. - const RandomTree::TreeNode::TargetDistribution* distribution = - tree_.ComputeDistributionForTesting(example.features); - EXPECT_NE(distribution, nullptr); - EXPECT_EQ(distribution->size(), 1u); - EXPECT_EQ(distribution->find(example.target_value)->second, n_examples); -} - -TEST_F(RandomTreeTest, SimpleSeparableTrainingData) { - TrainingExample example_1({FeatureValue(123)}, TargetValue(1)); - TrainingExample example_2({FeatureValue(456)}, TargetValue(2)); - TrainingData training_data({&example_1, &example_2}); - tree_.Train(training_data); - - // Each value should have a distribution with one target value with one count. - const RandomTree::TreeNode::TargetDistribution* distribution = - tree_.ComputeDistributionForTesting(example_1.features); - EXPECT_NE(distribution, nullptr); - EXPECT_EQ(distribution->size(), 1u); - EXPECT_EQ(distribution->find(example_1.target_value)->second, 1); - - distribution = tree_.ComputeDistributionForTesting(example_2.features); - EXPECT_NE(distribution, nullptr); - EXPECT_EQ(distribution->size(), 1u); - EXPECT_EQ(distribution->find(example_2.target_value)->second, 1); -} - -TEST_F(RandomTreeTest, ComplexSeparableTrainingData) { - // Build a four-feature training set that's completely separable, but one - // needs all four features to do it. - TrainingDataStorage training_data_storage; - for (int f1 = 0; f1 < 2; f1++) { - for (int f2 = 0; f2 < 2; f2++) { - for (int f3 = 0; f3 < 2; f3++) { - for (int f4 = 0; f4 < 2; f4++) { - training_data_storage.push_back( - TrainingExample({FeatureValue(f1), FeatureValue(f2), - FeatureValue(f3), FeatureValue(f4)}, - TargetValue(f1 * 1 + f2 * 2 + f3 * 4 + f4 * 8))); - } - } - } - } - - // Add two copies of each example. Note that we do this after fully - // constructing |training_data_storage|, since it may realloc. - TrainingData training_data; - for (auto& example : training_data_storage) { - training_data.push_back(&example); - training_data.push_back(&example); - } - - tree_.Train(training_data); - - // Each example should have a distribution by itself, with two counts. - for (const TrainingExample* example : training_data) { - const RandomTree::TreeNode::TargetDistribution* distribution = - tree_.ComputeDistributionForTesting(example->features); - EXPECT_NE(distribution, nullptr); - EXPECT_EQ(distribution->size(), 1u); - EXPECT_EQ(distribution->find(example->target_value)->second, 2); - } -} - -TEST_F(RandomTreeTest, UnseparableTrainingData) { - TrainingExample example_1({FeatureValue(123)}, TargetValue(1)); - TrainingExample example_2({FeatureValue(123)}, TargetValue(2)); - TrainingData training_data({&example_1, &example_2}); - tree_.Train(training_data); - - // Each value should have a distribution with two targets with one count each. - const RandomTree::TreeNode::TargetDistribution* distribution = - tree_.ComputeDistributionForTesting(example_1.features); - EXPECT_NE(distribution, nullptr); - EXPECT_EQ(distribution->size(), 2u); - EXPECT_EQ(distribution->find(example_1.target_value)->second, 1); - EXPECT_EQ(distribution->find(example_2.target_value)->second, 1); - - distribution = tree_.ComputeDistributionForTesting(example_2.features); - EXPECT_NE(distribution, nullptr); - EXPECT_EQ(distribution->size(), 2u); - EXPECT_EQ(distribution->find(example_1.target_value)->second, 1); - EXPECT_EQ(distribution->find(example_2.target_value)->second, 1); -} - -} // namespace learning -} // namespace media
diff --git a/media/learning/impl/training_algorithm.h b/media/learning/impl/training_algorithm.h new file mode 100644 index 0000000..54bd7d9 --- /dev/null +++ b/media/learning/impl/training_algorithm.h
@@ -0,0 +1,27 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_LEARNING_IMPL_TRAINING_ALGORITHM_H_ +#define MEDIA_LEARNING_IMPL_TRAINING_ALGORITHM_H_ + +#include <memory> + +#include "base/callback.h" +#include "media/learning/common/training_example.h" +#include "media/learning/impl/model.h" + +namespace media { +namespace learning { + +// A TrainingAlgorithm takes as input training examples, and produces as output +// a trained model that can be used for prediction. +// Train a model with on |examples| and return it. +// TODO(liberato): Switch to a callback to return the model. +using TrainingAlgorithmCB = base::RepeatingCallback<std::unique_ptr<Model>( + const TrainingData& examples)>; + +} // namespace learning +} // namespace media + +#endif // MEDIA_LEARNING_IMPL_TRAINING_ALGORITHM_H_
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc index 91bac5fe..7c0ef17 100644 --- a/media/renderers/video_resource_updater.cc +++ b/media/renderers/video_resource_updater.cc
@@ -479,8 +479,15 @@ frame_resources_.size() > 3 ? frame_resources_[3].id : 0, frame->ColorSpace(), frame_resource_offset_, frame_resource_multiplier_, frame_bits_per_channel_); - yuv_video_quad->is_protected_video = - frame->metadata()->IsTrue(VideoFrameMetadata::PROTECTED_VIDEO); + if (frame->metadata()->IsTrue(VideoFrameMetadata::PROTECTED_VIDEO)) { + if (frame->metadata()->IsTrue(VideoFrameMetadata::HW_PROTECTED)) { + yuv_video_quad->protected_video_type = + ui::ProtectedVideoType::kHardwareProtected; + } else { + yuv_video_quad->protected_video_type = + ui::ProtectedVideoType::kSoftwareProtected; + } + } for (viz::ResourceId resource_id : yuv_video_quad->resources) { resource_provider_->ValidateResource(resource_id);
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc index 3d041ac..c18ce6bf8 100644 --- a/net/base/mime_util.cc +++ b/net/base/mime_util.cc
@@ -449,10 +449,12 @@ std::string* top_level_type, std::string* subtype) const { std::vector<std::string> components = base::SplitString( - type_string, "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - if (components.size() != 2 || - !HttpUtil::IsToken(components[0]) || - !HttpUtil::IsToken(components[1])) + type_string, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); + if (components.size() != 2) + return false; + TrimWhitespaceASCII(components[0], base::TRIM_LEADING, &components[0]); + TrimWhitespaceASCII(components[1], base::TRIM_TRAILING, &components[1]); + if (!HttpUtil::IsToken(components[0]) || !HttpUtil::IsToken(components[1])) return false; if (top_level_type)
diff --git a/net/base/mime_util.h b/net/base/mime_util.h index 2b53c0a..e7a9820 100644 --- a/net/base/mime_util.h +++ b/net/base/mime_util.h
@@ -66,6 +66,9 @@ // // If |top_level_type| is non-NULL, sets it to parsed top-level type string. // If |subtype| is non-NULL, sets it to parsed subtype string. +// +// This function strips leading and trailing whitespace from the MIME type. +// TODO: investigate if we should strip strictly HTTP whitespace. NET_EXPORT bool ParseMimeTypeWithoutParameter(const std::string& type_string, std::string* top_level_type, std::string* subtype);
diff --git a/net/base/mime_util_unittest.cc b/net/base/mime_util_unittest.cc index 04aa044..a2c1f74 100644 --- a/net/base/mime_util_unittest.cc +++ b/net/base/mime_util_unittest.cc
@@ -231,6 +231,32 @@ EXPECT_FALSE(ParseMimeTypeWithoutParameter("application/a/b/c", NULL, NULL)); + // Test leading and trailing whitespace + EXPECT_TRUE(ParseMimeTypeWithoutParameter(" text/plain", NULL, NULL)); + EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain ", NULL, NULL)); + EXPECT_FALSE(ParseMimeTypeWithoutParameter("text /plain", NULL, NULL)); + EXPECT_FALSE(ParseMimeTypeWithoutParameter("text/ plain ", NULL, NULL)); + + EXPECT_TRUE(ParseMimeTypeWithoutParameter("\ttext/plain", NULL, NULL)); + EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain\t", NULL, NULL)); + EXPECT_FALSE(ParseMimeTypeWithoutParameter("text\t/plain", NULL, NULL)); + EXPECT_FALSE(ParseMimeTypeWithoutParameter("text/\tplain ", NULL, NULL)); + + EXPECT_TRUE(ParseMimeTypeWithoutParameter("\vtext/plain", NULL, NULL)); + EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain\v", NULL, NULL)); + EXPECT_FALSE(ParseMimeTypeWithoutParameter("text\v/plain", NULL, NULL)); + EXPECT_FALSE(ParseMimeTypeWithoutParameter("text/\vplain ", NULL, NULL)); + + EXPECT_TRUE(ParseMimeTypeWithoutParameter("\rtext/plain", NULL, NULL)); + EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain\r", NULL, NULL)); + EXPECT_FALSE(ParseMimeTypeWithoutParameter("text\r/plain", NULL, NULL)); + EXPECT_FALSE(ParseMimeTypeWithoutParameter("text/\rplain ", NULL, NULL)); + + EXPECT_TRUE(ParseMimeTypeWithoutParameter("\ntext/plain", NULL, NULL)); + EXPECT_TRUE(ParseMimeTypeWithoutParameter("text/plain\n", NULL, NULL)); + EXPECT_FALSE(ParseMimeTypeWithoutParameter("text\n/plain", NULL, NULL)); + EXPECT_FALSE(ParseMimeTypeWithoutParameter("text/\nplain ", NULL, NULL)); + //EXPECT_TRUE(ParseMimeTypeWithoutParameter("video/mime;parameter")); }
diff --git a/ppapi/cpp/BUILD.gn b/ppapi/cpp/BUILD.gn index a83cd49..da877e90 100644 --- a/ppapi/cpp/BUILD.gn +++ b/ppapi/cpp/BUILD.gn
@@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/jumbo.gni") + if (is_nacl) { import("//build/config/nacl/config.gni") } @@ -9,7 +11,7 @@ if (is_nacl && is_nacl_glibc) { cpp_target_type = "shared_library" } else { - cpp_target_type = "static_library" + cpp_target_type = "jumbo_static_library" } # Link to this target to get the PPAPI C++ wrapper objects and plugin startup @@ -50,7 +52,7 @@ # Link to this target to get only the PPAPI C++ wrapper objects but not the # plugin startup code. Some plugins need special startup code that they supply # themselves. -source_set("objects") { +jumbo_source_set("objects") { sources = [ "array_output.cc", "array_output.h",
diff --git a/ppapi/host/BUILD.gn b/ppapi/host/BUILD.gn index 32d3328..56b4526 100644 --- a/ppapi/host/BUILD.gn +++ b/ppapi/host/BUILD.gn
@@ -2,7 +2,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -component("host") { +import("//build/config/jumbo.gni") + +jumbo_component("host") { output_name = "ppapi_host" sources = [
diff --git a/ppapi/proxy/BUILD.gn b/ppapi/proxy/BUILD.gn index 075e81e..49f3837 100644 --- a/ppapi/proxy/BUILD.gn +++ b/ppapi/proxy/BUILD.gn
@@ -2,13 +2,14 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/jumbo.gni") import("//build/config/nacl/config.gni") config("proxy_implementation") { defines = [ "PPAPI_PROXY_IMPLEMENTATION" ] } -component("proxy") { +jumbo_component("proxy") { output_name = "ppapi_proxy" sources = [ @@ -365,7 +366,7 @@ } } -static_library("test_support") { +jumbo_static_library("test_support") { testonly = true sources = [
diff --git a/ppapi/shared_impl/BUILD.gn b/ppapi/shared_impl/BUILD.gn index c60f43a..edddfc8b0 100644 --- a/ppapi/shared_impl/BUILD.gn +++ b/ppapi/shared_impl/BUILD.gn
@@ -2,9 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/jumbo.gni") import("//build/config/nacl/config.gni") -component("shared_impl") { +jumbo_component("shared_impl") { output_name = "ppapi_shared" sources = [
diff --git a/remoting/protocol/BUILD.gn b/remoting/protocol/BUILD.gn index f8af6ab9..fb9f4b4 100644 --- a/remoting/protocol/BUILD.gn +++ b/remoting/protocol/BUILD.gn
@@ -259,6 +259,7 @@ } deps += [ + "//third_party/webrtc/api:create_peerconnection_factory", "//third_party/webrtc/api/audio_codecs:audio_codecs_api", "//third_party/webrtc/api/audio_codecs/opus:audio_decoder_opus", "//third_party/webrtc/api/audio_codecs/opus:audio_encoder_opus",
diff --git a/remoting/protocol/webrtc_transport.cc b/remoting/protocol/webrtc_transport.cc index 098c2917..a4c78bc 100644 --- a/remoting/protocol/webrtc_transport.cc +++ b/remoting/protocol/webrtc_transport.cc
@@ -34,6 +34,7 @@ #include "third_party/webrtc/api/audio_codecs/audio_encoder_factory_template.h" #include "third_party/webrtc/api/audio_codecs/opus/audio_decoder_opus.h" #include "third_party/webrtc/api/audio_codecs/opus/audio_encoder_opus.h" +#include "third_party/webrtc/api/create_peerconnection_factory.h" #include "third_party/webrtc/api/stats/rtcstats_objects.h" #include "third_party/webrtc/api/video_codecs/builtin_video_decoder_factory.h"
diff --git a/remoting/resources/remoting_strings_bn.xtb b/remoting/resources/remoting_strings_bn.xtb index 6026b9f..a60498c4 100644 --- a/remoting/resources/remoting_strings_bn.xtb +++ b/remoting/resources/remoting_strings_bn.xtb
@@ -83,7 +83,7 @@ <translation id="2841013758207633010">সময়</translation> <translation id="2851754573186462851">Chromium অ্যাপ্লিকেশান স্ট্রীমিং</translation> <translation id="2888969873284818612">নেটওয়ার্ক সংক্রান্ত ত্রুটি ঘটেছে। আপনার ডিভাইস আবার অন-লাইনে এলে আমরা অ্যাপ্লিকেশানটি আবার চালু করব।</translation> -<translation id="2891243864890517178">Mac-এর জন্য (OS X Yosemite 10.10 ও তার বেশি)</translation> +<translation id="2891243864890517178">Mac-এর জন্য (OS X Yosemite 10.10 ও তার পরবর্তী ভার্সন)</translation> <translation id="289405675947420287">আপনার iOS ডিভাইস থেকে নিরাপদে কম্পিউটার অ্যাক্সেস করুন। এটি দ্রুত, সহজ এবং ফ্রি। • আপনি যে কম্পিউটারটি দূরবর্তীভাবে অ্যাক্সেস করতে চান সেটিতে Chrome ওয়েব স্টোর থেকে Chrome রিমোট ডেক্সটপ অ্যাপটি ডাউনলোড করুন।
diff --git a/remoting/resources/remoting_strings_te.xtb b/remoting/resources/remoting_strings_te.xtb index 29d12a2b..e575fe6 100644 --- a/remoting/resources/remoting_strings_te.xtb +++ b/remoting/resources/remoting_strings_te.xtb
@@ -82,7 +82,7 @@ <translation id="2803375539583399270">PINను నమోదు చేయండి</translation> <translation id="2841013758207633010">సమయం</translation> <translation id="2851754573186462851">Chromium అనువర్తన స్ట్రీమింగ్</translation> -<translation id="2888969873284818612">నెట్వర్క్ లోపం సంభవించింది. మీ పరికరం మళ్లీ ఆన్లైన్లోకి వచ్చినప్పుడు మేము అనువర్తనాన్ని పునఃప్రారంభిస్తాము.</translation> +<translation id="2888969873284818612">నెట్వర్క్ ఎర్రర్ ఏర్పడింది. మీ పరికరం మళ్లీ ఆన్లైన్లోకి వచ్చినప్పుడు మేము యాప్ను పునఃప్రారంభిస్తాము.</translation> <translation id="2891243864890517178">Macలో అయితే (OS X Yosemite 10.10 మరియు దాని తర్వాతి పై వెర్షన్లలో మాత్రమే పని చేస్తుంది)</translation> <translation id="289405675947420287">మీ iOS పరికరం నుండి మీ కంప్యూటర్ని సురక్షితంగా యాక్సెస్ చేయండి. ఇది వేగవంతం, సులభం మరియు ఉచితం.
diff --git a/services/identity/BUILD.gn b/services/identity/BUILD.gn index 85dffec..08e06ff 100644 --- a/services/identity/BUILD.gn +++ b/services/identity/BUILD.gn
@@ -56,6 +56,7 @@ sources = [ "identity_manager_impl_unittest.cc", "public/cpp/access_token_fetcher_unittest.cc", + "public/cpp/accounts_mutator_unittest.cc", "public/cpp/identity_manager_unittest.cc", "public/cpp/identity_test_environment_unittest.cc", "public/cpp/primary_account_access_token_fetcher_unittest.cc",
diff --git a/services/identity/public/cpp/BUILD.gn b/services/identity/public/cpp/BUILD.gn index 2cd07bc..fcce44f 100644 --- a/services/identity/public/cpp/BUILD.gn +++ b/services/identity/public/cpp/BUILD.gn
@@ -8,6 +8,8 @@ "access_token_fetcher.h", "access_token_info.cc", "access_token_info.h", + "accounts_mutator.cc", + "accounts_mutator.h", "identity_manager.cc", "identity_manager.h", "primary_account_access_token_fetcher.cc",
diff --git a/services/identity/public/cpp/accounts_mutator.cc b/services/identity/public/cpp/accounts_mutator.cc new file mode 100644 index 0000000..a80285a1 --- /dev/null +++ b/services/identity/public/cpp/accounts_mutator.cc
@@ -0,0 +1,21 @@ +// 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/identity/public/cpp/accounts_mutator.h" + +#include "components/signin/core/browser/profile_oauth2_token_service.h" + +namespace identity { + +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 new file mode 100644 index 0000000..471be5b3 --- /dev/null +++ b/services/identity/public/cpp/accounts_mutator.h
@@ -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. + +#ifndef SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNTS_MUTATOR_H_ +#define SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNTS_MUTATOR_H_ + +#include <string> + +#include "base/macros.h" + +class ProfileOAuth2TokenService; + +namespace identity { + +// Supports seeding of account info and mutation of refresh tokens for the +// user's Gaia accounts. +class AccountsMutator { + public: + 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); +}; + +} // namespace identity + +#endif // SERVICES_IDENTITY_PUBLIC_CPP_ACCOUNTS_MUTATOR_H_
diff --git a/services/identity/public/cpp/accounts_mutator_unittest.cc b/services/identity/public/cpp/accounts_mutator_unittest.cc new file mode 100644 index 0000000..36e7ffc8 --- /dev/null +++ b/services/identity/public/cpp/accounts_mutator_unittest.cc
@@ -0,0 +1,82 @@ +// 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/identity/public/cpp/accounts_mutator.h" + +#include "base/message_loop/message_loop.h" +#include "components/signin/core/browser/fake_profile_oauth2_token_service.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" +#include "services/identity/public/cpp/accounts_mutator.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +// Class that observes updates from ProfileOAuth2TokenService. +class TestTokenServiceObserver : public OAuth2TokenService::Observer { + public: + explicit TestTokenServiceObserver(OAuth2TokenService* token_service) + : token_service_(token_service) { + token_service_->AddObserver(this); + } + ~TestTokenServiceObserver() override { token_service_->RemoveObserver(this); } + + void set_on_refresh_tokens_loaded_callback(base::OnceClosure callback) { + on_refresh_tokens_loaded_callback_ = std::move(callback); + } + + private: + // OAuth2TokenService::Observer: + void OnRefreshTokensLoaded() override { + if (on_refresh_tokens_loaded_callback_) + std::move(on_refresh_tokens_loaded_callback_).Run(); + } + + OAuth2TokenService* token_service_; + base::OnceClosure on_refresh_tokens_loaded_callback_; +}; + +} // namespace + +namespace identity { +class AccountsMutatorTest : public testing::Test { + public: + AccountsMutatorTest() + : token_service_(&pref_service_), + token_service_observer_(&token_service_), + accounts_mutator_(&token_service_) { + ProfileOAuth2TokenService::RegisterProfilePrefs(pref_service_.registry()); + } + + FakeProfileOAuth2TokenService* token_service() { return &token_service_; } + + TestTokenServiceObserver* token_service_observer() { + return &token_service_observer_; + } + + AccountsMutator* accounts_mutator() { return &accounts_mutator_; } + + private: + base::MessageLoop message_loop_; + sync_preferences::TestingPrefServiceSyncable pref_service_; + FakeProfileOAuth2TokenService token_service_; + TestTokenServiceObserver token_service_observer_; + AccountsMutator accounts_mutator_; + + DISALLOW_COPY_AND_ASSIGN(AccountsMutatorTest); +}; + +// 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.cc b/services/identity/public/cpp/identity_manager.cc index 066f4de..01ff5ce2 100644 --- a/services/identity/public/cpp/identity_manager.cc +++ b/services/identity/public/cpp/identity_manager.cc
@@ -54,7 +54,8 @@ token_service_(token_service), account_tracker_service_(account_tracker_service), gaia_cookie_manager_service_(gaia_cookie_manager_service), - primary_account_mutator_(std::move(primary_account_mutator)) { + primary_account_mutator_(std::move(primary_account_mutator)), + accounts_mutator_(token_service_) { signin_manager_->AddObserver(this); token_service_->AddDiagnosticsObserver(this); token_service_->AddObserver(this); @@ -191,6 +192,10 @@ return primary_account_mutator_.get(); } +AccountsMutator* IdentityManager::GetAccountsMutator() { + return &accounts_mutator_; +} + void IdentityManager::AddObserver(Observer* observer) { observer_list_.AddObserver(observer); }
diff --git a/services/identity/public/cpp/identity_manager.h b/services/identity/public/cpp/identity_manager.h index 26764b7..9757a8d 100644 --- a/services/identity/public/cpp/identity_manager.h +++ b/services/identity/public/cpp/identity_manager.h
@@ -13,6 +13,7 @@ #include "components/signin/core/browser/signin_manager_base.h" #include "components/signin/core/browser/signin_metrics.h" #include "services/identity/public/cpp/access_token_fetcher.h" +#include "services/identity/public/cpp/accounts_mutator.h" #include "services/identity/public/cpp/scope_set.h" #if !defined(OS_CHROMEOS) @@ -259,6 +260,10 @@ // null. PrimaryAccountMutator* GetPrimaryAccountMutator(); + // Returns pointer to the object used to seed accounts and mutate state of + // accounts' refresh tokens. Guaranteed to be non-null. + AccountsMutator* GetAccountsMutator(); + // Methods to register or remove observers. void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); @@ -366,6 +371,10 @@ // account state is not supported on the current platform. std::unique_ptr<PrimaryAccountMutator> primary_account_mutator_; + // AccountsMutator instance. Guaranteed to be non-null, as this + // functionality is supported on all platforms. + AccountsMutator accounts_mutator_; + // Lists of observers. // Makes sure lists are empty on destruction. base::ObserverList<Observer, true>::Unchecked observer_list_;
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc index ec76064d..3d9f75f 100644 --- a/services/identity/public/cpp/identity_manager_unittest.cc +++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -2004,4 +2004,9 @@ identity_manager_observer()->batch_change_records().at(0).at(0)); } +TEST_F(IdentityManagerTest, GetAccountsMutator) { + AccountsMutator* mutator = identity_manager()->GetAccountsMutator(); + EXPECT_TRUE(mutator); +} + } // namespace identity
diff --git a/services/network/network_service_proxy_delegate.cc b/services/network/network_service_proxy_delegate.cc index 98fd61b..a1345bb 100644 --- a/services/network/network_service_proxy_delegate.cc +++ b/services/network/network_service_proxy_delegate.cc
@@ -212,6 +212,10 @@ std::move(callback).Run(); } +void NetworkServiceProxyDelegate::ClearBadProxiesCache() { + proxy_resolution_service_->ClearBadProxiesCache(); +} + bool NetworkServiceProxyDelegate::IsInProxyConfig( const net::ProxyServer& proxy_server) const { if (!proxy_server.is_valid() || proxy_server.is_direct())
diff --git a/services/network/network_service_proxy_delegate.h b/services/network/network_service_proxy_delegate.h index b91f3e6..6d36748 100644 --- a/services/network/network_service_proxy_delegate.h +++ b/services/network/network_service_proxy_delegate.h
@@ -78,6 +78,7 @@ void MarkProxiesAsBad(base::TimeDelta bypass_duration, const net::ProxyList& bad_proxies, MarkProxiesAsBadCallback callback) override; + void ClearBadProxiesCache() override; mojom::CustomProxyConfigPtr proxy_config_; mojo::Binding<mojom::CustomProxyConfigClient> binding_;
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index c1d6e7f..db8124d 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -79,6 +79,10 @@ // not layered onto the proxy resolution results for subsequent requests. MarkProxiesAsBad(mojo_base.mojom.TimeDelta bypass_duration, ProxyList bad_proxies) => (); + + // Clears the list of bad proxy servers that has been cached in the proxy + // resolution service. + ClearBadProxiesCache(); }; [EnableIf=is_chromeos]
diff --git a/services/network/resource_scheduler.cc b/services/network/resource_scheduler.cc index 317d1d1..8448f97a 100644 --- a/services/network/resource_scheduler.cc +++ b/services/network/resource_scheduler.cc
@@ -53,18 +53,6 @@ const base::Feature kHeadPrioritySupportedRequestsDelayable{ "HeadPriorityRequestsDelayable", base::FEATURE_DISABLED_BY_DEFAULT}; -// In the event that many resource requests are started quickly, this feature -// will periodically yield (e.g., delaying starting of requests) by posting a -// task and waiting for the task to run to resume. This allows other -// operations that rely on the IO thread (e.g., already running network -// requests) to make progress. -const base::Feature kNetworkSchedulerYielding{ - "NetworkSchedulerYielding", base::FEATURE_DISABLED_BY_DEFAULT}; -const char kMaxRequestsBeforeYieldingParam[] = "MaxRequestsBeforeYieldingParam"; -const int kMaxRequestsBeforeYieldingDefault = 5; -const char kYieldMsParam[] = "MaxYieldMs"; -const int kYieldMsDefault = 0; - enum StartMode { START_SYNC, START_ASYNC }; // Flags identifying various attributes of the request that are used @@ -84,7 +72,6 @@ CLIENT_KILL, SPDY_PROXY_DETECTED, REQUEST_REPRIORITIZED, - START_WAS_YIELDED, LONG_QUEUED_REQUESTS_TIMER_FIRED, }; @@ -104,8 +91,6 @@ return "SPDY_PROXY_DETECTED"; case RequestStartTrigger::REQUEST_REPRIORITIZED: return "REQUEST_REPRIORITIZED"; - case RequestStartTrigger::START_WAS_YIELDED: - return "START_WAS_YIELDED"; case RequestStartTrigger::LONG_QUEUED_REQUESTS_TIMER_FIRED: return "LONG_QUEUED_REQUESTS_TIMER_FIRED"; } @@ -397,8 +382,6 @@ in_flight_delayable_count_(0), total_layout_blocking_count_(0), num_skipped_scans_due_to_scheduled_start_(0), - started_requests_since_yielding_(0), - did_scheduler_yield_(false), network_quality_estimator_(network_quality_estimator), resource_scheduler_(resource_scheduler), tick_clock_(tick_clock), @@ -426,8 +409,6 @@ StartRequest(request, START_SYNC, RequestStartTrigger::NONE); } else { pending_requests_.Insert(request); - if (should_start == YIELD_SCHEDULER) - did_scheduler_yield_ = true; } } @@ -523,8 +504,7 @@ enum ShouldStartReqResult { DO_NOT_START_REQUEST_AND_STOP_SEARCHING, DO_NOT_START_REQUEST_AND_KEEP_SEARCHING, - START_REQUEST, - YIELD_SCHEDULER + START_REQUEST }; // Records the metrics related to number of requests in flight. @@ -712,21 +692,6 @@ void StartRequest(ScheduledResourceRequestImpl* request, StartMode start_mode, RequestStartTrigger trigger) { - if (resource_scheduler_->yielding_scheduler_enabled()) { - started_requests_since_yielding_ += 1; - if (started_requests_since_yielding_ == 1) { - // This is the first started request since last yielding. Post a task to - // reset the counter and start any yielded tasks if necessary. We post - // this now instead of when we first yield so that if there is a pause - // between requests the counter is reset. - resource_scheduler_->task_runner()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&Client::ResumeIfYielded, - weak_ptr_factory_.GetWeakPtr()), - resource_scheduler_->yield_time()); - } - } - // Only log on requests that were blocked by the ResourceScheduler. if (start_mode == START_ASYNC) { DCHECK_NE(RequestStartTrigger::NONE, trigger); @@ -827,7 +792,7 @@ // https://crbug.com/164101. Also, theoretically we should not count a // request-priority capable request against the delayable requests limit. if (supports_priority) - return ShouldStartOrYieldRequest(request); + return START_REQUEST; } // Non-delayable requests. @@ -896,34 +861,6 @@ num_skipped_scans_due_to_scheduled_start_ += 1; } - void ResumeIfYielded() { - bool yielded = did_scheduler_yield_; - started_requests_since_yielding_ = 0; - did_scheduler_yield_ = false; - - if (yielded) - LoadAnyStartablePendingRequests(RequestStartTrigger::START_WAS_YIELDED); - } - - // For a request that is ready to start, return START_REQUEST if the - // scheduler doesn't need to yield, else YIELD_SCHEDULER. - ShouldStartReqResult ShouldStartOrYieldRequest( - ScheduledResourceRequestImpl* request) const { - DCHECK_GE(started_requests_since_yielding_, 0); - - // Don't yield if: - // 1. The yielding scheduler isn't enabled - // 2. The resource is high priority - // 3. There haven't been enough recent requests to warrant yielding. - if (!resource_scheduler_->yielding_scheduler_enabled() || - request->url_request()->priority() >= kDelayablePriorityThreshold || - started_requests_since_yielding_ < - resource_scheduler_->max_requests_before_yielding()) { - return START_REQUEST; - } - return YIELD_SCHEDULER; - } - void LoadAnyStartablePendingRequests(RequestStartTrigger trigger) { // We iterate through all the pending requests, starting with the highest // priority one. For each entry, one of three things can happen: @@ -960,9 +897,6 @@ } else if (query_result == DO_NOT_START_REQUEST_AND_KEEP_SEARCHING) { ++request_iter; continue; - } else if (query_result == YIELD_SCHEDULER) { - did_scheduler_yield_ = true; - break; } else { DCHECK(query_result == DO_NOT_START_REQUEST_AND_STOP_SEARCHING); break; @@ -986,14 +920,6 @@ // to smarter task scheduling around reprioritization. int num_skipped_scans_due_to_scheduled_start_; - // The number of started requests since the last ResumeIfYielded task was - // run. - int started_requests_since_yielding_; - - // If the scheduler had to yield the start of a request since the last - // ResumeIfYielded task was run. - bool did_scheduler_yield_; - // Network quality estimator for network aware resource scheudling. This may // be null. const net::NetworkQualityEstimator* const network_quality_estimator_; @@ -1022,16 +948,6 @@ base::FeatureList::IsEnabled(kPrioritySupportedRequestsDelayable)), head_priority_requests_delayable_(base::FeatureList::IsEnabled( kHeadPrioritySupportedRequestsDelayable)), - yielding_scheduler_enabled_( - base::FeatureList::IsEnabled(kNetworkSchedulerYielding)), - max_requests_before_yielding_(base::GetFieldTrialParamByFeatureAsInt( - kNetworkSchedulerYielding, - kMaxRequestsBeforeYieldingParam, - kMaxRequestsBeforeYieldingDefault)), - yield_time_(base::TimeDelta::FromMilliseconds( - base::GetFieldTrialParamByFeatureAsInt(kNetworkSchedulerYielding, - kYieldMsParam, - kYieldMsDefault))), task_runner_(base::ThreadTaskRunnerHandle::Get()) { DCHECK(tick_clock_);
diff --git a/services/network/resource_scheduler.h b/services/network/resource_scheduler.h index 8c1d4fa1..a4bfbfce 100644 --- a/services/network/resource_scheduler.h +++ b/services/network/resource_scheduler.h
@@ -148,23 +148,9 @@ bool head_priority_requests_delayable() const { return head_priority_requests_delayable_; } - bool yielding_scheduler_enabled() const { - return yielding_scheduler_enabled_; - } - int max_requests_before_yielding() const { - return max_requests_before_yielding_; - } - base::TimeDelta yield_time() const { return yield_time_; } base::SequencedTaskRunner* task_runner() { return task_runner_.get(); } // Testing setters - void SetMaxRequestsBeforeYieldingForTesting( - int max_requests_before_yielding) { - max_requests_before_yielding_ = max_requests_before_yielding; - } - void SetYieldTimeForTesting(base::TimeDelta yield_time) { - yield_time_ = yield_time; - } void SetTaskRunnerForTesting( scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner) { task_runner_ = std::move(sequenced_task_runner); @@ -230,12 +216,6 @@ // be delayed while the parser is in head. bool head_priority_requests_delayable_; - // True if the scheduler should yield between several successive calls to - // start resource requests. - bool yielding_scheduler_enabled_; - int max_requests_before_yielding_; - base::TimeDelta yield_time_; - ResourceSchedulerParamsManager resource_scheduler_params_manager_; // The TaskRunner to post tasks on. Can be overridden for tests.
diff --git a/services/network/resource_scheduler_unittest.cc b/services/network/resource_scheduler_unittest.cc index d5266b0..ce618ff 100644 --- a/services/network/resource_scheduler_unittest.cc +++ b/services/network/resource_scheduler_unittest.cc
@@ -60,35 +60,8 @@ "PrioritySupportedRequestsDelayable"; const char kHeadPrioritySupportedRequestsDelayable[] = "HeadPriorityRequestsDelayable"; -const char kNetworkSchedulerYielding[] = "NetworkSchedulerYielding"; const size_t kMaxNumDelayableRequestsPerHostPerClient = 6; -void ConfigureYieldFieldTrial( - int max_requests_before_yielding, - int max_yield_ms, - base::test::ScopedFeatureList* scoped_feature_list) { - const std::string kTrialName = "TrialName"; - const std::string kGroupName = "GroupName"; // Value not used - const std::string kNetworkSchedulerYielding = "NetworkSchedulerYielding"; - - scoped_refptr<base::FieldTrial> trial = - base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName); - - std::map<std::string, std::string> params; - params["MaxRequestsBeforeYieldingParam"] = - base::IntToString(max_requests_before_yielding); - params["MaxYieldMs"] = base::IntToString(max_yield_ms); - ASSERT_TRUE( - base::FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams( - kTrialName, kGroupName, params)); - - std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); - feature_list->RegisterFieldTrialOverride( - kNetworkSchedulerYielding, base::FeatureList::OVERRIDE_ENABLE_FEATURE, - trial.get()); - scoped_feature_list->InitWithFeatureList(std::move(feature_list)); -} - class TestRequest { public: TestRequest(std::unique_ptr<net::URLRequest> url_request, @@ -495,189 +468,6 @@ 2); } -TEST_F(ResourceSchedulerTest, SchedulerYieldsOnSpdy) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitFromCommandLine(kNetworkSchedulerYielding, ""); - InitializeScheduler(); - - // The second low-priority request should yield. - scheduler_->SetMaxRequestsBeforeYieldingForTesting(1); - - // Set a custom yield time. - scheduler_->SetYieldTimeForTesting(base::TimeDelta::FromMilliseconds(42)); - - // Use a testing task runner so that we can control time. - auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); - scheduler_->SetTaskRunnerForTesting(task_runner); - - http_server_properties_.SetSupportsSpdy( - url::SchemeHostPort("https", "spdyhost", 443), true); - - std::unique_ptr<TestRequest> request( - NewRequest("https://spdyhost/low", net::LOWEST)); - std::unique_ptr<TestRequest> request2( - NewRequest("https://spdyhost/low", net::LOWEST)); - std::unique_ptr<TestRequest> request3( - NewRequest("https://spdyhost/low", net::LOWEST)); - - // Just before the yield task runs, only the first request should have - // started. - task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds(41)); - EXPECT_TRUE(request->started()); - EXPECT_FALSE(request2->started()); - EXPECT_FALSE(request3->started()); - - // Yield is done, run the next task. - task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds(1)); - EXPECT_TRUE(request2->started()); - EXPECT_FALSE(request3->started()); - - // Just before the yield task runs, only the first two requests should have - // started. - task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds(41)); - EXPECT_FALSE(request3->started()); - - // Yield is done, run the next task. - task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds(1)); - EXPECT_TRUE(request3->started()); -} - -// Same as SchedulerYieldsOnSpdy but uses FieldTrial Parameters for -// configuration. -TEST_F(ResourceSchedulerTest, SchedulerYieldFieldTrialParams) { - base::test::ScopedFeatureList scoped_feature_list; - - ConfigureYieldFieldTrial(1 /* requests before yielding */, - 42 /* yield time */, &scoped_feature_list); - InitializeScheduler(); - - // Make sure the parameters were properly set. - EXPECT_EQ(42, scheduler_->yield_time().InMilliseconds()); - EXPECT_EQ(1, scheduler_->max_requests_before_yielding()); - - // Use a testing task runner so that we can control time. - auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); - scheduler_->SetTaskRunnerForTesting(task_runner); - - http_server_properties_.SetSupportsSpdy( - url::SchemeHostPort("https", "spdyhost", 443), true); - - std::unique_ptr<TestRequest> request( - NewRequest("https://spdyhost/low", net::LOWEST)); - std::unique_ptr<TestRequest> request2( - NewRequest("https://spdyhost/low", net::LOWEST)); - - // Just before the yield task runs, only the first request should have - // started. - task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds(41)); - EXPECT_TRUE(request->started()); - EXPECT_FALSE(request2->started()); - - // Yield is done, run the next task. - task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds(1)); - EXPECT_TRUE(request2->started()); -} - -TEST_F(ResourceSchedulerTest, YieldingDisabled) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitFromCommandLine("", kNetworkSchedulerYielding); - InitializeScheduler(); - - // We're setting a yield parameter, but no yielding will happen since it's - // disabled. - scheduler_->SetMaxRequestsBeforeYieldingForTesting(1); - - http_server_properties_.SetSupportsSpdy( - url::SchemeHostPort("https", "spdyhost", 443), true); - - std::unique_ptr<TestRequest> request( - NewRequest("https://spdyhost/low", net::LOWEST)); - std::unique_ptr<TestRequest> request2( - NewRequest("https://spdyhost/low", net::LOWEST)); - EXPECT_TRUE(request->started()); - EXPECT_TRUE(request2->started()); -} - -TEST_F(ResourceSchedulerTest, SchedulerDoesNotYieldH1) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitFromCommandLine(kNetworkSchedulerYielding, ""); - InitializeScheduler(); - SetMaxDelayableRequests(1); - - // Use a testing task runner so that we can control time. - auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); - scheduler_->SetTaskRunnerForTesting(task_runner); - - // Yield after each request. - scheduler_->SetMaxRequestsBeforeYieldingForTesting(1); - scheduler_->SetYieldTimeForTesting(base::TimeDelta::FromMilliseconds(42)); - - std::unique_ptr<TestRequest> request( - NewRequest("https://host/low", net::LOWEST)); - std::unique_ptr<TestRequest> request2( - NewRequest("https://host/low", net::LOWEST)); - - EXPECT_TRUE(request->started()); - EXPECT_FALSE(request2->started()); - - // Finish the first task so that the second can start. - request = nullptr; - - // Run tasks without advancing time, if there were yielding the next task - // wouldn't start. - task_runner->RunUntilIdle(); - - // The next task started, so there was no yielding. - EXPECT_TRUE(request2->started()); -} - -TEST_F(ResourceSchedulerTest, SchedulerDoesNotYieldAltSchemes) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitFromCommandLine(kNetworkSchedulerYielding, ""); - InitializeScheduler(); - - // Yield after each request. - scheduler_->SetMaxRequestsBeforeYieldingForTesting(1); - scheduler_->SetYieldTimeForTesting(base::TimeDelta::FromMilliseconds(42)); - - std::unique_ptr<TestRequest> request( - NewRequest("yyy://host/low", net::LOWEST)); - std::unique_ptr<TestRequest> request2( - NewRequest("zzz://host/low", net::LOWEST)); - - EXPECT_TRUE(request->started()); - EXPECT_TRUE(request2->started()); -} - -TEST_F(ResourceSchedulerTest, SchedulerDoesNotYieldSyncRequests) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitFromCommandLine(kNetworkSchedulerYielding, ""); - InitializeScheduler(); - - // The second low-priority request should yield. - scheduler_->SetMaxRequestsBeforeYieldingForTesting(1); - - // Use spdy so that we don't throttle. - http_server_properties_.SetSupportsSpdy( - url::SchemeHostPort("https", "spdyhost", 443), true); - - std::unique_ptr<TestRequest> request( - NewRequest("https://spdyhost/low", net::LOWEST)); - std::unique_ptr<TestRequest> request2( - NewRequest("https://spdyhost/low", net::LOWEST)); // yields - - // Add a synchronous request, it shouldn't yield. - std::unique_ptr<TestRequest> sync_request( - NewSyncRequest("http://spdyhost/low", net::LOWEST)); - - EXPECT_TRUE(request->started()); - EXPECT_FALSE(request2->started()); - EXPECT_TRUE(sync_request->started()); // The sync request started. - - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(request2->started()); -} - TEST_F(ResourceSchedulerTest, MaxRequestsPerHostForSpdyWhenNotDelayable) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitFromCommandLine("", @@ -805,11 +595,6 @@ } TEST_F(ResourceSchedulerTest, LimitedNumberOfDelayableRequestsInFlight) { - // The yielding feature will sometimes yield requests before they get a - // chance to start, which conflicts this test. So disable the feature. - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitFromCommandLine("", kNetworkSchedulerYielding); - // Throw in one high priority request to make sure that's not a factor. std::unique_ptr<TestRequest> high( NewRequest("http://host/high", net::HIGHEST));
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_base.h b/services/resource_coordinator/coordination_unit/coordination_unit_base.h index 1f63890..85a7600 100644 --- a/services/resource_coordinator/coordination_unit/coordination_unit_base.h +++ b/services/resource_coordinator/coordination_unit/coordination_unit_base.h
@@ -8,6 +8,7 @@ #include <memory> #include "base/callback.h" +#include "base/macros.h" #include "base/observer_list.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/interface_request.h" @@ -130,13 +131,15 @@ mojo::Binding<MojoInterfaceClass>& binding() { return binding_; } - protected: static CoordinationUnitClass* GetCoordinationUnitByID( CoordinationUnitGraph* graph, const CoordinationUnitID cu_id) { DCHECK(cu_id.type == CoordinationUnitClass::Type()); auto* cu = graph->GetCoordinationUnitByID(cu_id); - DCHECK(cu->id().type == CoordinationUnitClass::Type()); + if (!cu) + return nullptr; + + CHECK_EQ(cu->id().type, CoordinationUnitClass::Type()); return static_cast<CoordinationUnitClass*>(cu); }
diff --git a/services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.cc b/services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.cc index ee129155..b03f9c0 100644 --- a/services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.cc +++ b/services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.cc
@@ -31,6 +31,16 @@ child_frame->RemoveParentFrame(this); } +void FrameCoordinationUnitImpl::SetProcess(const CoordinationUnitID& cu_id) { + ProcessCoordinationUnitImpl* process_cu = + ProcessCoordinationUnitImpl::GetCoordinationUnitByID(graph_, cu_id); + if (!process_cu) + return; + DCHECK(!process_coordination_unit_); + process_coordination_unit_ = process_cu; + process_cu->AddFrame(this); +} + void FrameCoordinationUnitImpl::AddChildFrame(const CoordinationUnitID& cu_id) { DCHECK(cu_id != id()); FrameCoordinationUnitImpl* frame_cu = @@ -178,12 +188,6 @@ page_coordination_unit_ = page_coordination_unit; } -void FrameCoordinationUnitImpl::AddProcessCoordinationUnit( - ProcessCoordinationUnitImpl* process_coordination_unit) { - DCHECK(!process_coordination_unit_); - process_coordination_unit_ = process_coordination_unit; -} - void FrameCoordinationUnitImpl::RemovePageCoordinationUnit( PageCoordinationUnitImpl* page_coordination_unit) { DCHECK(page_coordination_unit == page_coordination_unit_);
diff --git a/services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.h b/services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.h index b3f43c6..783a5c1 100644 --- a/services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.h +++ b/services/resource_coordinator/coordination_unit/frame_coordination_unit_impl.h
@@ -30,6 +30,7 @@ ~FrameCoordinationUnitImpl() override; // FrameCoordinationUnit implementation. + void SetProcess(const CoordinationUnitID& cu_id) override; void AddChildFrame(const CoordinationUnitID& cu_id) override; void RemoveChildFrame(const CoordinationUnitID& cu_id) override; void SetAudibility(bool audible) override;
diff --git a/services/resource_coordinator/coordination_unit/mock_coordination_unit_graphs.cc b/services/resource_coordinator/coordination_unit/mock_coordination_unit_graphs.cc index c0fd8c56..07d7b16 100644 --- a/services/resource_coordinator/coordination_unit/mock_coordination_unit_graphs.cc +++ b/services/resource_coordinator/coordination_unit/mock_coordination_unit_graphs.cc
@@ -32,7 +32,7 @@ page(TestCoordinationUnitWrapper<PageCoordinationUnitImpl>::Create( graph)) { page->AddFrame(frame->id()); - process->AddFrame(frame->id()); + frame->SetProcess(process->id()); process->SetPID(1); } @@ -49,7 +49,7 @@ other_page(TestCoordinationUnitWrapper<PageCoordinationUnitImpl>::Create( graph)) { other_page->AddFrame(other_frame->id()); - process->AddFrame(other_frame->id()); + other_frame->SetProcess(process->id()); } MockMultiplePagesInSingleProcessCoordinationUnitGraph:: @@ -67,7 +67,7 @@ graph)) { frame->AddChildFrame(child_frame->id()); page->AddFrame(child_frame->id()); - other_process->AddFrame(child_frame->id()); + child_frame->SetProcess(other_process->id()); other_process->SetPID(2); } @@ -86,7 +86,7 @@ graph)) { other_frame->AddChildFrame(child_frame->id()); other_page->AddFrame(child_frame->id()); - other_process->AddFrame(child_frame->id()); + child_frame->SetProcess(other_process->id()); other_process->SetPID(2); }
diff --git a/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.cc b/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.cc index feb95ba..b84830b 100644 --- a/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.cc +++ b/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.cc
@@ -26,12 +26,12 @@ child_frame->RemoveProcessCoordinationUnit(this); } -void ProcessCoordinationUnitImpl::AddFrame(const CoordinationUnitID& cu_id) { - DCHECK(cu_id.type == CoordinationUnitType::kFrame); - auto* frame_cu = - FrameCoordinationUnitImpl::GetCoordinationUnitByID(graph_, cu_id); - if (frame_cu) - AddFrameImpl(frame_cu); +void ProcessCoordinationUnitImpl::AddFrame( + FrameCoordinationUnitImpl* frame_cu) { + const bool inserted = frame_coordination_units_.insert(frame_cu).second; + DCHECK(inserted); + if (frame_cu->lifecycle_state() == mojom::LifecycleState::kFrozen) + IncrementNumFrozenFrames(); } void ProcessCoordinationUnitImpl::SetCPUUsage(double cpu_usage) { @@ -56,14 +56,31 @@ } void ProcessCoordinationUnitImpl::SetPID(base::ProcessId pid) { - // The PID can only be set once. - DCHECK_EQ(process_id_, base::kNullProcessId); + // Either this is the initial process associated with this process CU, + // or it's a subsequent process. In the latter case, there must have been + // an exit status associated with the previous process. + DCHECK(process_id_ == base::kNullProcessId || exit_status_.has_value()); graph()->BeforeProcessPidChange(this, pid); + process_id_ = pid; + + // Clear launch time and exit status for the previous process (if any). + launch_time_ = base::Time(); + exit_status_.reset(); + + // Also clear the measurement data (if any), as it references the previous + // process. + private_footprint_kb_ = 0; + cumulative_cpu_usage_ = base::TimeDelta(); + SetProperty(mojom::PropertyType::kPID, pid); } +void ProcessCoordinationUnitImpl::SetProcessExitStatus(int32_t exit_status) { + exit_status_ = exit_status; +} + void ProcessCoordinationUnitImpl::OnRendererIsBloated() { SendEvent(mojom::Event::kRendererIsBloated); } @@ -111,16 +128,6 @@ observer.OnProcessPropertyChanged(this, property_type, value); } -void ProcessCoordinationUnitImpl::AddFrameImpl( - FrameCoordinationUnitImpl* frame_cu) { - const bool inserted = frame_coordination_units_.insert(frame_cu).second; - if (inserted) { - frame_cu->AddProcessCoordinationUnit(this); - if (frame_cu->lifecycle_state() == mojom::LifecycleState::kFrozen) - IncrementNumFrozenFrames(); - } -} - void ProcessCoordinationUnitImpl::RemoveFrame( FrameCoordinationUnitImpl* frame_cu) { DCHECK(base::ContainsKey(frame_coordination_units_, frame_cu));
diff --git a/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.h b/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.h index d01b13a7..f2535aa0 100644 --- a/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.h +++ b/services/resource_coordinator/coordination_unit/process_coordination_unit_impl.h
@@ -6,6 +6,7 @@ #define SERVICES_RESOURCE_COORDINATOR_COORDINATION_UNIT_PROCESS_COORDINATION_UNIT_IMPL_H_ #include "base/macros.h" +#include "base/optional.h" #include "base/process/process_handle.h" #include "base/time/time.h" #include "services/resource_coordinator/coordination_unit/coordination_unit_base.h" @@ -14,6 +15,16 @@ class FrameCoordinationUnitImpl; +// A process coordination unit follows the lifetime of a RenderProcessHost. +// It may reference zero or one processes at a time, but during its lifetime, it +// may reference more than one process. This can happen if the associated +// renderer crashes, and an associated frame is then reloaded or re-navigated. +// The state of the process CU goes through: +// 1. Created, no PID. +// 2. Process started, have PID - in the case where the associated render +// process fails to start, this state may not occur. +// 3. Process died or falied to start, have exit status. +// 4. Back to 2. class ProcessCoordinationUnitImpl : public CoordinationUnitInterface<ProcessCoordinationUnitImpl, mojom::ProcessCoordinationUnit, @@ -28,12 +39,12 @@ ~ProcessCoordinationUnitImpl() override; // mojom::ProcessCoordinationUnit implementation. - void AddFrame(const CoordinationUnitID& cu_id) override; void SetCPUUsage(double cpu_usage) override; void SetExpectedTaskQueueingDuration(base::TimeDelta duration) override; void SetLaunchTime(base::Time launch_time) override; void SetMainThreadTaskLoadIsLow(bool main_thread_task_load_is_low) override; void SetPID(base::ProcessId pid) override; + void SetProcessExitStatus(int32_t exit_status) override; void OnRendererIsBloated() override; // Private implementation properties. @@ -52,7 +63,10 @@ base::ProcessId process_id() const { return process_id_; } base::Time launch_time() const { return launch_time_; } + base::Optional<int32_t> exit_status() const { return exit_status_; } + // Add |frame_cu| to this process. + void AddFrame(FrameCoordinationUnitImpl* frame_cu); // Removes |frame_cu| from the set of frames hosted by this process. Invoked // from the destructor of FrameCoordinationUnitImpl. void RemoveFrame(FrameCoordinationUnitImpl* frame_cu); @@ -67,8 +81,6 @@ void OnPropertyChanged(mojom::PropertyType property_type, int64_t value) override; - void AddFrameImpl(FrameCoordinationUnitImpl* frame_cu); - void DecrementNumFrozenFrames(); void IncrementNumFrozenFrames(); @@ -77,6 +89,7 @@ base::ProcessId process_id_ = base::kNullProcessId; base::Time launch_time_; + base::Optional<int32_t> exit_status_; std::set<FrameCoordinationUnitImpl*> frame_coordination_units_;
diff --git a/services/resource_coordinator/coordination_unit/process_coordination_unit_impl_unittest.cc b/services/resource_coordinator/coordination_unit/process_coordination_unit_impl_unittest.cc index b2ceb510..697f13a 100644 --- a/services/resource_coordinator/coordination_unit/process_coordination_unit_impl_unittest.cc +++ b/services/resource_coordinator/coordination_unit/process_coordination_unit_impl_unittest.cc
@@ -71,4 +71,45 @@ cu_graph.frame->SetLifecycleState(mojom::LifecycleState::kFrozen); } +TEST_F(ProcessCoordinationUnitImplTest, ProcessLifeCycle) { + auto process_cu = CreateCoordinationUnit<ProcessCoordinationUnitImpl>(); + + // Test the potential lifecycles of a process CU. + // First go to exited without an intervening PID, as would happen + // in the case the process fails to start. + EXPECT_FALSE(process_cu->exit_status()); + constexpr int32_t kExitStatus = 0xF00; + process_cu->SetProcessExitStatus(kExitStatus); + EXPECT_TRUE(process_cu->exit_status()); + EXPECT_EQ(kExitStatus, process_cu->exit_status().value()); + + // Next go through PID->exit status. + constexpr base::ProcessId kTestPid = 0xCAFE; + process_cu->SetPID(kTestPid); + // Resurrection should clear the exit status. + EXPECT_FALSE(process_cu->exit_status()); + + EXPECT_EQ(base::Time(), process_cu->launch_time()); + EXPECT_EQ(0U, process_cu->private_footprint_kb()); + EXPECT_EQ(base::TimeDelta(), process_cu->cumulative_cpu_usage()); + + process_cu->SetLaunchTime(base::Time::Now()); + process_cu->set_private_footprint_kb(10U); + process_cu->set_cumulative_cpu_usage(base::TimeDelta::FromMicroseconds(1)); + + // Kill it again and verify the properties above stick around. + process_cu->SetProcessExitStatus(kExitStatus); + + EXPECT_NE(base::Time(), process_cu->launch_time()); + EXPECT_NE(0U, process_cu->private_footprint_kb()); + EXPECT_NE(base::TimeDelta(), process_cu->cumulative_cpu_usage()); + + // Resurrect again and verify the launch time and measurements + // are cleared. + process_cu->SetPID(kTestPid); + EXPECT_EQ(base::Time(), process_cu->launch_time()); + EXPECT_EQ(0U, process_cu->private_footprint_kb()); + EXPECT_EQ(base::TimeDelta(), process_cu->cumulative_cpu_usage()); +} + } // namespace resource_coordinator
diff --git a/services/resource_coordinator/observers/metrics_collector_unittest.cc b/services/resource_coordinator/observers/metrics_collector_unittest.cc index 38eae02e..da72f935 100644 --- a/services/resource_coordinator/observers/metrics_collector_unittest.cc +++ b/services/resource_coordinator/observers/metrics_collector_unittest.cc
@@ -351,7 +351,7 @@ auto frame_cu = CreateCoordinationUnit<FrameCoordinationUnitImpl>(); page_cu->AddFrame(frame_cu->id()); - process_cu->AddFrame(frame_cu->id()); + frame_cu->SetProcess(process_cu->id()); ukm::TestUkmRecorder ukm_recorder; coordination_unit_graph()->set_ukm_recorder(&ukm_recorder);
diff --git a/services/resource_coordinator/public/cpp/frame_resource_coordinator.cc b/services/resource_coordinator/public/cpp/frame_resource_coordinator.cc index f4782191..aa57c4f 100644 --- a/services/resource_coordinator/public/cpp/frame_resource_coordinator.cc +++ b/services/resource_coordinator/public/cpp/frame_resource_coordinator.cc
@@ -4,6 +4,8 @@ #include "services/resource_coordinator/public/cpp/frame_resource_coordinator.h" +#include "services/resource_coordinator/public/cpp/process_resource_coordinator.h" + namespace resource_coordinator { FrameResourceCoordinator::FrameResourceCoordinator( @@ -16,6 +18,15 @@ FrameResourceCoordinator::~FrameResourceCoordinator() = default; +void FrameResourceCoordinator::SetProcess( + const ProcessResourceCoordinator& process) { + if (!service_ || !process.service()) + return; + process.service()->GetID( + base::BindOnce(&FrameResourceCoordinator::SetProcessByID, + weak_ptr_factory_.GetWeakPtr())); +} + void FrameResourceCoordinator::SetAudibility(bool audible) { if (!service_) return; @@ -31,7 +42,7 @@ void FrameResourceCoordinator::AddChildFrame( const FrameResourceCoordinator& child) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (!service_) + if (!service_ || !child.service()) return; // We could keep the ID around ourselves, but this hop ensures that the child // has been created on the service-side. @@ -43,7 +54,7 @@ void FrameResourceCoordinator::RemoveChildFrame( const FrameResourceCoordinator& child) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (!service_) + if (!service_ || !child.service()) return; child.service()->GetID( base::BindOnce(&FrameResourceCoordinator::RemoveChildFrameByID, @@ -56,16 +67,25 @@ provider->CreateFrameCoordinationUnit(mojo::MakeRequest(&service_), cu_id); } +void FrameResourceCoordinator::SetProcessByID( + const CoordinationUnitID& process_id) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + if (service_) + service_->SetProcess(process_id); +} + void FrameResourceCoordinator::AddChildFrameByID( const CoordinationUnitID& child_id) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - service_->AddChildFrame(child_id); + if (service_) + service_->AddChildFrame(child_id); } void FrameResourceCoordinator::RemoveChildFrameByID( const CoordinationUnitID& child_id) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - service_->RemoveChildFrame(child_id); + if (service_) + service_->RemoveChildFrame(child_id); } } // namespace resource_coordinator
diff --git a/services/resource_coordinator/public/cpp/frame_resource_coordinator.h b/services/resource_coordinator/public/cpp/frame_resource_coordinator.h index c452abd..6906fc3 100644 --- a/services/resource_coordinator/public/cpp/frame_resource_coordinator.h +++ b/services/resource_coordinator/public/cpp/frame_resource_coordinator.h
@@ -12,6 +12,8 @@ namespace resource_coordinator { +class ProcessResourceCoordinator; + class COMPONENT_EXPORT(SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP) FrameResourceCoordinator : public ResourceCoordinatorInterface<mojom::FrameCoordinationUnitPtr, @@ -20,15 +22,20 @@ FrameResourceCoordinator(service_manager::Connector* connector); ~FrameResourceCoordinator() override; + void SetProcess(const ProcessResourceCoordinator& process); void SetAudibility(bool audible); void OnAlertFired(); void AddChildFrame(const FrameResourceCoordinator& child); void RemoveChildFrame(const FrameResourceCoordinator& child); + // Closes the connection to the service. + void reset() { service_.reset(); } + private: void ConnectToService(mojom::CoordinationUnitProviderPtr& provider, const CoordinationUnitID& cu_id) override; + void SetProcessByID(const CoordinationUnitID& process_id); void AddChildFrameByID(const CoordinationUnitID& child_id); void RemoveChildFrameByID(const CoordinationUnitID& child_id);
diff --git a/services/resource_coordinator/public/cpp/page_resource_coordinator.cc b/services/resource_coordinator/public/cpp/page_resource_coordinator.cc index ddf98d4..69aa40a 100644 --- a/services/resource_coordinator/public/cpp/page_resource_coordinator.cc +++ b/services/resource_coordinator/public/cpp/page_resource_coordinator.cc
@@ -58,7 +58,7 @@ void PageResourceCoordinator::AddFrame(const FrameResourceCoordinator& frame) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (!service_) + if (!service_ || !frame.service()) return; // We could keep the ID around ourselves, but this hop ensures that the child // has been created on the service-side. @@ -69,7 +69,7 @@ void PageResourceCoordinator::RemoveFrame( const FrameResourceCoordinator& frame) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (!service_) + if (!service_ || !frame.service()) return; frame.service()->GetID( base::BindOnce(&PageResourceCoordinator::RemoveFrameByID,
diff --git a/services/resource_coordinator/public/cpp/process_resource_coordinator.cc b/services/resource_coordinator/public/cpp/process_resource_coordinator.cc index aacac596..b45a93c8 100644 --- a/services/resource_coordinator/public/cpp/process_resource_coordinator.cc +++ b/services/resource_coordinator/public/cpp/process_resource_coordinator.cc
@@ -15,13 +15,15 @@ CoordinationUnitID new_cu_id(CoordinationUnitType::kProcess, CoordinationUnitID::RANDOM_ID); ResourceCoordinatorInterface::ConnectToService(connector, new_cu_id); - DCHECK(service_); } ProcessResourceCoordinator::~ProcessResourceCoordinator() = default; void ProcessResourceCoordinator::OnProcessLaunched( const base::Process& process) { + if (!service_) + return; + // TODO(fdoray): Merge ProcessCoordinationUnit::SetPID/SetLaunchTime(). service_->SetPID(process.Pid()); service_->SetLaunchTime( @@ -37,17 +39,17 @@ } void ProcessResourceCoordinator::SetCPUUsage(double cpu_usage) { + if (!service_) + return; + service_->SetCPUUsage(cpu_usage); } -void ProcessResourceCoordinator::AddFrame( - const FrameResourceCoordinator& frame) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // We could keep the ID around ourselves, but this hop ensures that the child - // has been created on the service-side. - frame.service()->GetID( - base::BindOnce(&ProcessResourceCoordinator::AddFrameByID, - weak_ptr_factory_.GetWeakPtr())); +void ProcessResourceCoordinator::SetProcessExitStatus(int32_t exit_status) { + if (!service_) + return; + + service_->SetProcessExitStatus(exit_status); } void ProcessResourceCoordinator::ConnectToService( @@ -56,9 +58,4 @@ provider->CreateProcessCoordinationUnit(mojo::MakeRequest(&service_), cu_id); } -void ProcessResourceCoordinator::AddFrameByID(const CoordinationUnitID& cu_id) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - service_->AddFrame(cu_id); -} - } // namespace resource_coordinator
diff --git a/services/resource_coordinator/public/cpp/process_resource_coordinator.h b/services/resource_coordinator/public/cpp/process_resource_coordinator.h index 5828056..882c5b3 100644 --- a/services/resource_coordinator/public/cpp/process_resource_coordinator.h +++ b/services/resource_coordinator/public/cpp/process_resource_coordinator.h
@@ -26,14 +26,12 @@ void OnProcessLaunched(const base::Process& process); void SetCPUUsage(double usage); - void AddFrame(const FrameResourceCoordinator& frame); + void SetProcessExitStatus(int32_t exit_status); private: void ConnectToService(mojom::CoordinationUnitProviderPtr& provider, const CoordinationUnitID& cu_id) override; - void AddFrameByID(const CoordinationUnitID& cu_id); - THREAD_CHECKER(thread_checker_); // The WeakPtrFactory should come last so the weak ptrs are invalidated
diff --git a/services/resource_coordinator/public/mojom/coordination_unit.mojom b/services/resource_coordinator/public/mojom/coordination_unit.mojom index e43d364..62e4a47 100644 --- a/services/resource_coordinator/public/mojom/coordination_unit.mojom +++ b/services/resource_coordinator/public/mojom/coordination_unit.mojom
@@ -54,6 +54,9 @@ // children. GetID() => (CoordinationUnitID id); + // Sets the process hosting this frame. + SetProcess(CoordinationUnitID id); + // Add a new binding to an existing FrameCoordinationUnit. AddBinding(FrameCoordinationUnit& request); AddChildFrame(CoordinationUnitID cu_id); @@ -106,7 +109,6 @@ // Add a new binding to an existing ProcessCoordinationUnit. AddBinding(ProcessCoordinationUnit& request); - AddFrame(CoordinationUnitID cu_id); // Property signals. SetCPUUsage(double cpu_usage); @@ -114,6 +116,8 @@ SetLaunchTime(mojo_base.mojom.Time launch_time); SetMainThreadTaskLoadIsLow(bool main_thread_task_load_is_low); SetPID(mojo_base.mojom.ProcessId pid); + // Called when the process is known to have died or to have failed to start. + SetProcessExitStatus(int32 exit_status); // Event signals.
diff --git a/services/service_manager/public/cpp/service_binding.cc b/services/service_manager/public/cpp/service_binding.cc index cac9eef..ed8c57a 100644 --- a/services/service_manager/public/cpp/service_binding.cc +++ b/services/service_manager/public/cpp/service_binding.cc
@@ -67,13 +67,14 @@ void ServiceBinding::OnStart(const Identity& identity, OnStartCallback callback) { identity_ = identity; - service_->OnStart(); if (!pending_connector_request_.is_pending()) connector_ = Connector::Create(&pending_connector_request_); std::move(callback).Run(std::move(pending_connector_request_), mojo::MakeRequest(&service_control_)); + service_->OnStart(); + // Execute any prior |RequestClose()| request on the service's behalf. if (request_closure_on_start_) service_control_->RequestQuit();
diff --git a/services/service_manager/public/cpp/test/BUILD.gn b/services/service_manager/public/cpp/test/BUILD.gn index 430f845e..52e2d455 100644 --- a/services/service_manager/public/cpp/test/BUILD.gn +++ b/services/service_manager/public/cpp/test/BUILD.gn
@@ -51,12 +51,18 @@ sources = [ "test_connector_factory.cc", "test_connector_factory.h", + "test_service.cc", + "test_service.h", "test_service_decorator.cc", "test_service_decorator.h", + "test_service_manager.cc", + "test_service_manager.h", ] public_deps = [ "//base", + "//services/service_manager", + "//services/service_manager/background:lib", "//services/service_manager/public/cpp", "//services/service_manager/public/mojom", ]
diff --git a/services/service_manager/public/cpp/test/test_connector_factory.cc b/services/service_manager/public/cpp/test/test_connector_factory.cc index b4184dac..75832d4 100644 --- a/services/service_manager/public/cpp/test/test_connector_factory.cc +++ b/services/service_manager/public/cpp/test/test_connector_factory.cc
@@ -196,10 +196,12 @@ class ProxiedServiceConnector : public mojom::Connector { public: ProxiedServiceConnector( + TestConnectorFactory* factory, TestConnectorFactory::NameToServiceProxyMap* proxies, TestConnectorFactory::NameToServiceHandlerMap* handlers, const base::Token& test_instance_group) : fake_guid_(base::Token::CreateRandom()), + factory_(factory), proxies_(proxies), handlers_(handlers), test_instance_group_(test_instance_group) {} @@ -230,6 +232,12 @@ mojo::ScopedMessagePipeHandle interface_pipe, BindInterfaceCallback callback) override { auto* proxy = GetServiceProxy(service_filter.service_name()); + if (!proxy && factory_->ignore_unknown_service_requests()) { + std::move(callback).Run(mojom::ConnectResult::ACCESS_DENIED, + base::nullopt); + return; + } + CHECK(proxy) << "TestConnectorFactory received a BindInterface request for an " << "unregistered service '" << service_filter.service_name() << "'"; @@ -271,6 +279,7 @@ } const base::Token fake_guid_; + TestConnectorFactory* const factory_; TestConnectorFactory::NameToServiceProxyMap* const proxies_; TestConnectorFactory::NameToServiceHandlerMap* const handlers_; const base::Token test_instance_group_; @@ -284,7 +293,7 @@ TestConnectorFactory::TestConnectorFactory() { test_instance_group_ = base::Token::CreateRandom(); impl_ = std::make_unique<ProxiedServiceConnector>( - &service_proxies_, &service_handlers_, test_instance_group_); + this, &service_proxies_, &service_handlers_, test_instance_group_); } TestConnectorFactory::TestConnectorFactory(
diff --git a/services/service_manager/public/cpp/test/test_connector_factory.h b/services/service_manager/public/cpp/test/test_connector_factory.h index 569d31a2..86fdb775 100644 --- a/services/service_manager/public/cpp/test/test_connector_factory.h +++ b/services/service_manager/public/cpp/test/test_connector_factory.h
@@ -111,6 +111,16 @@ return test_instance_group_; } + // Normally a TestConnectorFactory will assert if asked to route a request to + // an unregistered service. If this is set to |true|, such requests will be + // silently ignored instead. + bool ignore_unknown_service_requests() const { + return ignore_unknown_service_requests_; + } + void set_ignore_unknown_service_requests(bool ignore) { + ignore_unknown_service_requests_ = ignore; + } + // Normally when a service instance registered via either |RegisterInstance()| // or |RegisterServiceHandler()| requests termination from the Service // Manager, TestConnectorFactory immediately severs the service instance's @@ -152,6 +162,7 @@ mojo::AssociatedBindingSet<mojom::ServiceControl, std::string> service_control_bindings_; + bool ignore_unknown_service_requests_ = false; bool ignore_quit_requests_ = false; DISALLOW_COPY_AND_ASSIGN(TestConnectorFactory);
diff --git a/services/service_manager/public/cpp/test/test_service.cc b/services/service_manager/public/cpp/test/test_service.cc new file mode 100644 index 0000000..c68008c7 --- /dev/null +++ b/services/service_manager/public/cpp/test/test_service.cc
@@ -0,0 +1,23 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/service_manager/public/cpp/test/test_service.h" + +#include "services/service_manager/public/mojom/connector.mojom.h" + +namespace service_manager { + +TestService::TestService(mojom::ServiceRequest request) + : binding_(this, std::move(request)) { + // Run until we have a functioning Connector end-to-end, in case e.g. the test + // wants to making blocking calls on interfaces right away. + mojom::ConnectorPtr flushing_connector; + binding_.GetConnector()->BindConnectorRequest( + mojo::MakeRequest(&flushing_connector)); + flushing_connector.FlushForTesting(); +} + +TestService::~TestService() = default; + +} // namespace service_manager
diff --git a/services/service_manager/public/cpp/test/test_service.h b/services/service_manager/public/cpp/test/test_service.h new file mode 100644 index 0000000..4d09fa13 --- /dev/null +++ b/services/service_manager/public/cpp/test/test_service.h
@@ -0,0 +1,60 @@ +// 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_SERVICE_MANAGER_PUBLIC_CPP_TEST_TEST_SERVICE_H_ +#define SERVICES_SERVICE_MANAGER_PUBLIC_CPP_TEST_TEST_SERVICE_H_ + +#include "base/macros.h" +#include "services/service_manager/public/cpp/connector.h" +#include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/cpp/service_binding.h" +#include "services/service_manager/public/mojom/service.mojom.h" + +namespace service_manager { + +// A very simple test helper for unit tests which want to use a real Service +// Manager instance and have each test behave like a unique service instance +// that can connect to any of various services under test. +// +// Typical usage is paired with ServiceManager::RegisterServiceForTesting, for +// example: +// +// class MyTest : public testing::Test { +// public: +// MyTest() +// : test_service_( +// test_service_manager_.RegisterTestInstance("foo_unittests")) {} +// +// service_manager::Connector* connector() { +// return test_service_.connector(); +// } +// +// private: +// base::test::ScopedTaskEnvironment task_environment_; +// service_manager::TestServiceManager test_service_manager_; +// service_manager::TestService test_service_; +// }; +// +// TEST_F(MyTest, ConnectToFoo) { +// foo::mojom::FooPtr foo; +// connector()->BindInterface("foo", mojo::MakeRequest(&foo)); +// foo->DoSomeStuff(); +// // etc... +// } +class TestService : public Service { + public: + explicit TestService(mojom::ServiceRequest request); + ~TestService() override; + + Connector* connector() { return binding_.GetConnector(); } + + private: + ServiceBinding binding_; + + DISALLOW_COPY_AND_ASSIGN(TestService); +}; + +} // namespace service_manager + +#endif // SERVICES_SERVICE_MANAGER_PUBLIC_CPP_TEST_TEST_SERVICE_H_
diff --git a/services/service_manager/public/cpp/test/test_service_manager.cc b/services/service_manager/public/cpp/test/test_service_manager.cc new file mode 100644 index 0000000..11a9bc6 --- /dev/null +++ b/services/service_manager/public/cpp/test/test_service_manager.cc
@@ -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. + +#include "services/service_manager/public/cpp/test/test_service_manager.h" + +#include "services/service_manager/background/background_service_manager.h" +#include "services/service_manager/service_manager.h" + +namespace service_manager { + +TestServiceManager::TestServiceManager() : TestServiceManager(nullptr) {} + +TestServiceManager::TestServiceManager(std::unique_ptr<base::Value> catalog) + : background_service_manager_( + std::make_unique<BackgroundServiceManager>(nullptr, + std::move(catalog))) {} + +TestServiceManager::~TestServiceManager() = default; + +mojom::ServiceRequest TestServiceManager::RegisterTestInstance( + const std::string& service_name) { + mojom::ServicePtr service; + mojom::ServiceRequest request = mojo::MakeRequest(&service); + background_service_manager_->RegisterService( + Identity{service_name, base::Token::CreateRandom(), base::Token{}, + base::Token::CreateRandom()}, + std::move(service), nullptr); + return request; +} + +} // namespace service_manager
diff --git a/services/service_manager/public/cpp/test/test_service_manager.h b/services/service_manager/public/cpp/test/test_service_manager.h new file mode 100644 index 0000000..8caff05 --- /dev/null +++ b/services/service_manager/public/cpp/test/test_service_manager.h
@@ -0,0 +1,54 @@ +// 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_SERVICE_MANAGER_PUBLIC_CPP_TEST_TEST_SERVICE_MANAGER_H_ +#define SERVICES_SERVICE_MANAGER_PUBLIC_CPP_TEST_TEST_SERVICE_MANAGER_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/values.h" +#include "services/service_manager/public/mojom/service.mojom.h" + +namespace service_manager { + +class BackgroundServiceManager; + +// Creates a real ServiceManager instance for use in unit tests which want such +// a thing. Tests should use this class instead of depending on and constructing +// a |service_manager::ServiceManager| instance directly. +// +// NOTE: Using this object in tests requires a task execution environment, for +// example a live |base::test::ScopedTaskEnvironment| object. +class TestServiceManager { + public: + // Creates a TestServiceManager using the default global catalog. + TestServiceManager(); + + // Creates a TestServiceManager using the specific catalog contents in + // |catalog.| + explicit TestServiceManager(std::unique_ptr<base::Value> catalog); + + ~TestServiceManager(); + + // Registers a new service instance with a random Identity including + // |service_name|. Returns a ServiceRequest which the test fixture should + // bind to a ServiceBinding it owns. This allows each test to behave as a + // unique service instance with capabilities tied to |service_name|'s entry + // in the testing catalog. + // + // TODO(https://crbug.com/895616): Support the caller supplying a manifest + // object directly rather than supplying a service name and consulting a + // global catalog. + mojom::ServiceRequest RegisterTestInstance(const std::string& service_name); + + private: + const std::unique_ptr<BackgroundServiceManager> background_service_manager_; + + DISALLOW_COPY_AND_ASSIGN(TestServiceManager); +}; + +} // namespace service_manager + +#endif // SERVICES_SERVICE_MANAGER_PUBLIC_CPP_TEST_TEST_SERVICE_MANAGER_H_
diff --git a/services/service_manager/service_manager.cc b/services/service_manager/service_manager.cc index 8bc456e..237854beb 100644 --- a/services/service_manager/service_manager.cc +++ b/services/service_manager/service_manager.cc
@@ -974,9 +974,6 @@ DISALLOW_COPY_AND_ASSIGN(IdentityToInstanceMap); }; -//////////////////////////////////////////////////////////////////////////////// -// ServiceManager, public: - ServiceManager::ServiceManager(std::unique_ptr<ServiceProcessLauncherFactory> service_process_launcher_factory, std::unique_ptr<base::Value> catalog_contents,
diff --git a/services/viz/public/cpp/compositing/quads_struct_traits.cc b/services/viz/public/cpp/compositing/quads_struct_traits.cc index af3742e9..3c928eab 100644 --- a/services/viz/public/cpp/compositing/quads_struct_traits.cc +++ b/services/viz/public/cpp/compositing/quads_struct_traits.cc
@@ -175,7 +175,8 @@ !data.ReadUvTexCoordRect(&quad->uv_tex_coord_rect) || !data.ReadYaTexSize(&quad->ya_tex_size) || !data.ReadUvTexSize(&quad->uv_tex_size) || - !data.ReadVideoColorSpace(&quad->video_color_space)) { + !data.ReadVideoColorSpace(&quad->video_color_space) || + !data.ReadProtectedVideoType(&quad->protected_video_type)) { return false; } quad->resources.ids[viz::YUVVideoDrawQuad::kYPlaneResourceIdIndex] = @@ -199,7 +200,6 @@ return false; } quad->require_overlay = data.require_overlay(); - quad->is_protected_video = data.is_protected_video(); return true; }
diff --git a/services/viz/public/cpp/compositing/quads_struct_traits.h b/services/viz/public/cpp/compositing/quads_struct_traits.h index 129fcd1c..fe4c601 100644 --- a/services/viz/public/cpp/compositing/quads_struct_traits.h +++ b/services/viz/public/cpp/compositing/quads_struct_traits.h
@@ -31,6 +31,39 @@ viz::QuadList* list); template <> +struct EnumTraits<viz::mojom::ProtectedVideoState, ui::ProtectedVideoType> { + static viz::mojom::ProtectedVideoState ToMojom(ui::ProtectedVideoType input) { + switch (input) { + case ui::ProtectedVideoType::kClear: + return viz::mojom::ProtectedVideoState::kClear; + case ui::ProtectedVideoType::kHardwareProtected: + return viz::mojom::ProtectedVideoState::kHardwareProtected; + case ui::ProtectedVideoType::kSoftwareProtected: + return viz::mojom::ProtectedVideoState::kSoftwareProtected; + } + NOTREACHED(); + return viz::mojom::ProtectedVideoState::kClear; + } + + static bool FromMojom(viz::mojom::ProtectedVideoState input, + ui::ProtectedVideoType* out) { + switch (input) { + case viz::mojom::ProtectedVideoState::kClear: + *out = ui::ProtectedVideoType::kClear; + return true; + case viz::mojom::ProtectedVideoState::kHardwareProtected: + *out = ui::ProtectedVideoType::kHardwareProtected; + return true; + case viz::mojom::ProtectedVideoState::kSoftwareProtected: + *out = ui::ProtectedVideoType::kSoftwareProtected; + return true; + } + NOTREACHED(); + return false; + } +}; + +template <> struct UnionTraits<viz::mojom::DrawQuadStateDataView, viz::DrawQuad> { static viz::mojom::DrawQuadStateDataView::Tag GetTag( const viz::DrawQuad& quad) { @@ -449,12 +482,12 @@ viz::YUVVideoDrawQuad::MaterialCast(&input); return quad->require_overlay; } - static bool is_protected_video(const viz::DrawQuad& input) { + static ui::ProtectedVideoType protected_video_type( + const viz::DrawQuad& input) { const viz::YUVVideoDrawQuad* quad = viz::YUVVideoDrawQuad::MaterialCast(&input); - return quad->is_protected_video; + return quad->protected_video_type; } - static bool Read(viz::mojom::YUVVideoQuadStateDataView data, viz::DrawQuad* out); };
diff --git a/services/viz/public/cpp/compositing/render_pass.typemap b/services/viz/public/cpp/compositing/render_pass.typemap index 125a498..a16f1583 100644 --- a/services/viz/public/cpp/compositing/render_pass.typemap +++ b/services/viz/public/cpp/compositing/render_pass.typemap
@@ -6,6 +6,7 @@ public_headers = [ "//components/viz/common/quads/draw_quad.h", "//components/viz/common/quads/render_pass.h", + "//ui/gl/dc_renderer_layer_params.h", ] traits_headers = [ "//services/viz/public/cpp/compositing/quads_struct_traits.h", @@ -15,4 +16,7 @@ "//services/viz/public/cpp/compositing/quads_struct_traits.cc", "//services/viz/public/cpp/compositing/render_pass_struct_traits.cc", ] -type_mappings = [ "viz.mojom.RenderPass=std::unique_ptr<viz::RenderPass>[move_only,nullable_is_same_type]" ] +type_mappings = [ + "viz.mojom.RenderPass=std::unique_ptr<viz::RenderPass>[move_only,nullable_is_same_type]", + "viz::mojom::ProtectedVideoState=ui::ProtectedVideoType", +]
diff --git a/services/viz/public/cpp/compositing/struct_traits_unittest.cc b/services/viz/public/cpp/compositing/struct_traits_unittest.cc index 0cb36c0..a7fd962 100644 --- a/services/viz/public/cpp/compositing/struct_traits_unittest.cc +++ b/services/viz/public/cpp/compositing/struct_traits_unittest.cc
@@ -1125,7 +1125,8 @@ const float resource_multiplier = 1234.6f; const uint32_t bits_per_channel = 13; const bool require_overlay = true; - const bool is_protected_video = true; + const ui::ProtectedVideoType protected_video_type = + ui::ProtectedVideoType::kSoftwareProtected; SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState(); YUVVideoDrawQuad* quad = @@ -1134,7 +1135,7 @@ uv_tex_coord_rect, ya_tex_size, uv_tex_size, y_plane_resource_id, u_plane_resource_id, v_plane_resource_id, a_plane_resource_id, video_color_space, resource_offset, resource_multiplier, - bits_per_channel, require_overlay, is_protected_video); + bits_per_channel, require_overlay, protected_video_type); std::unique_ptr<RenderPass> output; mojo::test::SerializeAndDeserialize<mojom::RenderPass>(&render_pass, &output); @@ -1159,7 +1160,7 @@ EXPECT_EQ(resource_multiplier, out_quad->resource_multiplier); EXPECT_EQ(bits_per_channel, out_quad->bits_per_channel); EXPECT_EQ(require_overlay, out_quad->require_overlay); - EXPECT_EQ(is_protected_video, out_quad->is_protected_video); + EXPECT_EQ(protected_video_type, out_quad->protected_video_type); } TEST_F(StructTraitsTest, CopyOutputResult_Empty) {
diff --git a/services/viz/public/interfaces/compositing/quads.mojom b/services/viz/public/interfaces/compositing/quads.mojom index 3f12a14..eefd5de 100644 --- a/services/viz/public/interfaces/compositing/quads.mojom +++ b/services/viz/public/interfaces/compositing/quads.mojom
@@ -84,6 +84,12 @@ bool force_anti_aliasing_off; }; +enum ProtectedVideoState { + kClear, + kSoftwareProtected, + kHardwareProtected, +}; + struct YUVVideoQuadState { gfx.mojom.RectF ya_tex_coord_rect; gfx.mojom.RectF uv_tex_coord_rect; @@ -98,7 +104,7 @@ uint32 bits_per_channel; gfx.mojom.ColorSpace video_color_space; bool require_overlay; - bool is_protected_video; + ProtectedVideoState protected_video_type; }; union DrawQuadState {
diff --git a/services/ws/test_ws/test_ws.cc b/services/ws/test_ws/test_ws.cc index 286e589..fa7186b 100644 --- a/services/ws/test_ws/test_ws.cc +++ b/services/ws/test_ws/test_ws.cc
@@ -8,10 +8,8 @@ #include "services/service_manager/public/cpp/service_runner.h" #include "services/ws/test_ws/test_window_service_factory.h" #include "ui/base/ui_base_paths.h" -#include "ui/gfx/gfx_paths.h" MojoResult ServiceMain(MojoHandle service_request_handle) { - gfx::RegisterPathProvider(); ui::RegisterPathProvider(); // |runner| takes ownership of the created test_ws service.
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index 5d93162b..fe2bab0 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h
@@ -130,7 +130,8 @@ // until we update our call-sites (typically these are for API changes). // // Remove these as we update our sites. -// + +#define SK_LEGACY_PLATFORM_MATRIX_PROCS // Workaround for poor anisotropic mipmap quality, // pending Skia ripmap support.
diff --git a/sql/database.cc b/sql/database.cc index 8d3bf081..a88e25a 100644 --- a/sql/database.cc +++ b/sql/database.cc
@@ -1384,13 +1384,11 @@ const char* sql) { auto it = statement_cache_.find(id); if (it != statement_cache_.end()) { - // Statement is in the cache. It should still be active. We're the only - // one invalidating cached statements, and we remove them from the cache + // Statement is in the cache. It should still be valid. We're the only + // entity invalidating cached statements, and we remove them from the cache // when we do that. DCHECK(it->second->is_valid()); - DCHECK_EQ(base::TrimWhitespaceASCII(sql, base::TRIM_ALL), - base::TrimWhitespaceASCII(sqlite3_sql(it->second->stmt()), - base::TRIM_ALL)) + DCHECK_EQ(std::string(sqlite3_sql(it->second->stmt())), std::string(sql)) << "GetCachedStatement used with same ID but different SQL"; // Reset the statement so it can be reused. @@ -1399,8 +1397,11 @@ } scoped_refptr<StatementRef> statement = GetUniqueStatement(sql); - if (statement->is_valid()) + if (statement->is_valid()) { statement_cache_[id] = statement; // Only cache valid statements. + DCHECK_EQ(std::string(sqlite3_sql(statement->stmt())), std::string(sql)) + << "Input SQL does not match SQLite's normalized version"; + } return statement; } @@ -1611,9 +1612,17 @@ // Custom memory-mapping VFS which reads pages using regular I/O on first hit. sqlite3_vfs* vfs = VFSWrapper(); const char* vfs_name = (vfs ? vfs->zName : nullptr); - int err = - sqlite3_open_v2(file_name.c_str(), &db_, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, vfs_name); + + // The flags are documented at https://www.sqlite.org/c3ref/open.html. + // + // Chrome uses SQLITE_OPEN_PRIVATECACHE because SQLite is used by many + // disparate features with their own databases, and having separate page + // caches makes it easier to reason about each feature's performance in + // isolation. + int err = sqlite3_open_v2( + file_name.c_str(), &db_, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_PRIVATECACHE, + vfs_name); if (err != SQLITE_OK) { // Extended error codes cannot be enabled until a handle is // available, fetch manually.
diff --git a/sql/database.h b/sql/database.h index 7bee2567..8dc0dc4 100644 --- a/sql/database.h +++ b/sql/database.h
@@ -376,19 +376,23 @@ // keeping commonly-used ones around for future use is important for // performance. // + // The SQL_FROM_HERE macro is the recommended way of generating a StatementID. + // Code that generates custom IDs must ensure that a StatementID is never used + // for different SQL statements. Failing to meet this requirement results in + // incorrect behavior, and should be caught by a DCHECK. + // + // The SQL statement passed in |sql| must match the SQL statement reported + // back by SQLite. Mismatches are caught by a DCHECK, so any code that has + // automated test coverage or that was manually tested on a DCHECK build will + // not exhibit this problem. Mismatches generally imply that the statement + // passed in has extra whitespace or comments surrounding it, which waste + // storage and CPU cycles. + // // If the |sql| has an error, an invalid, inert StatementRef is returned (and // the code will crash in debug). The caller must deal with this eventuality, // either by checking validity of the |sql| before calling, by correctly // handling the return of an inert statement, or both. // - // The StatementID and the SQL must always correspond to one-another. The - // ID is the lookup into the cache, so crazy things will happen if you use - // different SQL with the same ID. - // - // You will normally use the SQL_FROM_HERE macro to generate a statement - // ID associated with the current line of code. This gives uniqueness without - // you having to manage unique names. See StatementID above for more. - // // Example: // sql::Statement stmt(database_.GetCachedStatement( // SQL_FROM_HERE, "SELECT * FROM foo"));
diff --git a/sql/database_unittest.cc b/sql/database_unittest.cc index 5bb4c047..38cd6c01 100644 --- a/sql/database_unittest.cc +++ b/sql/database_unittest.cc
@@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/strings/string_number_conversions.h" +#include "base/test/gtest_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_tick_clock.h" @@ -230,8 +231,7 @@ TEST_F(SQLDatabaseTest, CachedStatement) { sql::StatementID id1 = SQL_FROM_HERE; sql::StatementID id2 = SQL_FROM_HERE; - // Ensure leading and trailing whitespace doesn't break anything. - static const char kId1Sql[] = "\n SELECT a FROM foo \n"; + static const char kId1Sql[] = "SELECT a FROM foo"; static const char kId2Sql[] = "SELECT b FROM foo"; ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); @@ -281,6 +281,11 @@ ASSERT_TRUE(from_id2.Step()) << "cached statement was not reset"; EXPECT_EQ(13, from_id2.ColumnInt(0)); } + + EXPECT_DCHECK_DEATH(db().GetCachedStatement(id1, kId2Sql)) + << "Using a different SQL with the same statement ID should DCHECK"; + EXPECT_DCHECK_DEATH(db().GetCachedStatement(id2, kId1Sql)) + << "Using a different SQL with the same statement ID should DCHECK"; } TEST_F(SQLDatabaseTest, IsSQLValidTest) {
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index f14f1f2..31cd48e 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -4537,6 +4537,13 @@ "os": "Mac-10.12.6" } ], + "optional_dimensions": { + "1200": [ + { + "os": "Mac-10.13" + } + ] + }, "shards": 12 } },
diff --git a/testing/buildbot/filters/chromeos.single_process_mash.ash_unittests.filter b/testing/buildbot/filters/chromeos.single_process_mash.ash_unittests.filter index 64dfa2c..106e4dc 100644 --- a/testing/buildbot/filters/chromeos.single_process_mash.ash_unittests.filter +++ b/testing/buildbot/filters/chromeos.single_process_mash.ash_unittests.filter
@@ -25,6 +25,7 @@ -MagnificationControllerTest.TextfieldFocusedWithKeyboard -OverviewVirtualKeyboardTest.ToggleOverviewModeHidesVirtualKeyboard -OverviewVirtualKeyboardTest.ToggleOverviewModeDoesNotHideLockedVirtualKeyboard +-PopulatedAppListTest.TappingAppsGridClosesVirtualKeyboard -ShelfLayoutManagerKeyboardTest.ShelfIgnoreWorkAreaChangeInNonStickyMode -ShelfLayoutManagerKeyboardTest.ShelfNotMoveOnKeyboardOpen -ShelfLayoutManagerKeyboardTest.ShelfShouldChangeWorkAreaInStickyMode
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter index ac71b8f..b80bd908 100644 --- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter +++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -46,6 +46,9 @@ -ContextMenuBrowserTest.DataSaverOpenOrigImageInNewTab -DataReductionProxyBrowsertest.UMAMetricsRecorded +# https://crbug.com/899268 +-PolicyTestSafeSearchRedirect.ForceGoogleSafeSearch + # 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/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter b/testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter index 2040b0dd..2754663 100644 --- a/testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter +++ b/testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter
@@ -115,13 +115,9 @@ -org.chromium.android_webview.test.ClientOnReceivedError2Test.testIframeSubresource -org.chromium.android_webview.test.ClientOnReceivedError2Test.testImageSubresource -org.chromium.android_webview.test.ClientOnReceivedError2Test.testMainFrame --org.chromium.android_webview.test.ClientOnReceivedError2Test.testOnCacheMiss -org.chromium.android_webview.test.ClientOnReceivedError2Test.testUserGesture -org.chromium.android_webview.test.ClientOnReceivedError2Test.testUserGestureForIframeSubresource -# https://crbug.com/893574 --org.chromium.android_webview.test.ClientOnReceivedErrorTest.testCacheMiss - # https://crbug.com/893575 -org.chromium.android_webview.test.CookieManagerStartupTest.testShouldInterceptRequestDeadlock -org.chromium.android_webview.test.CookieManagerStartupTest.testStartup @@ -144,6 +140,7 @@ -org.chromium.android_webview.test.LoadDataWithBaseUrlTest.testLoadDataWithBaseUrlAccessingFile -org.chromium.android_webview.test.LoadDataWithBaseUrlTest.testSetCookieInIframe -org.chromium.android_webview.test.LoadDataWithBaseUrlTest.testThirdPartyCookieInIframe +-org.chromium.android_webview.test.LoadDataWithBaseUrlTest.testXhrForHttpSchemeUrl # https://crbug.com/893581 -org.chromium.android_webview.test.LoadUrlTest.testLoadUrlWithExtraHeaders
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index d7cb82e..7875773 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -1261,6 +1261,10 @@ "label": "//ui/native_theme:native_theme_unittests", "type": "windowed_test_launcher", }, + "shipped_binaries": { + "label": "//:shipped_binaries", + "type": "additional_compile_target", + }, "ui_android_unittests": { "label": "//ui/android:ui_android_unittests", "type": "console_test_launcher",
diff --git a/testing/buildbot/manage.py b/testing/buildbot/manage.py index 019f4a1..a0a7e0b 100755 --- a/testing/buildbot/manage.py +++ b/testing/buildbot/manage.py
@@ -131,11 +131,12 @@ 'net_junit_tests', 'net_junit_tests', 'service_junit_tests', + 'shipped_binaries', 'system_webview_apk', 'ui_junit_tests', - 'vrcore_fps_test', 'vr_common_perftests', 'vr_perf_tests', + 'vrcore_fps_test', 'webapk_client_junit_tests', 'webapk_shell_apk_h2o_junit_tests', 'webapk_shell_apk_junit_tests',
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 73d293b..876ef1d 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1442,7 +1442,6 @@ }, }, 'Mac10.13 Tests': { - # TODO(crbug.com/853356): Switch this to 10.13. # TODO(kbr): if the Swarming dimensions were explicitly specified for # all jobs then this wouldn't be needed. 'swarming': { @@ -1453,6 +1452,16 @@ }, ], 'shards': 12, + # TODO(crbug.com/853356): Switch this fully to 10.13. + # Starting with a 20 minute expiration for now, we will reduce this + # later. + 'optional_dimensions': { + 1200: [ + { + 'os': 'Mac-10.13', + } + ], + }, }, }, 'Mac10.13 Tests (dbg)': {
diff --git a/testing/scripts/check_network_annotations.py b/testing/scripts/check_network_annotations.py index f778080..3d1e8153 100755 --- a/testing/scripts/check_network_annotations.py +++ b/testing/scripts/check_network_annotations.py
@@ -35,7 +35,7 @@ def main_compile_targets(args): - json.dump(['gn_all'], args.output) + json.dump(['shipped_binaries'], args.output) if __name__ == '__main__':
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 4ccb100..7fa94d1 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1286,25 +1286,6 @@ ] } ], - "CommittedSSLInterstitialsEnabled": [ - { - "platforms": [ - "android", - "chromeos", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "CommittedSSLInterstitialsEnabled", - "enable_features": [ - "SSLCommittedInterstitials" - ] - } - ] - } - ], "CompositorImageAnimation": [ { "platforms": [ @@ -2548,21 +2529,6 @@ ] } ], - "JavaScriptTabModalDialogs": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "TabModalJsDialog" - ] - } - ] - } - ], "LegacySymantecPKI": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees index 6c220dc..7bd6b7bc 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees
@@ -117,6 +117,9 @@ crbug.com/857501 compositing/gestures/gesture-tapHighlight-with-filter.html [ Pass ] crbug.com/400829 media/video-object-fit.html [ Pass ] crbug.com/400829 compositing/composited-canvas-with-overflowing-object-fit.html [ Pass ] +crbug.com/907175 external/wpt/css/css-masking/clip/clip-filter-order.html [ Pass ] +crbug.com/907175 external/wpt/css/css-masking/clip-path/clip-path-filter-order.html [ Pass ] +crbug.com/907175 external/wpt/svg/rendering/order/clip-path-filter-order.svg [ Pass ] # These tests are no longer applicable with layer list mode. # Move to NeverFixTests later.
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService index a38dbb6..b09a222 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -11,7 +11,7 @@ # Only passes with Network Servce enabled (unfortunately these expectations still # allow Failure or Timeout from the top-level expectations though). crbug.com/800898 external/wpt/FileAPI/url/url-in-tags-revoke.window.html [ Pass ] -crbug.com/800898 external/wpt/workers/worker-from-blob-url.window.html [ Pass ] +crbug.com/800898 external/wpt/workers/shared-worker-from-blob-url.window.html [ Pass ] crbug.com/595993 external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Pass ] crbug.com/862886 external/wpt/service-workers/service-worker/navigation-preload/broken-chunked-encoding.https.html [ Pass ] crbug.com/896924 http/tests/inspector-protocol/network/interception-multiclient.js [ Pass ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 index fc99895..199efae 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -582,7 +582,6 @@ crbug.com/702350 virtual/threaded/transitions/opacity-transform-transitions-inside-iframe.html [ Timeout ] crbug.com/702353 virtual/threaded/transitions/transition-end-event-destroy-iframe.html [ Timeout ] crbug.com/702365 virtual/threaded/animations/composited-filter-webkit-filter.html [ Failure ] -crbug.com/702370 virtual/threaded/animations/compositor-independent-transform-cancel.html [ Failure ] # Eight of the frames in the test below paint no content. In SPv2 we will never # composite animations that paint nothing. For now we mark this test as failing, @@ -825,6 +824,9 @@ Bug(none) virtual/threaded/external/wpt/css/css-scroll-snap/snap-at-user-scroll-end-manual.html [ Timeout ] Bug(none) synthetic_gestures/animated-wheel-tiny-delta.html [ Failure ] +# Duplicated display item id of background of scrollable table cell. +Bug(none) fast/table/overflowHidden.html [ Crash ] + # These tests have failures that were introduced between enabling BGPT for the # first time and later disabling it. These are not real failures and can be # rebaselined.
diff --git a/third_party/WebKit/LayoutTests/LeakExpectations b/third_party/WebKit/LayoutTests/LeakExpectations index 00c8a1527..db13c500 100644 --- a/third_party/WebKit/LayoutTests/LeakExpectations +++ b/third_party/WebKit/LayoutTests/LeakExpectations
@@ -62,34 +62,6 @@ crbug.com/809609 [ Linux ] editing/inserting/insert_div_with_style.html [ Pass Leak ] # ----------------------------------------------------------------- -# Not revert suspected CL at lukasza@ request. Suspecting that this is -# an OOPIF-related issue with leak detection in the test harness, rather -# than a real leak. -# -# Leaks that repro only with site-per-process: -crbug.com/906809 external/wpt/html/browsers/the-window-object/security-window/window-security.https.html [ Pass Leak ] -crbug.com/906809 http/tests/feature-policy/fullscreen-allowed-by-container-policy-relocate.html [ Pass Leak ] -crbug.com/906809 http/tests/feature-policy/fullscreen-allowed-by-container-policy.html [ Pass Leak ] -crbug.com/906809 http/tests/feature-policy/fullscreen-disabled.php [ Pass Leak ] -crbug.com/906809 http/tests/feature-policy/fullscreen-enabledforall.php [ Pass Leak ] -crbug.com/906809 http/tests/feature-policy/fullscreen-enabledforself.php [ Pass Leak ] -crbug.com/906809 http/tests/html/validation-bubble-oopif.html [ Pass Leak ] -crbug.com/906809 http/tests/media/autoplay/webaudio-autoplay-iframe-with-gesture.html [ Pass Leak ] -crbug.com/906809 http/tests/security/referrer-policy-redirect-link.html [ Pass Leak ] -crbug.com/906809 http/tests/security/vibration/vibrate-in-cross-origin-iframe-with-user-gesture-allowed.html [ Pass Leak ] -crbug.com/906809 http/tests/security/xss-DENIED-window-open-javascript-url-with-spaces.html [ Pass Leak ] -crbug.com/906809 http/tests/security/xss-DENIED-window-open-javascript-url.html [ Pass Leak ] -crbug.com/906809 virtual/outofblink-cors-ns/http/tests/security/referrer-policy-redirect-link.html [ Pass Leak ] -crbug.com/906809 virtual/outofblink-cors-ns/http/tests/security/vibration/vibrate-in-cross-origin-iframe-with-user-gesture-allowed.html [ Pass Leak ] -crbug.com/906809 virtual/outofblink-cors-ns/http/tests/security/xss-DENIED-window-open-javascript-url-with-spaces.html [ Pass Leak ] -crbug.com/906809 virtual/outofblink-cors-ns/http/tests/security/xss-DENIED-window-open-javascript-url.html [ Pass Leak ] -crbug.com/906809 virtual/outofblink-cors/http/tests/security/referrer-policy-redirect-link.html [ Pass Leak ] -crbug.com/906809 virtual/outofblink-cors/http/tests/security/vibration/vibrate-in-cross-origin-iframe-with-user-gesture-allowed.html [ Pass Leak ] -crbug.com/906809 virtual/outofblink-cors/http/tests/security/xss-DENIED-window-open-javascript-url-with-spaces.html [ Pass Leak ] -crbug.com/906809 virtual/outofblink-cors/http/tests/security/xss-DENIED-window-open-javascript-url.html [ Pass Leak ] -crbug.com/906809 virtual/user-activation-v2/http/tests/media/autoplay/webaudio-autoplay-iframe-with-gesture.html [ Pass Leak ] - -# ----------------------------------------------------------------- # Sheriff 2018-04-23 # ----------------------------------------------------------------- crbug.com/836278 [ Linux ] external/wpt/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.html [ Pass Leak ]
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests index 785bb9c..441109a 100644 --- a/third_party/WebKit/LayoutTests/SlowTests +++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -806,7 +806,6 @@ crbug.com/874695 external/wpt/workers/semantics/multiple-workers/004.html [ Slow ] crbug.com/874695 external/wpt/workers/semantics/multiple-workers/007.html [ Slow ] crbug.com/874695 external/wpt/workers/Worker_cross_origin_security_err.htm [ Slow ] -crbug.com/874695 external/wpt/workers/worker-from-blob-url.window.html [ Slow ] crbug.com/874695 external/wpt/worklets/animation-worklet-referrer.https.html [ Slow ] crbug.com/874695 external/wpt/worklets/layout-worklet-referrer.https.html [ Slow ] crbug.com/874695 external/wpt/worklets/paint-worklet-referrer.https.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 963dd4ac..ed9294a 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -161,6 +161,7 @@ crbug.com/872952 http/tests/media/autoplay/document-user-activation-feature-policy-iframe-no-gesture.html [ Failure Pass Timeout ] crbug.com/895001 external/wpt/html/user-activation/message-event-activation-api-iframe-cross-origin.sub.tentative.html [ Timeout Pass ] crbug.com/901502 http/tests/devtools/oopif/oopif-storage.js [ Pass Failure ] +crbug.com/906879 http/tests/inspector-protocol/network/navigation-blocking-xorigin-iframe.js [ Pass Failure ] # ====== Site Isolation failures until here ====== # ====== Oilpan-only failures from here ====== @@ -2808,8 +2809,10 @@ crbug.com/800898 external/wpt/FileAPI/url/url-with-fetch.any.worker.html [ Pass Failure ] crbug.com/800898 external/wpt/FileAPI/url/url-with-xhr.any.worker.html [ Pass Failure ] crbug.com/800898 external/wpt/FileAPI/url/url-in-tags-revoke.window.html [ Timeout ] -crbug.com/800898 external/wpt/workers/worker-from-blob-url.window.html [ Timeout ] -crbug.com/800898 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/worker-from-blob-url.window.html [ Timeout ] + +# These will be fixed when NetworkService gets enabled. +crbug.com/800898 external/wpt/workers/shared-worker-from-blob-url.window.html [ Skip ] +crbug.com/800898 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/shared-worker-from-blob-url.window.html [ Skip ] crbug.com/849737 virtual/mojo-blob-urls/external/wpt/FileAPI/url/sandboxed-iframe.html [ Pass Timeout ] crbug.com/849737 virtual/mojo-blob-urls/external/wpt/FileAPI/url/url-format.any.html [ Pass Timeout ] @@ -3013,76 +3016,29 @@ crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/viewportanchor_y_50_percent.html [ Failure ] crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/regions/width_50_percent.html [ Failure ] crbug.com/626703 external/wpt/css/css-backgrounds/border-image-width-008.html [ Failure ] +crbug.com/626703 virtual/outofblink-cors-ns/external/wpt/referrer-policy/css-integration/svg/internal-stylesheet.html [ Timeout ] crbug.com/367760 external/wpt/svg/pservers/reftests/meshgradient-basic-004.svg [ Failure ] crbug.com/367760 external/wpt/svg/pservers/reftests/meshgradient-basic-001.svg [ Failure ] - -crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/external-stylesheet.html [ Timeout ] +crbug.com/626703 virtual/outofblink-cors-ns/external/wpt/referrer-policy/css-integration/svg/presentation-attribute.html [ Timeout ] +crbug.com/626703 virtual/outofblink-cors-ns/external/wpt/referrer-policy/css-integration/svg/external-stylesheet.html [ Timeout ] +crbug.com/626703 virtual/outofblink-cors/external/wpt/referrer-policy/css-integration/svg/inline-style.html [ Timeout ] +crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/presentation-attribute.html [ Timeout ] crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/inline-style.html [ Timeout ] crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/internal-stylesheet.html [ Timeout ] -crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/presentation-attribute.html [ Timeout ] -crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/processing-instruction.html [ Timeout ] -crbug.com/626703 virtual/outofblink-cors/external/wpt/referrer-policy/css-integration/svg/external-stylesheet.html [ Timeout ] -crbug.com/626703 virtual/outofblink-cors/external/wpt/referrer-policy/css-integration/svg/inline-style.html [ Timeout ] -crbug.com/626703 virtual/outofblink-cors/external/wpt/referrer-policy/css-integration/svg/internal-stylesheet.html [ Timeout ] -crbug.com/626703 virtual/outofblink-cors/external/wpt/referrer-policy/css-integration/svg/presentation-attribute.html [ Timeout ] crbug.com/626703 virtual/outofblink-cors/external/wpt/referrer-policy/css-integration/svg/processing-instruction.html [ Timeout ] -crbug.com/626703 virtual/outofblink-cors-ns/external/wpt/referrer-policy/css-integration/svg/external-stylesheet.html [ Timeout ] -crbug.com/626703 virtual/outofblink-cors-ns/external/wpt/referrer-policy/css-integration/svg/inline-style.html [ Timeout ] -crbug.com/626703 virtual/outofblink-cors-ns/external/wpt/referrer-policy/css-integration/svg/internal-stylesheet.html [ Timeout ] -crbug.com/626703 virtual/outofblink-cors-ns/external/wpt/referrer-policy/css-integration/svg/presentation-attribute.html [ Timeout ] -crbug.com/626703 virtual/outofblink-cors-ns/external/wpt/referrer-policy/css-integration/svg/processing-instruction.html [ Timeout ] -crbug.com/626703 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/css-integration/svg/external-stylesheet.html [ Timeout ] -crbug.com/626703 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/css-integration/svg/inline-style.html [ Timeout ] -crbug.com/626703 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/css-integration/svg/internal-stylesheet.html [ Timeout ] -crbug.com/626703 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/css-integration/svg/presentation-attribute.html [ Timeout ] -crbug.com/626703 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/css-integration/svg/processing-instruction.html [ Timeout ] - -# referrer-policy tests are failing in off-main-thread-worker-script-fetch -# because referrer policy is not correctly set and -# referrer URL is set to worker request URL (which should be Document URL). -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-http/worker-request/keep-origin-redirect/generic.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-http/worker-request/no-redirect/generic.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/worker-request/keep-origin-redirect/generic.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/worker-request/no-redirect/generic.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/worker-request/keep-origin-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/worker-request/no-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/worker-request/keep-origin-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/worker-request/no-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/origin/http-rp/same-origin/http-http/worker-request/keep-origin-redirect/generic.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/origin/http-rp/same-origin/http-http/worker-request/no-redirect/generic.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-http/worker-request/keep-origin-redirect/generic.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-http/worker-request/no-redirect/generic.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/worker-request/keep-origin-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/worker-request/no-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/worker-request/keep-origin-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/worker-request/no-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/same-origin/http-rp/same-origin/http-http/worker-request/keep-origin-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/same-origin/http-rp/same-origin/http-http/worker-request/no-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/same-origin/meta-referrer/same-origin/http-http/worker-request/keep-origin-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/same-origin/meta-referrer/same-origin/http-http/worker-request/no-redirect/same-origin-insecure.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-http/worker-request/keep-origin-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-http/worker-request/no-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-http/worker-request/keep-origin-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-http/worker-request/no-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/worker-request/keep-origin-redirect/same-insecure.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/worker-request/no-redirect/same-insecure.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/worker-request/keep-origin-redirect/same-insecure.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/worker-request/no-redirect/same-insecure.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-http/worker-request/keep-origin-redirect/generic.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-http/worker-request/no-redirect/generic.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/worker-request/keep-origin-redirect/generic.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/worker-request/no-redirect/generic.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/worker-request/keep-origin-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/worker-request/no-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/worker-request/keep-origin-redirect/insecure-protocol.http.html [ Failure ] -crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/worker-request/no-redirect/insecure-protocol.http.html [ Failure ] - +crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/external-stylesheet.html [ Timeout ] crbug.com/367760 external/wpt/svg/pservers/reftests/meshgradient-complex-001.svg [ Failure ] +crbug.com/626703 virtual/outofblink-cors-ns/external/wpt/referrer-policy/css-integration/svg/inline-style.html [ Timeout ] +crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/processing-instruction.html [ Timeout ] +crbug.com/626703 virtual/outofblink-cors/external/wpt/referrer-policy/css-integration/svg/presentation-attribute.html [ Timeout ] crbug.com/367760 external/wpt/svg/pservers/reftests/meshgradient-bicubic-001.svg [ Failure ] crbug.com/626703 external/wpt/x-frame-options/multiple.sub.html [ Timeout ] crbug.com/367760 external/wpt/svg/pservers/reftests/meshgradient-basic-005.svg [ Failure ] crbug.com/367760 external/wpt/svg/pservers/reftests/meshgradient-basic-002.svg [ Failure ] +crbug.com/626703 virtual/outofblink-cors-ns/external/wpt/referrer-policy/css-integration/svg/processing-instruction.html [ Timeout ] crbug.com/367760 external/wpt/svg/pservers/reftests/meshgradient-basic-003.svg [ Failure ] +crbug.com/626703 virtual/outofblink-cors/external/wpt/referrer-policy/css-integration/svg/internal-stylesheet.html [ Timeout ] +crbug.com/626703 virtual/outofblink-cors/external/wpt/referrer-policy/css-integration/svg/external-stylesheet.html [ Timeout ] crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins.html [ Failure ] crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-rendering.html [ Failure ] crbug.com/626703 [ Mac ] external/wpt/css/css-text/hyphens/hyphens-auto-001.html [ Failure ] @@ -3830,8 +3786,6 @@ crbug.com/888470 virtual/outofblink-cors/external/wpt/referrer-policy/css-integration/child-css/processing-instruction.html [ Failure ] crbug.com/888470 virtual/outofblink-cors-ns/external/wpt/referrer-policy/css-integration/child-css/internal-import-stylesheet.html [ Failure ] crbug.com/888470 virtual/outofblink-cors-ns/external/wpt/referrer-policy/css-integration/child-css/processing-instruction.html [ Failure ] -crbug.com/888470 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/css-integration/child-css/internal-import-stylesheet.html [ Failure ] -crbug.com/888470 virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/css-integration/child-css/processing-instruction.html [ Failure ] # This test times out on debug builds, see https://crbug.com/755810 crbug.com/626703 [ Debug ] external/wpt/html/semantics/tabular-data/processing-model-1/span-limits.html [ Skip ] @@ -3908,6 +3862,11 @@ # This fails because off-the-main-thread script loading goes through different # loading path. Although we could remove this test. disable it for now. crbug.com/835717 virtual/off-main-thread-worker-script-fetch/fast/workers/chromium/worker-crash-with-invalid-location.html [ Skip ] +# Looks like calling |URL.revokeObjectURL(blob_url)| immediately after +# |new Worker(blob_url)| fails worker start because off-the-main-thread worker +# script loading changes the order of url revocation and script fetch. +# See also crbug.com/800898. +crbug.com/835717 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/dedicated-worker-from-blob-url.window.html [ Timeout ] # This fails because AllowedByNoSniff::MimeTypeAsScript() blocks the nested worker's # worker script, because the script url has a .html file extension. @@ -4114,6 +4073,7 @@ crbug.com/747751 [ Win ] http/tests/devtools/application-panel/resources-panel-resource-preview.js [ Failure Pass ] crbug.com/689781 external/wpt/media-source/mediasource-duration.html [ Failure Pass ] +crbug.com/689781 [ Win ] http/tests/media/media-source/mediasource-duration.html [ Failure Pass ] crbug.com/681468 fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom125.html [ Failure Pass ] crbug.com/681468 fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom200.html [ Failure Pass ] @@ -4139,6 +4099,11 @@ # changed with BlinkGenPropertyTrees. Until that launches, this test will fail. crbug.com/857501 compositing/gestures/gesture-tapHighlight-with-filter.html [ Failure ] +# Clip and Clip-path order with filtering is currently incorrect. This is being fixed with BlinkGenPropertyTrees. +crbug.com/907175 external/wpt/css/css-masking/clip/clip-filter-order.html [ Failure ] +crbug.com/907175 external/wpt/css/css-masking/clip-path/clip-path-filter-order.html [ Failure ] +crbug.com/907175 external/wpt/svg/rendering/order/clip-path-filter-order.svg [ Failure ] + crbug.com/716320 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.html [ Failure Timeout ] crbug.com/716320 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success.html [ Failure Timeout ] crbug.com/716320 [ Android ] external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-messagechannel-success.html [ Failure Timeout ] @@ -5394,3 +5359,8 @@ #Sheriff 2018-11-19 crbug.com/906591 printing/single-line-must-not-be-split-into-two-pages.html [ Failure ] crbug.com/906591 virtual/threaded/printing/single-line-must-not-be-split-into-two-pages.html [ Failure ] + +# Flaky crash due to "bad mojo message". +crbug.com/906952 editing/pasteboard/file-drag-to-editable.html [ Pass Crash ] +crbug.com/906952 fast/events/before-unload-return-value-from-listener.html [ Pass Crash ] +
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites index 75c4754..776c096 100644 --- a/third_party/WebKit/LayoutTests/VirtualTestSuites +++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -696,11 +696,6 @@ }, { "prefix": "off-main-thread-worker-script-fetch", - "base": "external/wpt/referrer-policy", - "args": ["--enable-blink-features=OffMainThreadWorkerScriptFetch"] - }, - { - "prefix": "off-main-thread-worker-script-fetch", "base": "fast/workers", "args": ["--enable-blink-features=OffMainThreadWorkerScriptFetch"] }, @@ -929,6 +924,11 @@ }, { "prefix": "not-site-per-process", + "base": "http/tests/inspector-protocol/network/navigation-blocking-xorigin-iframe.js", + "args": ["--disable-site-isolation-trials"] + }, + { + "prefix": "not-site-per-process", "base": "http/tests/inspector-protocol/request-mixed-content-status-blockable.js", "args": ["--disable-site-isolation-trials"] }, @@ -1026,5 +1026,10 @@ "prefix": "not-site-per-process", "base": "http/tests/xmlhttprequest/origin-whitelisting-ip-addresses.html", "args": ["--disable-site-isolation-trials"] + }, + { + "prefix": "transferable-streams", + "base": "http/tests/streams/transferable", + "args": ["--enable-blink-features=TransferableStreams"] } ]
diff --git a/third_party/WebKit/LayoutTests/custom-elements/tentative/HTMLElement-attachInternals.html b/third_party/WebKit/LayoutTests/custom-elements/tentative/HTMLElement-attachInternals.html index 3721dc9..d686117 100644 --- a/third_party/WebKit/LayoutTests/custom-elements/tentative/HTMLElement-attachInternals.html +++ b/third_party/WebKit/LayoutTests/custom-elements/tentative/HTMLElement-attachInternals.html
@@ -34,6 +34,11 @@ const builtin = document.createElement('div'); assert_throws('InvalidStateError', () => { builtin.attachInternals() }); + const doc = document.implementation.createDocument('foo', null); + const span = doc.appendChild(doc.createElementNS('http://www.w3.org/1999/xhtml', 'html:span')); + assert_true(span instanceof HTMLElement); + assert_throws('InvalidStateError', () => { span.attachInternals(); }); + const undefinedCustom = document.createElement('my-element'); assert_throws('InvalidStateError', () => { undefinedCustom.attachInternals() }); }, 'If a custom element definition for the local name of the element doesn\'t' +
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json index e806dae..98ed10da 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json
@@ -173124,6 +173124,16 @@ {} ] ], + "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html.headers": [ + [ + {} + ] + ], + "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html.headers": [ + [ + {} + ] + ], "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html.headers": [ [ {} @@ -173454,6 +173464,16 @@ {} ] ], + "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html.headers": [ + [ + {} + ] + ], + "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html.headers": [ + [ + {} + ] + ], "referrer-policy/no-referrer/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html.headers": [ [ {} @@ -173784,6 +173804,16 @@ {} ] ], + "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html.headers": [ + [ + {} + ] + ], + "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html.headers": [ + [ + {} + ] + ], "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html.headers": [ [ {} @@ -174219,6 +174249,16 @@ {} ] ], + "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html.headers": [ + [ + {} + ] + ], + "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html.headers": [ + [ + {} + ] + ], "referrer-policy/origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html.headers": [ [ {} @@ -174549,6 +174589,16 @@ {} ] ], + "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html.headers": [ + [ + {} + ] + ], + "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html.headers": [ + [ + {} + ] + ], "referrer-policy/same-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html.headers": [ [ {} @@ -174834,6 +174884,16 @@ {} ] ], + "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html.headers": [ + [ + {} + ] + ], + "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html.headers": [ + [ + {} + ] + ], "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-insecure.http.html.headers": [ [ {} @@ -175164,6 +175224,16 @@ {} ] ], + "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html.headers": [ + [ + {} + ] + ], + "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html.headers": [ + [ + {} + ] + ], "referrer-policy/strict-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html.headers": [ [ {} @@ -175494,6 +175564,16 @@ {} ] ], + "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html.headers": [ + [ + {} + ] + ], + "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html.headers": [ + [ + {} + ] + ], "referrer-policy/unsafe-url/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html.headers": [ [ {} @@ -187194,6 +187274,11 @@ {} ] ], + "xhr/formdata-expected.txt": [ + [ + {} + ] + ], "xhr/getallresponseheaders-expected.txt": [ [ {} @@ -234185,6 +234270,12 @@ {} ] ], + "html/semantics/embedded-content/the-iframe-element/iframe_remove_src.html": [ + [ + "/html/semantics/embedded-content/the-iframe-element/iframe_remove_src.html", + {} + ] + ], "html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_script.html": [ [ "/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_script.html", @@ -257137,6 +257228,18 @@ {} ] ], + "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ + [ + "/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html", + {} + ] + ], + "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ + [ + "/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html", + {} + ] + ], "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ [ "/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html", @@ -257533,6 +257636,18 @@ {} ] ], + "referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ + [ + "/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html", + {} + ] + ], + "referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ + [ + "/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html", + {} + ] + ], "referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ [ "/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html", @@ -258169,6 +258284,18 @@ {} ] ], + "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ + [ + "/referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html", + {} + ] + ], + "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ + [ + "/referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html", + {} + ] + ], "referrer-policy/no-referrer/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ [ "/referrer-policy/no-referrer/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html", @@ -258565,6 +258692,18 @@ {} ] ], + "referrer-policy/no-referrer/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ + [ + "/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html", + {} + ] + ], + "referrer-policy/no-referrer/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ + [ + "/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html", + {} + ] + ], "referrer-policy/no-referrer/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ [ "/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html", @@ -259279,6 +259418,18 @@ {} ] ], + "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ + [ + "/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html", + {} + ] + ], + "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ + [ + "/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html", + {} + ] + ], "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ [ "/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html", @@ -259801,6 +259952,18 @@ {} ] ], + "referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ + [ + "/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html", + {} + ] + ], + "referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ + [ + "/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html", + {} + ] + ], "referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ [ "/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html", @@ -260563,6 +260726,18 @@ {} ] ], + "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ + [ + "/referrer-policy/origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html", + {} + ] + ], + "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ + [ + "/referrer-policy/origin/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html", + {} + ] + ], "referrer-policy/origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ [ "/referrer-policy/origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html", @@ -260959,6 +261134,18 @@ {} ] ], + "referrer-policy/origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ + [ + "/referrer-policy/origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html", + {} + ] + ], + "referrer-policy/origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ + [ + "/referrer-policy/origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html", + {} + ] + ], "referrer-policy/origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ [ "/referrer-policy/origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html", @@ -261553,6 +261740,18 @@ {} ] ], + "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ + [ + "/referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html", + {} + ] + ], + "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ + [ + "/referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html", + {} + ] + ], "referrer-policy/same-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ [ "/referrer-policy/same-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html", @@ -261883,6 +262082,18 @@ {} ] ], + "referrer-policy/same-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ + [ + "/referrer-policy/same-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html", + {} + ] + ], + "referrer-policy/same-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ + [ + "/referrer-policy/same-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html", + {} + ] + ], "referrer-policy/same-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ [ "/referrer-policy/same-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html", @@ -262453,6 +262664,18 @@ {} ] ], + "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html": [ + [ + "/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html", + {} + ] + ], + "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html": [ + [ + "/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html", + {} + ] + ], "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-insecure.http.html": [ [ "/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-insecure.http.html", @@ -262849,6 +263072,18 @@ {} ] ], + "referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html": [ + [ + "/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html", + {} + ] + ], + "referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html": [ + [ + "/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html", + {} + ] + ], "referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-insecure.http.html": [ [ "/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-insecure.http.html", @@ -263485,6 +263720,18 @@ {} ] ], + "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ + [ + "/referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html", + {} + ] + ], + "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ + [ + "/referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html", + {} + ] + ], "referrer-policy/strict-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ [ "/referrer-policy/strict-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html", @@ -263881,6 +264128,18 @@ {} ] ], + "referrer-policy/strict-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ + [ + "/referrer-policy/strict-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html", + {} + ] + ], + "referrer-policy/strict-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ + [ + "/referrer-policy/strict-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html", + {} + ] + ], "referrer-policy/strict-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ [ "/referrer-policy/strict-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html", @@ -264517,6 +264776,18 @@ {} ] ], + "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ + [ + "/referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html", + {} + ] + ], + "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ + [ + "/referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html", + {} + ] + ], "referrer-policy/unsafe-url/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ [ "/referrer-policy/unsafe-url/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html", @@ -264913,6 +265184,18 @@ {} ] ], + "referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ + [ + "/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html", + {} + ] + ], + "referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ + [ + "/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html", + {} + ] + ], "referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ [ "/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html", @@ -265549,6 +265832,18 @@ {} ] ], + "referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ + [ + "/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html", + {} + ] + ], + "referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ + [ + "/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html", + {} + ] + ], "referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ [ "/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html", @@ -265945,6 +266240,18 @@ {} ] ], + "referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ + [ + "/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html", + {} + ] + ], + "referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ + [ + "/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html", + {} + ] + ], "referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ [ "/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html", @@ -279781,6 +280088,12 @@ {} ] ], + "workers/dedicated-worker-from-blob-url.window.js": [ + [ + "/workers/dedicated-worker-from-blob-url.window.html", + {} + ] + ], "workers/importscripts_mime.tentative.any.js": [ [ "/workers/importscripts_mime.tentative.any.serviceworker.html", @@ -280491,15 +280804,15 @@ {} ] ], - "workers/shared-worker-name-via-options.html": [ + "workers/shared-worker-from-blob-url.window.js": [ [ - "/workers/shared-worker-name-via-options.html", + "/workers/shared-worker-from-blob-url.window.html", {} ] ], - "workers/worker-from-blob-url.window.js": [ + "workers/shared-worker-name-via-options.html": [ [ - "/workers/worker-from-blob-url.window.html", + "/workers/shared-worker-name-via-options.html", {} ] ], @@ -301705,11 +302018,11 @@ "testharness" ], "cookie-store/cookieStore_get_set_across_frames.tentative.https.html": [ - "fe5c1f14605815d9914a7a968b91d77d54b604ca", + "c2ef184940390348020aa7e8cdfd24b4a8b9d335", "testharness" ], "cookie-store/cookieStore_get_set_across_origins.tentative.sub.https.html": [ - "5cbe542e32b37b45857e1cecb0c5ddb045bd9f5c", + "e8792612c4352dc1697a2d4efc8dbe6ab7092a7e", "testharness" ], "cookie-store/cookieStore_get_set_basic.tentative.https.window.js": [ @@ -398372,6 +398685,10 @@ "d6c2abe7d57655261ca935a6d5d61bc8d7d5fe44", "testharness" ], + "html/semantics/embedded-content/the-iframe-element/iframe_remove_src.html": [ + "f0ff9ff5082d849d6b987a8ee4b46d5d0d1794e5", + "testharness" + ], "html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_script.html": [ "3e65d91984eeffbfe43d366df8d136848c434b23", "testharness" @@ -419981,7 +420298,7 @@ "testharness" ], "referrer-policy/generic/common.js": [ - "c98056f680b49b7d765064e9c6d5403ed0cfd21b", + "4a3befefc590353906b690d62ff130f3302b86eb", "support" ], "referrer-policy/generic/iframe-inheritance.html": [ @@ -420033,7 +420350,7 @@ "support" ], "referrer-policy/generic/referrer-policy-test-case.js": [ - "14ccd4e2de171e5c8b284e2ced552024b28d345d", + "f19407157d6125642da948ebe7bd1c80c4418777", "support" ], "referrer-policy/generic/sandboxed-iframe-with-opaque-origin.html": [ @@ -420049,7 +420366,7 @@ "testharness" ], "referrer-policy/generic/subresource-test/attr-referrer-invalid-value.html": [ - "9bc74f54a971ac7bd8da01f3668eb275543c5a5a", + "bfdf1166ce7876c478b4cfcf9dab439d04a7e437", "testharness" ], "referrer-policy/generic/subresource-test/fetch-messaging.html": [ @@ -420696,6 +421013,22 @@ "f2152da955f3295aec2ac05adc2357ac7629cf7b", "support" ], + "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ + "6cc76f7583b2f1bcdff27ee6e2fdba8634d26afb", + "testharness" + ], + "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html.headers": [ + "f2152da955f3295aec2ac05adc2357ac7629cf7b", + "support" + ], + "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ + "7eb7b813825853a2207d5016fcd1fd017c71c903", + "testharness" + ], + "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html.headers": [ + "f2152da955f3295aec2ac05adc2357ac7629cf7b", + "support" + ], "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ "c0fe57edd2661e8ae300b6b07f81abe43a0103d7", "testharness" @@ -421056,6 +421389,14 @@ "ce744e0093b15d266dacd23992ae2201f0436987", "testharness" ], + "referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ + "574cdccc9b6dc4f06fa5193088361069c1fb4f56", + "testharness" + ], + "referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ + "f452387ad236f0b0486bc017d63f92880a9cd6f9", + "testharness" + ], "referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ "a70858c0585033e2f46fb80175b6b912aa1d2ede", "testharness" @@ -421648,6 +421989,22 @@ "9b531426e5ab952b03e88b378feb5672a1e5eb4e", "support" ], + "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ + "b18fbef56a84c969c71e014e28d7cd4e8e984a0b", + "testharness" + ], + "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html.headers": [ + "9b531426e5ab952b03e88b378feb5672a1e5eb4e", + "support" + ], + "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ + "3edc386aaa29596a1d61b9f37b6ec03a5cf990f4", + "testharness" + ], + "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html.headers": [ + "9b531426e5ab952b03e88b378feb5672a1e5eb4e", + "support" + ], "referrer-policy/no-referrer/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ "4f12853c0fcb909db6e403deb430e835cf229b38", "testharness" @@ -422008,6 +422365,14 @@ "ea981ad14d08b7fde416e46ee26258ee80f566cb", "testharness" ], + "referrer-policy/no-referrer/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ + "ea935b1d542aae46f105f6be8eff04d448a868db", + "testharness" + ], + "referrer-policy/no-referrer/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ + "e22b638b5d16c44b9c5d58ad72e7e3ab29124079", + "testharness" + ], "referrer-policy/no-referrer/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ "222b078cc664e0472642788c35238e6d29ef2b1e", "testharness" @@ -422652,6 +423017,22 @@ "9ce1de38843b358434a917f1c992c99d0c7fd9fb", "support" ], + "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ + "291f4928bad916933a32c2e50f1cfd649c70d52d", + "testharness" + ], + "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html.headers": [ + "9ce1de38843b358434a917f1c992c99d0c7fd9fb", + "support" + ], + "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ + "f4006d10ac47f7f3d026326026352f5da09fb495", + "testharness" + ], + "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html.headers": [ + "9ce1de38843b358434a917f1c992c99d0c7fd9fb", + "support" + ], "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ "61669344ddd77739934d94de3d0cd4afdac7b2c2", "testharness" @@ -423180,6 +423561,14 @@ "0245434f37cc429db0c28948169f4af353cfb2e7", "testharness" ], + "referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ + "12b857b64dcfd55e208c7082b19af53338599105", + "testharness" + ], + "referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ + "056ff4efbf29acf8372713dce4ed5f7fc018da7a", + "testharness" + ], "referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ "969d7e8dd4c9b634b5233859e1a11d93fb33239b", "testharness" @@ -423856,6 +424245,22 @@ "306a53536ac57625957da5cf4ff55e4124276617", "support" ], + "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ + "db8e7be2376b0119fb9f4ce37a72df943bf51507", + "testharness" + ], + "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html.headers": [ + "306a53536ac57625957da5cf4ff55e4124276617", + "support" + ], + "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ + "5a335d0863cafbfd15e95b6b1fcb7cde9b14663a", + "testharness" + ], + "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html.headers": [ + "306a53536ac57625957da5cf4ff55e4124276617", + "support" + ], "referrer-policy/origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ "04027e95f075c85d94be9a973c85081fc9b70f71", "testharness" @@ -424216,6 +424621,14 @@ "65ed223f1ec81b5f5257a37f77bab0ba640de725", "testharness" ], + "referrer-policy/origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ + "87ebfbfa0b0ae7854dd5747c073ca39b68e50d5b", + "testharness" + ], + "referrer-policy/origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ + "0cf72a93e9e9f89628be50a54b6920e3eeae12dd", + "testharness" + ], "referrer-policy/origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ "96e7d4e7bf935bc23118970f04c719a60cca465f", "testharness" @@ -424780,6 +425193,22 @@ "309da8091a927735fec71fbd4af9acb39eb3a964", "support" ], + "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ + "8da4f3b3be0d75ddb57d280e2b9de46c0479c607", + "testharness" + ], + "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html.headers": [ + "309da8091a927735fec71fbd4af9acb39eb3a964", + "support" + ], + "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ + "424221d94140ef5b31500f0f3e4fcf0cd5e4047f", + "testharness" + ], + "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html.headers": [ + "309da8091a927735fec71fbd4af9acb39eb3a964", + "support" + ], "referrer-policy/same-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ "bbc8f26a58338d88d412759d3dc8d212fe36c6a8", "testharness" @@ -425052,6 +425481,14 @@ "fe2b40c58d48dad8df2d4ed9dd54fbeb1ba59389", "testharness" ], + "referrer-policy/same-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ + "c0d87fa32023fd8914ff1e0a1b438e6cd4ec0617", + "testharness" + ], + "referrer-policy/same-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ + "8586b96fe8b0e66ebfc6fa9c8bf4911d8500a50b", + "testharness" + ], "referrer-policy/same-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ "18f3dbc804e5d2ba22a8df980744f01ffd8c1399", "testharness" @@ -425105,11 +425542,11 @@ "testharness" ], "referrer-policy/spec.src.json": [ - "1ee2b70ee020f7535ab0753626c6863bb085d9c7", + "e67b8c53a94bb227f09f19ea21f588f086e01975", "support" ], "referrer-policy/spec_json.js": [ - "dd1962dbe0c756077e10aca280c4c4dbfda84fc1", + "5377df740f757bd8ebfe3a4e893afc8edfe193a6", "support" ], "referrer-policy/strict-origin-when-cross-origin/attr-referrer/cross-origin/http-http/a-tag/no-redirect/cross-insecure.http.html": [ @@ -425608,6 +426045,22 @@ "d74467b0af6f7dda8bee9107a37e9c14661a9054", "support" ], + "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html": [ + "80d2dcd0787beeed2e906f31d1f562f1b83d2c26", + "testharness" + ], + "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html.headers": [ + "d74467b0af6f7dda8bee9107a37e9c14661a9054", + "support" + ], + "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html": [ + "695afae60374a9604c9314701a0fe5193b26c48f", + "testharness" + ], + "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html.headers": [ + "d74467b0af6f7dda8bee9107a37e9c14661a9054", + "support" + ], "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-insecure.http.html": [ "16c752ce04c794227da700bb8f588aefea4e4f6b", "testharness" @@ -425968,6 +426421,14 @@ "28a143047e54ff10c972fd052d8be01186da4504", "testharness" ], + "referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html": [ + "a74c968cd6f62a03a210ce28cf9070ada039cff8", + "testharness" + ], + "referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html": [ + "e75274330b59cd092fedf6a8c00a2c7552105273", + "testharness" + ], "referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-insecure.http.html": [ "06e0cf6ccb57eefa6e13c117fa7a1ce5d6da7cd8", "testharness" @@ -426560,6 +427021,22 @@ "07af8e286fd7431890f78f10b9e8a0f4b106b5cc", "support" ], + "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ + "82b67545c48b83ef16fbad140020ac89513b91fe", + "testharness" + ], + "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html.headers": [ + "07af8e286fd7431890f78f10b9e8a0f4b106b5cc", + "support" + ], + "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ + "bb8d797d0cb21555280f569442230882ff3898e2", + "testharness" + ], + "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html.headers": [ + "07af8e286fd7431890f78f10b9e8a0f4b106b5cc", + "support" + ], "referrer-policy/strict-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ "56fdc7923fd4fe507f9ddaf81da6f56b20f4210a", "testharness" @@ -426920,6 +427397,14 @@ "46a7a33c3ff1bf81d4bc97e1e9fa1ee3c496397d", "testharness" ], + "referrer-policy/strict-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ + "f60cef60c73b7d6abce9d6474a11928f2b2202c7", + "testharness" + ], + "referrer-policy/strict-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ + "3ee6b651a90dfcc0356fb8db435a04cad7a46c89", + "testharness" + ], "referrer-policy/strict-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ "6186d57f3f85397c8a057a71ca1769b54aadcfd8", "testharness" @@ -427512,6 +427997,22 @@ "c67e521584390fb6c068bcb1a814d73ed9543570", "support" ], + "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ + "8d97cd77bfd1b348322f9bd5e21c26bc005d9833", + "testharness" + ], + "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html.headers": [ + "c67e521584390fb6c068bcb1a814d73ed9543570", + "support" + ], + "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ + "a3291b0ca86e9595880c80032db774885d2f0cbe", + "testharness" + ], + "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html.headers": [ + "c67e521584390fb6c068bcb1a814d73ed9543570", + "support" + ], "referrer-policy/unsafe-url/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ "435281a74c99e98b5e4ec8143cd6d7c82f7dc269", "testharness" @@ -427872,6 +428373,14 @@ "7fe2baacff826cc8b3c13e4a81f60e3897df4332", "testharness" ], + "referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ + "c33155b299903c196404e8a09ac8114b011640f7", + "testharness" + ], + "referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ + "eae3381ae927126b06371038823c423585e6b8ab", + "testharness" + ], "referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ "e1db3d1e59e260c85aa36b3d01efe592513d5e1f", "testharness" @@ -428296,6 +428805,14 @@ "621aaf86a285df38b4298ec486e25016d968f004", "testharness" ], + "referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ + "aa5a9ac86bb5bc899ad21444c9591c33273ea09a", + "testharness" + ], + "referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ + "c2201e9c4e210fb68f52b924d96ed0268c09ffa7", + "testharness" + ], "referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ "2c16b549ae919f7f4524d0f455434df0456f1e34", "testharness" @@ -428560,6 +429077,14 @@ "842e32d571fe2af5253a171eae12bdf8c3f39848", "testharness" ], + "referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ + "15103438ba6853acb9b111fa6b3bf883d46bdaf7", + "testharness" + ], + "referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ + "37e4203474d4189565b237457ee29fbfcfc12278", + "testharness" + ], "referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ "39410f46c6538378abba4e442e7b8cf92c5daf97", "testharness" @@ -441749,7 +442274,7 @@ "support" ], "webrtc/getstats.html": [ - "053d9092ceb6f1ca6900d164ee10965c001f2a0c", + "979e99c0b27cc39af3f3a050df16a70b8f1221e8", "testharness" ], "webrtc/historical-expected.txt": [ @@ -446976,6 +447501,10 @@ "f8fe65e520c4ed9dd0c8779fe55b76459571ec94", "testharness" ], + "workers/dedicated-worker-from-blob-url.window.js": [ + "f54faf54350990a9593e7af022c9eeb769595b15", + "testharness" + ], "workers/importscripts_mime.tentative.any.js": [ "04c63a3a5f6d9bd3b71d94142f65a1825358b8ed", "testharness" @@ -447764,6 +448293,10 @@ "d446781eb7c1cb0d5e60160fb1fe04f9a188f89c", "support" ], + "workers/shared-worker-from-blob-url.window.js": [ + "98e34cc3a69a17f31cf5b890744e5f9ca52559b5", + "testharness" + ], "workers/shared-worker-name-via-options-expected.txt": [ "f2bdb115de3cb52ff71816d0fc27dfd99900ab1d", "support" @@ -447876,10 +448409,6 @@ "d31a8c5eb4633a5379ad2e7be950a2a8ca8ff32d", "support" ], - "workers/worker-from-blob-url.window.js": [ - "fc2fe40c33f53a8ba108b4f1fe8358f2979c9c7d", - "testharness" - ], "workers/worker-performance.worker.js": [ "c913b2e7375067c1a21bdc655f394b5c27bc5aed", "testharness" @@ -448564,6 +449093,10 @@ "283b44b5ab01d1aaa51ba8751547d0f5670d6fcb", "testharness" ], + "xhr/formdata-expected.txt": [ + "0adbe0b731379f828294535ab91889bdeae1acc3", + "support" + ], "xhr/formdata-foreach.html": [ "3ad184c4d55789a2d2f23db61d41b7ad9c650b0b", "testharness" @@ -448581,7 +449114,7 @@ "testharness" ], "xhr/formdata.htm": [ - "e0d0a4e1d4b75420ee5e1592fc8902e1bdfce7a0", + "4390af4a00f21f201bd4db9e4e7197bd27decac3", "testharness" ], "xhr/getallresponseheaders-cookies.htm": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cors/cors-safelisted-request-header.any-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cors/cors-safelisted-request-header.any-expected.txt deleted file mode 100644 index a098d078..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/cors/cors-safelisted-request-header.any-expected.txt +++ /dev/null
@@ -1,18 +0,0 @@ -This is a testharness.js-based test. -FAIL Preflight for {"content-type":"text /plain"} assert_unreached: Should have rejected: undefined Reached unreachable code -FAIL Preflight for {"content-type":"text\t/\tplain"} assert_unreached: Should have rejected: undefined Reached unreachable code -PASS No preflight for {"content-type":"text/plain;"} -PASS No preflight for {"content-type":"text/plain;garbage"} -PASS Preflight for {"content-type":"text/plain;garbage\u0001\u0002"} -PASS Preflight for {"content-type":"text/plain,"} -PASS Preflight for {"content-type":",text/plain"} -PASS Preflight for {"content-type":"text/plain,text/plain"} -PASS Preflight for {"content-type":"text/plain,x/x"} -PASS Preflight for {"content-type":"text/plain\u000b"} -PASS Preflight for {"content-type":"text/plain\f"} -PASS Preflight for {"content-type":"application/www-form-urlencoded"} -PASS Preflight for {"content-type":"application/x-www-form-urlencoded;"} -PASS No preflight for {"content-type":"multipart/form-data"} -PASS Preflight for {"content-type":"multipart/form-data;\""} -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cors/cors-safelisted-request-header.any.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cors/cors-safelisted-request-header.any.worker-expected.txt deleted file mode 100644 index a098d078..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/cors/cors-safelisted-request-header.any.worker-expected.txt +++ /dev/null
@@ -1,18 +0,0 @@ -This is a testharness.js-based test. -FAIL Preflight for {"content-type":"text /plain"} assert_unreached: Should have rejected: undefined Reached unreachable code -FAIL Preflight for {"content-type":"text\t/\tplain"} assert_unreached: Should have rejected: undefined Reached unreachable code -PASS No preflight for {"content-type":"text/plain;"} -PASS No preflight for {"content-type":"text/plain;garbage"} -PASS Preflight for {"content-type":"text/plain;garbage\u0001\u0002"} -PASS Preflight for {"content-type":"text/plain,"} -PASS Preflight for {"content-type":",text/plain"} -PASS Preflight for {"content-type":"text/plain,text/plain"} -PASS Preflight for {"content-type":"text/plain,x/x"} -PASS Preflight for {"content-type":"text/plain\u000b"} -PASS Preflight for {"content-type":"text/plain\f"} -PASS Preflight for {"content-type":"application/www-form-urlencoded"} -PASS Preflight for {"content-type":"application/x-www-form-urlencoded;"} -PASS No preflight for {"content-type":"multipart/form-data"} -PASS Preflight for {"content-type":"multipart/form-data;\""} -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip-path/clip-path-filter-order-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip-path/clip-path-filter-order-ref.html new file mode 100644 index 0000000..5fdef1e --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip-path/clip-path-filter-order-ref.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Clip-path should be applied after filtering</title> +<link rel="author" title="Philip Rogers" href="mailto:pdr@chromium.org"> + +<div> + <p>Expected: A green box.<br> + There should be no red visible.<br> + There should be a crisp, clipped edge around the green box (no blurring).</p> +</div> + +<style> + #testcase { + position: absolute; + width: 200px; + height: 200px; + background: green; + will-change: transform; + } +</style> +<div id="testcase"></div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip-path/clip-path-filter-order.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip-path/clip-path-filter-order.html new file mode 100644 index 0000000..5806e75 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip-path/clip-path-filter-order.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Clip-path should be applied after filtering</title> +<link rel="author" title="Philip Rogers" href="mailto:pdr@chromium.org"> +<link rel="help" href="https://drafts.fxtf.org/css-masking-1/#placement"> +<link rel="match" href="clip-path-filter-order-ref.html"> + +<div> + <p>Expected: A green box.<br> + There should be no red visible.<br> + There should be a crisp, clipped edge around the green box (no blurring).</p> +</div> + +<style> + #testcase { + position: absolute; + width: 400px; + height: 400px; + background: green; + will-change: transform; + filter: drop-shadow(16px 16px 20px red); + clip-path: inset(0px 200px 200px 0px); + } +</style> +<div id="testcase"></div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip/clip-filter-order-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip/clip-filter-order-ref.html new file mode 100644 index 0000000..e5763bf --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip/clip-filter-order-ref.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Clip should be applied after filtering</title> +<link rel="author" title="Philip Rogers" href="mailto:pdr@chromium.org"> + +<div> + <p>Expected: A green box.<br> + There should be no red visible.<br> + There should be a crisp, clipped edge around the green box (no blurring).</p> +</div> + +<style> + #testcase { + position: absolute; + width: 200px; + height: 200px; + background: green; + will-change: transform; + } +</style> +<div id="testcase"></div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip/clip-filter-order.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip/clip-filter-order.html new file mode 100644 index 0000000..79f2f71 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip/clip-filter-order.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Clip should be applied after filtering</title> +<link rel="author" title="Philip Rogers" href="mailto:pdr@chromium.org"> +<link rel="help" href="https://drafts.fxtf.org/css-masking-1/#placement"> +<link rel="match" href="clip-filter-order-ref.html"> + +<div> + <p>Expected: A green box.<br> + There should be no red visible.<br> + There should be a crisp, clipped edge around the green box (no blurring).</p> +</div> + +<style> + #testcase { + position: absolute; + width: 400px; + height: 400px; + background: green; + will-change: transform; + filter: drop-shadow(16px 16px 20px red); + clip: rect(0px, 200px, 200px, 0px); + } +</style> +<div id="testcase"></div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-text/text-indent/percentage-value-intrinsic-size.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text/text-indent/percentage-value-intrinsic-size.html new file mode 100644 index 0000000..d63a9f1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-text/text-indent/percentage-value-intrinsic-size.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-text-3/#text-indent-property"> +<meta name="assert" content="Percentages should be ignored when calculating min/max intrinsic sizes."> +<p>Test passes if there is a filled green square.</p> +<div id="container" data-expected-width="50" style="position:relative; float:left; height:100px; background:green;"> + <div id="foo"> + <div data-offset-x="50" data-expected-width="50" style="display:inline-block; width:50px; height:100px; background:green;"></div> + <div style="width:50px;"></div> + </div> +</div> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<script> + document.body.offsetTop; + foo.style.textIndent = "100%"; + checkLayout("#container"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/data-urls/processing.any-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/data-urls/processing.any-expected.txt index 645f1166..a0a3296b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/fetch/data-urls/processing.any-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/data-urls/processing.any-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 71 tests; 44 PASS, 27 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 71 tests; 45 PASS, 26 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Setup. PASS "data://test/,X" FAIL "data://test:test/,X" assert_unreached: Should have rejected: undefined Reached unreachable code @@ -31,7 +31,7 @@ PASS "data:\0,%FF" PASS "data:%00,%FF" PASS "data:text/html ,X" -FAIL "data:text / html,X" assert_equals: expected "text/plain;charset=US-ASCII" but got "text / html" +PASS "data:text / html,X" PASS "data:†,X" PASS "data:†/†,X" PASS "data:X,X"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/data-urls/processing.any.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/data-urls/processing.any.worker-expected.txt index 645f1166..a0a3296b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/fetch/data-urls/processing.any.worker-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/data-urls/processing.any.worker-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 71 tests; 44 PASS, 27 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 71 tests; 45 PASS, 26 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Setup. PASS "data://test/,X" FAIL "data://test:test/,X" assert_unreached: Should have rejected: undefined Reached unreachable code @@ -31,7 +31,7 @@ PASS "data:\0,%FF" PASS "data:%00,%FF" PASS "data:text/html ,X" -FAIL "data:text / html,X" assert_equals: expected "text/plain;charset=US-ASCII" but got "text / html" +PASS "data:text / html,X" PASS "data:†,X" PASS "data:†/†,X" PASS "data:X,X"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_remove_src.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_remove_src.html new file mode 100644 index 0000000..f0ff9ff --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_remove_src.html
@@ -0,0 +1,40 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test that removing the src attribute of an iframe loads about:blank + instead of whatever was loaded previously.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> + <script> + var iframe; + var t = async_test(); + t.step(setupFrame); + + function setupFrame() { + iframe = document.createElement("iframe"); + iframe.src = URL.createObjectURL(new Blob(["text"], { type: "text/html" })); + iframe.onload = t.step_func(blobLoaded); + document.body.appendChild(iframe); + } + + var removalRunning = false; + function blobLoaded() { + assert_equals(iframe.contentDocument.location.protocol, "blob:", + "Should have loaded the blob"); + assert_equals(iframe.contentDocument.documentElement.textContent, "text", + "Should have loaded the blob text"); + iframe.onload = t.step_func_done(aboutBlankLoaded); + removalRunning = true; + iframe.removeAttribute("src"); + removalRunning = false; + } + + function aboutBlankLoaded() { + assert_false(removalRunning, "Should not have loaded about:blank sync"); + assert_equals(iframe.contentDocument.location.href, "about:blank", + "Should have loaded about:blank"); + assert_equals(iframe.contentDocument.documentElement.textContent, "", + "Should have loaded the about:blank text"); + } + </script> +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/subresource-test/attr-referrer-invalid-value.html b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/subresource-test/attr-referrer-invalid-value.html index 9bc74f5..bfdf116 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/subresource-test/attr-referrer-invalid-value.html +++ b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/subresource-test/attr-referrer-invalid-value.html
@@ -11,7 +11,7 @@ <script> test(function () { - var elements = ["iframe", "img", "a", "area", "link"]; + var elements = ["iframe", "img", "a", "area", "link", "script"]; for (var i = 0; i < elements.length; i++) { var elem = document.createElement(elements[i]); elem.referrerPolicy = "unsafe-url";
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/clients-get-client-types.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/clients-get-client-types.https.html index 897e368..63e3e51 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/clients-get-client-types.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/clients-get-client-types.https.html
@@ -9,11 +9,13 @@ var shared_worker_url = scope + '-shared-worker.js'; var worker_url = scope + '-worker.js'; var client_ids = []; +var registration; var frame; promise_test(function(t) { return service_worker_unregister_and_register( t, 'resources/clients-get-worker.js', scope) - .then(function(registration) { + .then(function(r) { + registration = r; add_completion_callback(function() { registration.unregister(); }); return wait_for_state(t, registration.installing, 'activated'); }) @@ -59,12 +61,10 @@ }) .then(function(client_id) { client_ids.push(client_id); - var channel = new MessageChannel(); var saw_message = new Promise(function(resolve) { - channel.port1.onmessage = resolve; + navigator.serviceWorker.onmessage = resolve; }); - frame.contentWindow.navigator.serviceWorker.controller.postMessage( - {port: channel.port2, clientIds: client_ids}, [channel.port2]); + registration.active.postMessage({clientIds: client_ids}); return saw_message; }) .then(function(e) {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/clients-get.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/clients-get.https.html index b052740..4cfbf59 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/clients-get.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/clients-get.https.html
@@ -4,221 +4,151 @@ <script src="/resources/testharnessreport.js"></script> <script src="resources/test-helpers.sub.js"></script> <script> -var scope = 'resources/clients-get-frame.html'; -var client_ids = []; -var frame; -promise_test(function(t) { - return service_worker_unregister_and_register( - t, 'resources/clients-get-worker.js', scope) - .then(function(registration) { - add_completion_callback(function() { registration.unregister(); }); - return wait_for_state(t, registration.installing, 'activated'); - }) - .then(function() { - return with_iframe(scope + '#1'); - }) - .then(function(frame1) { - add_completion_callback(function() { frame1.remove(); }); - frame1.focus(); - return wait_for_clientId(); - }) - .then(function(client_id) { - client_ids.push(client_id); - return with_iframe(scope + '#2'); - }) - .then(function(frame2) { - frame = frame2; - add_completion_callback(function() { frame2.remove(); }); - return wait_for_clientId(); - }) - .then(function(client_id) { - client_ids.push(client_id, 'invalid-id'); - var channel = new MessageChannel(); - var saw_message = new Promise(function(resolve) { - channel.port1.onmessage = resolve; - }); - frame.contentWindow.navigator.serviceWorker.controller.postMessage( - {port: channel.port2, clientIds: client_ids}, [channel.port2]); - return saw_message; - }) - .then(function(e) { - assert_equals(e.data.length, 3); - assert_array_equals(e.data[0], expected[0]); - assert_array_equals(e.data[1], expected[1]); - assert_equals(e.data[2], expected[2]); - }); - }, 'Test Clients.get()'); - -promise_test((t) => { - let frame = null; - const scope = 'resources/simple.html'; - const outerSwContainer = navigator.serviceWorker; - let innerSwReg = null; - let innerSw = null; - - return service_worker_unregister_and_register( - t, 'resources/clients-get-resultingClientId-worker.js', scope) - .then((registration) => { - innerSwReg = registration; - add_completion_callback(function() { registration.unregister(); }); - return wait_for_state(t, registration.installing, 'activated'); - }) - .then(() => { - // load frame and get resulting client id - let channel = new MessageChannel(); - innerSw = innerSwReg.active; - - let p = new Promise(resolve => { - function getResultingClientId(e) { - if (e.data.msg == 'getResultingClientId') { - const { resultingClientId } = e.data; - - channel.port1.removeEventListener('message', getResultingClientId); - - resolve({ resultingClientId, port: channel.port1 }); - } - } - - channel.port1.onmessage = getResultingClientId; - }); - - - return with_iframe(scope).then((iframe) => { - innerSw.postMessage( - { port: channel.port2, msg: 'getResultingClientId' }, - [channel.port2], - ); - - frame = iframe; - frame.focus(); - add_completion_callback(() => iframe.remove()); - - return p; - }); - }) - .then(({ resultingClientId, port }) => { - // query service worker for clients.get(resultingClientId) - let channel = new MessageChannel(); - - let p = new Promise(resolve => { - function getIsResultingClientUndefined(e) { - if (e.data.msg == 'getIsResultingClientUndefined') { - let { isResultingClientUndefined } = e.data; - - port.removeEventListener('message', getIsResultingClientUndefined); - - resolve(isResultingClientUndefined); - } - } - - port.onmessage = getIsResultingClientUndefined; - }); - - innerSw.postMessage( - { port: channel.port2, msg: 'getIsResultingClientUndefined', resultingClientId }, - [channel.port2], - ); - - return p; - }) - .then((isResultingClientUndefined) => { - assert_false(isResultingClientUndefined, 'Clients.get(FetchEvent.resultingClientId) resolved with a Client'); - }); -}, 'Test successful Clients.get(FetchEvent.resultingClientId)'); - -promise_test((t) => { - const scope = 'resources/simple.html?fail'; - const outerSwContainer = navigator.serviceWorker; - let innerSwReg = null; - let innerSw = null; - - return service_worker_unregister_and_register( - t, 'resources/clients-get-resultingClientId-worker.js', scope) - .then((registration) => { - innerSwReg = registration; - add_completion_callback(function() { registration.unregister(); }); - return wait_for_state(t, registration.installing, 'activated'); - }) - .then(() => { - // load frame, destroying it while loading, and get resulting client id - innerSw = innerSwReg.active; - - let iframe = document.createElement('iframe'); - iframe.className = 'test-iframe'; - iframe.src = scope; - - function destroyIframe(e) { - if (e.data.msg == 'destroyResultingClient') { - iframe.remove(); - iframe = null; - - innerSw.postMessage({ msg: 'resultingClientDestroyed' }); - } - } - - outerSwContainer.addEventListener('message', destroyIframe); - - let p = new Promise(resolve => { - function resultingClientDestroyedAck(e) { - if (e.data.msg == 'resultingClientDestroyedAck') { - let { resultingDestroyedClientId } = e.data; - - outerSwContainer.removeEventListener('message', resultingClientDestroyedAck); - resolve(resultingDestroyedClientId); - } - } - - outerSwContainer.addEventListener('message', resultingClientDestroyedAck); - }); - - document.body.appendChild(iframe); - - return p; - }) - .then((resultingDestroyedClientId) => { - // query service worker for clients.get(resultingDestroyedClientId) - let channel = new MessageChannel(); - - let p = new Promise((resolve, reject) => { - function getIsResultingClientUndefined(e) { - if (e.data.msg == 'getIsResultingClientUndefined') { - let { isResultingClientUndefined } = e.data; - - channel.port1.removeEventListener('message', getIsResultingClientUndefined); - - resolve(isResultingClientUndefined); - } - } - - channel.port1.onmessage = getIsResultingClientUndefined; - }); - - innerSw.postMessage( - { port: channel.port2, msg: 'getIsResultingClientUndefined', resultingClientId: resultingDestroyedClientId }, - [channel.port2], - ); - - return p; - }) - .then((isResultingClientUndefined) => { - assert_true(isResultingClientUndefined, 'Clients.get(FetchEvent.resultingClientId) resolved with `undefined`'); - }); -}, 'Test unsuccessful Clients.get(FetchEvent.resultingClientId)'); - function wait_for_clientId() { return new Promise(function(resolve, reject) { - function get_client_id(e) { - window.removeEventListener('message', get_client_id); - resolve(e.data.clientId); - } - window.addEventListener('message', get_client_id, false); - }); + window.onmessage = e => { + resolve(e.data.clientId); + }; + }); } -var expected = [ +promise_test(async t => { + // Register service worker. + const scope = 'resources/clients-get-frame.html'; + const client_ids = []; + const registration = await service_worker_unregister_and_register( + t, 'resources/clients-get-worker.js', scope); + t.add_cleanup(() => registration.unregister()); + await wait_for_state(t, registration.installing, 'activated'); + + // Prepare for test cases. + // Case 1: frame1 which is focused. + const frame1 = await with_iframe(scope + '#1'); + t.add_cleanup(() => frame1.remove()); + frame1.focus(); + client_ids.push(await wait_for_clientId()); + // Case 2: frame2 which is not focused. + const frame2 = await with_iframe(scope + '#2'); + t.add_cleanup(() => frame2.remove()); + client_ids.push(await wait_for_clientId()); + // Case 3: invalid id. + client_ids.push('invalid-id'); + + // Call clients.get() for each id on the service worker. + const message_event = await new Promise(resolve => { + navigator.serviceWorker.onmessage = resolve; + registration.active.postMessage({clientIds: client_ids}); + }); + + const expected = [ // visibilityState, focused, url, type, frameType ['visible', true, normalizeURL(scope) + '#1', 'window', 'nested'], ['visible', false, normalizeURL(scope) + '#2', 'window', 'nested'], undefined -]; + ]; + assert_equals(message_event.data.length, 3); + assert_array_equals(message_event.data[0], expected[0]); + assert_array_equals(message_event.data[1], expected[1]); + assert_equals(message_event.data[2], expected[2]); +}, 'Test Clients.get()'); + +promise_test(async t => { + // Register service worker. + const scope = 'resources/simple.html'; + const registration = await service_worker_unregister_and_register( + t, 'resources/clients-get-resultingClientId-worker.js', scope) + t.add_cleanup(() => registration.unregister()); + await wait_for_state(t, registration.installing, 'activated'); + const worker = registration.active; + + // Load frame within the scope. + const frame = await with_iframe(scope); + t.add_cleanup(() => frame.remove()); + frame.focus(); + + // Get resulting client id. + const resultingClientId = await new Promise(resolve => { + navigator.serviceWorker.onmessage = e => { + if (e.data.msg == 'getResultingClientId') { + resolve(e.data.resultingClientId); + } + }; + worker.postMessage({msg: 'getResultingClientId'}); + }); + + // Query service worker for clients.get(resultingClientId). + const isResultingClientUndefined = await new Promise(resolve => { + navigator.serviceWorker.onmessage = e => { + if (e.data.msg == 'getIsResultingClientUndefined') { + resolve(e.data.isResultingClientUndefined); + } + }; + worker.postMessage({msg: 'getIsResultingClientUndefined', + resultingClientId}); + }); + + assert_false( + isResultingClientUndefined, + 'Clients.get(FetchEvent.resultingClientId) resolved with a Client'); +}, 'Test successful Clients.get(FetchEvent.resultingClientId)'); + +promise_test(async t => { + // Register service worker. + const scope = 'resources/simple.html?fail'; + const registration = await service_worker_unregister_and_register( + t, 'resources/clients-get-resultingClientId-worker.js', scope); + t.add_cleanup(() => registration.unregister()); + await wait_for_state(t, registration.installing, 'activated'); + + // Load frame, and destroy it while loading. + const worker = registration.active; + let frame = document.createElement('iframe'); + frame.src = scope; + t.add_cleanup(() => { + if (frame) { + frame.remove(); + } + }); + + await new Promise(resolve => { + navigator.serviceWorker.onmessage = e => { + // The service worker posts a message to remove the iframe during fetch + // event. + if (e.data.msg == 'destroyResultingClient') { + frame.remove(); + frame = null; + worker.postMessage({msg: 'resultingClientDestroyed'}); + resolve(); + } + }; + document.body.appendChild(frame); + }); + + resultingDestroyedClientId = await new Promise(resolve => { + navigator.serviceWorker.onmessage = e => { + // The worker sends a message back when it receives the message + // 'resultingClientDestroyed' with the resultingClientId. + if (e.data.msg == 'resultingClientDestroyedAck') { + assert_equals(frame, null, 'Frame should be destroyed at this point.'); + resolve(e.data.resultingDestroyedClientId); + } + }; + }); + + // Query service worker for clients.get(resultingDestroyedClientId). + const isResultingClientUndefined = await new Promise(resolve => { + navigator.serviceWorker.onmessage = e => { + if (e.data.msg == 'getIsResultingClientUndefined') { + resolve(e.data.isResultingClientUndefined); + } + }; + worker.postMessage({msg: 'getIsResultingClientUndefined', + resultingClientId: resultingDestroyedClientId }); + }); + + assert_true( + isResultingClientUndefined, + 'Clients.get(FetchEvent.resultingClientId) resolved with `undefined`'); +}, 'Test unsuccessful Clients.get(FetchEvent.resultingClientId)'); + </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-cross-origin-frame.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-cross-origin-frame.html index eaade327..e16bb11 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-cross-origin-frame.html +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-cross-origin-frame.html
@@ -38,16 +38,13 @@ }) .then(function(iframe) { add_completion_callback(function() { iframe.remove(); }); - var channel = new MessageChannel(); - channel.port1.onmessage = function(e) { + navigator.serviceWorker.onmessage = function(e) { registration.unregister(); window.parent.postMessage( { type: 'clientId', value: e.data }, host_info['HTTPS_ORIGIN'] ); }; - iframe.contentWindow.navigator.serviceWorker.controller.postMessage( - {port:channel.port2, clientIds: cross_origin_client_ids}, - [channel.port2]); + registration.active.postMessage({clientIds: cross_origin_client_ids}); }); }); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-resultingClientId-worker.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-resultingClientId-worker.js index 153a8e3..5a46ff9 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-resultingClientId-worker.js +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-resultingClientId-worker.js
@@ -1,31 +1,27 @@ let savedPort = null; let savedResultingClientId = null; -async function destroyResultingClient(e) { - const outer = await self.clients.matchAll({ type: 'window', includeUncontrolled: true }) - .then((clientList) => { - for (let c of clientList) { - if (c.url.endsWith('clients-get.https.html')) { - c.focus(); - return c; - } +async function getTestingPage() { + const clientList = await self.clients.matchAll({ type: 'window', includeUncontrolled: true }); + for (let c of clientList) { + if (c.url.endsWith('clients-get.https.html')) { + c.focus(); + return c; } - }); + } + return null; +} - const p = new Promise(resolve => { - function resultingClientDestroyed(evt) { - if (evt.data.msg == 'resultingClientDestroyed') { - self.removeEventListener('message', resultingClientDestroyed); - resolve(outer); +async function destroyResultingClient(testingPage) { + const destroyedPromise = new Promise(resolve => { + self.addEventListener('message', e => { + if (e.data.msg == 'resultingClientDestroyed') { + resolve(); } - } - - self.addEventListener('message', resultingClientDestroyed); + }, {once: true}); }); - - outer.postMessage({ msg: 'destroyResultingClient' }); - - return await p; + testingPage.postMessage({ msg: 'destroyResultingClient' }); + return destroyedPromise; } self.addEventListener('fetch', async (e) => { @@ -33,32 +29,32 @@ savedResultingClientId = resultingClientId; if (e.request.url.endsWith('simple.html?fail')) { - e.waitUntil(new Promise(async (resolve) => { - let outer = await destroyResultingClient(e); - - outer.postMessage({ msg: 'resultingClientDestroyedAck', - resultingDestroyedClientId: savedResultingClientId }); - resolve(); - })); - } else { - e.respondWith(fetch(e.request)); + e.waitUntil((async () => { + const testingPage = await getTestingPage(); + await destroyResultingClient(testingPage); + testingPage.postMessage({ msg: 'resultingClientDestroyedAck', + resultingDestroyedClientId: savedResultingClientId }); + })()); + return; } + + e.respondWith(fetch(e.request)); }); self.addEventListener('message', (e) => { - let { msg, port, resultingClientId } = e.data; - savedPort = savedPort || port; - - if (msg == 'getIsResultingClientUndefined') { - self.clients.get(resultingClientId).then((client) => { + let { msg, resultingClientId } = e.data; + e.waitUntil((async () => { + if (msg == 'getIsResultingClientUndefined') { + const client = await self.clients.get(resultingClientId); let isUndefined = typeof client == 'undefined'; - savedPort.postMessage({ msg: 'getIsResultingClientUndefined', + e.source.postMessage({ msg: 'getIsResultingClientUndefined', isResultingClientUndefined: isUndefined }); - }); - } - - if (msg == 'getResultingClientId') { - savedPort.postMessage({ msg: 'getResultingClientId', - resultingClientId: savedResultingClientId }); - } + return; + } + if (msg == 'getResultingClientId') { + e.source.postMessage({ msg: 'getResultingClientId', + resultingClientId: savedResultingClientId }); + return; + } + })()); });
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-worker.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-worker.js index 87368ae..8effa56c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-worker.js +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/clients-get-worker.js
@@ -11,7 +11,6 @@ }; self.onmessage = function(e) { - var port = e.data.port; var client_ids = e.data.clientIds; var message = []; @@ -23,7 +22,7 @@ // No matching client for a given id or a matched client is off-origin // from the service worker. if (clients.length == 1 && clients[0] == undefined) { - port.postMessage(clients[0]); + e.source.postMessage(clients[0]); } else { clients.forEach(function(client) { if (client instanceof Client) { @@ -36,7 +35,7 @@ message.push(client); } }); - port.postMessage(message); + e.source.postMessage(message); } })); };
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/embedded/image-embedding-svg-with-viewport-units-inline-style.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/embedded/image-embedding-svg-with-viewport-units-inline-style.svg new file mode 100644 index 0000000..7880fcf --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/embedded/image-embedding-svg-with-viewport-units-inline-style.svg
@@ -0,0 +1,10 @@ +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:h="http://www.w3.org/1999/xhtml"> + <metadata> + <title><image> embedding SVG image with viewport units</title> + <h:link rel="match" href="support/green-rect-100x100.svg"/> + </metadata> + <image xlink:href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><rect style='width: 50vw; height: 50vh' fill='green'/></svg>" + width="200" height="200"/> +</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/rendering/order/clip-path-filter-order-ref.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/rendering/order/clip-path-filter-order-ref.svg new file mode 100644 index 0000000..ea42d9eb --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/rendering/order/clip-path-filter-order-ref.svg
@@ -0,0 +1,6 @@ +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:h="http://www.w3.org/1999/xhtml" + xmlns:xlink="http://www.w3.org/1999/xlink" + width="800" height="600" viewBox="0 0 800 600"> + <rect x="100" y="100" width="200" height="200" fill="green" /> +</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/rendering/order/clip-path-filter-order.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/rendering/order/clip-path-filter-order.svg new file mode 100644 index 0000000..22cda52 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/rendering/order/clip-path-filter-order.svg
@@ -0,0 +1,26 @@ +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:h="http://www.w3.org/1999/xhtml" + xmlns:xlink="http://www.w3.org/1999/xlink" + width="800" height="600" viewBox="0 0 800 600"> + <metadata> + <h:link rel="author" title="Philip Rogers" href="mailto:pdr@chromium.org"/> + <h:link rel="help" href="https://www.w3.org/TR/SVG11/single-page.html#render-RenderingOrder"/> + <h:link rel="match" href="clip-path-filter-order-ref.svg"/> + <h:meta name="assert" content="Clip path should apply after filtering."/> + </metadata> + + <defs> + <filter id="redDropShadowFilter"> + <feOffset result="offsetOut" in="SourceGraphic" dx="10" dy="10" /> + <feColorMatrix result="colorMatrixOut" in="offsetOut" type="matrix" + values="1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" /> + <feGaussianBlur result="blurOut" in="colorMatrixOut" stdDeviation="15" /> + <feBlend in="SourceGraphic" in2="blurOut" mode="normal" /> + </filter> + <clipPath id="clipPath"> + <rect x="100" y="100" width="200" height="200" /> + </clipPath> + </defs> + <rect x="100" y="100" width="400" height="400" fill="green" + filter="url(#redDropShadowFilter)" clip-path="url(#clipPath)" /> +</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/getstats.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/getstats.html index 053d9092..979e99c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/getstats.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/getstats.html
@@ -12,6 +12,7 @@ <div id="log"></div> <h2>Retrieved stats info</h2> <pre> + <input type="button" onclick="showStats()" value="Show stats"></input> <div id="stats"> </div> </pre> @@ -21,7 +22,7 @@ <script src="/resources/testharnessreport.js"></script> <script type="text/javascript"> var test = async_test('Can get stats from a basic WebRTC call.'); - + var statsToShow; var gFirstConnection = null; var gSecondConnection = null; @@ -56,13 +57,11 @@ } gFirstConnection.getStats() .then(function(report) { - // Show the retrieved stats info - var showStats = document.getElementById('stats'); let reportDictionary = {}; for (let stats of report.values()) { reportDictionary[stats.id] = stats; } - showStats.innerHTML = JSON.stringify(reportDictionary, null, 2); + statsToShow = JSON.stringify(reportDictionary, null, 2); // Check the stats properties. assert_not_equals(report, null, 'No report'); let sessionStat = getStatsRecordByType(report, 'peer-connection'); @@ -121,6 +120,13 @@ ' happened at step ' + atStep); })); }); + + function showStats() { + // Show the retrieved stats info + var showStats = document.getElementById('stats'); + showStats.innerHTML = statsToShow; + } + </script> </body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/dedicated-worker-from-blob-url.window.js b/third_party/WebKit/LayoutTests/external/wpt/workers/dedicated-worker-from-blob-url.window.js new file mode 100644 index 0000000..f54faf5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/workers/dedicated-worker-from-blob-url.window.js
@@ -0,0 +1,28 @@ +function message_from_port(port) { + return new Promise(resolve => { + port.onmessage = e => resolve(e.data); + }); +} + +promise_test(async t => { + const run_result = 'worker_OK'; + const blob_contents = 'self.postMessage("' + run_result + '");'; + const blob = new Blob([blob_contents]); + const url = URL.createObjectURL(blob); + + const worker = new Worker(url); + const reply = await message_from_port(worker); + assert_equals(reply, run_result); +}, 'Creating a dedicated worker from a blob URL works.'); + +promise_test(async t => { + const run_result = 'worker_OK'; + const blob_contents = 'self.postMessage("' + run_result + '");'; + const blob = new Blob([blob_contents]); + const url = URL.createObjectURL(blob); + + const worker = new Worker(url); + URL.revokeObjectURL(url); + const reply = await message_from_port(worker); + assert_equals(reply, run_result); +}, 'Creating a dedicated worker from a blob URL works immediately before revoking.');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/worker-from-blob-url.window.js b/third_party/WebKit/LayoutTests/external/wpt/workers/shared-worker-from-blob-url.window.js similarity index 69% rename from third_party/WebKit/LayoutTests/external/wpt/workers/worker-from-blob-url.window.js rename to third_party/WebKit/LayoutTests/external/wpt/workers/shared-worker-from-blob-url.window.js index fc2fe40..98e34cc 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/workers/worker-from-blob-url.window.js +++ b/third_party/WebKit/LayoutTests/external/wpt/workers/shared-worker-from-blob-url.window.js
@@ -5,29 +5,6 @@ } promise_test(async t => { - const run_result = 'worker_OK'; - const blob_contents = 'self.postMessage("' + run_result + '");'; - const blob = new Blob([blob_contents]); - const url = URL.createObjectURL(blob); - - const worker = new Worker(url); - const reply = await message_from_port(worker); - assert_equals(reply, run_result); -}, 'Creating a dedicated worker from a blob URL works.'); - -promise_test(async t => { - const run_result = 'worker_OK'; - const blob_contents = 'self.postMessage("' + run_result + '");'; - const blob = new Blob([blob_contents]); - const url = URL.createObjectURL(blob); - - const worker = new Worker(url); - URL.revokeObjectURL(url); - const reply = await message_from_port(worker); - assert_equals(reply, run_result); -}, 'Creating a dedicated worker from a blob URL works immediately before revoking.'); - -promise_test(async t => { const run_result = 'worker_OK_'; const blob_contents = 'self.counter = 0; self.onconnect = e => {++self.counter;' + @@ -57,7 +34,6 @@ assert_equals(reply, run_result); }, 'Creating a shared worker from a blob URL works immediately before revoking.'); - promise_test(async t => { const run_result = 'worker_OK_'; const blob_contents =
diff --git a/third_party/WebKit/LayoutTests/external/wpt/xhr/formdata-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/xhr/formdata-expected.txt new file mode 100644 index 0000000..0adbe0b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/xhr/formdata-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +FAIL Constructors assert_throws: function "() => { new FormData(null); }" did not throw +PASS empty formdata +PASS formdata with string +PASS formdata with named string +PASS formdata from form +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/xhr/formdata.htm b/third_party/WebKit/LayoutTests/external/wpt/xhr/formdata.htm index e0d0a4e..4390af4a 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/xhr/formdata.htm +++ b/third_party/WebKit/LayoutTests/external/wpt/xhr/formdata.htm
@@ -1,7 +1,7 @@ <!doctype html> <html lang=en> <meta charset=utf-8> -<title>XMLHttpRequest: upload formdata</title> +<title>XMLHttpRequest: Construct and upload FormData</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <link rel="help" href="https://xhr.spec.whatwg.org/#interface-formdata" data-tested-assertations="following::P[1]" /> @@ -35,6 +35,11 @@ return fd; } + test(() => { + assert_throws(new TypeError(), () => { new FormData(null); }); + assert_throws(new TypeError(), () => { new FormData("string"); }); + }, "Constructors"); + do_test("empty formdata", new FormData(), '\n'); do_test("formdata with string", create_formdata(['key', 'value']), 'key=value,\n'); do_test("formdata with named string", create_formdata(['key', new Blob(['value'], {type: 'text/plain'}), 'kv.txt']), '\nkey=kv.txt:text/plain:5,');
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/add-remove-float-after-table-relayout-crash.html b/third_party/WebKit/LayoutTests/fast/block/float/add-remove-float-after-table-relayout-crash.html new file mode 100644 index 0000000..074af4a --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/block/float/add-remove-float-after-table-relayout-crash.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<style>body { overflow:scroll; }</style> +<p>PASS if no crash or DCHECK failure</p> +<div id="container" style="width:300px;"> + <div style="display:table;"></div> + <div id="firstFloat" style="float:left;"></div> + <div id="secondFloat" style="display:none; float:left;"></div> +</div> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script> + test(() => { + document.body.offsetTop; + container.style.width = "301px"; + document.body.offsetTop; + secondFloat.style.display = "block"; + document.body.offsetTop; + secondFloat.style.display = "none"; + }, "PASS if no crash or DCHECK failure"); +</script>
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/compositing/should-not-paint-outline-on-foreground-layer-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/compositing/should-not-paint-outline-on-foreground-layer-expected.txt index b6485857..fb01873 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/compositing/should-not-paint-outline-on-foreground-layer-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/compositing/should-not-paint-outline-on-foreground-layer-expected.txt
@@ -23,6 +23,13 @@ } ], "transform": 1 + }, + { + "name": "LayoutBlockFlow (positioned) DIV", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#FF0000", + "transform": 2 } ], "transforms": [ @@ -34,6 +41,16 @@ [0, 0, 1, 0], [8, 8, 0, 1] ] + }, + { + "id": 2, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, -400, 0, 1] + ] } ] }
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/position/abspos-shift-image-incorrect-repaint-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/position/abspos-shift-image-incorrect-repaint-expected.txt index 8e7c606..589f5f9 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/position/abspos-shift-image-incorrect-repaint-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/position/abspos-shift-image-incorrect-repaint-expected.txt
@@ -19,7 +19,7 @@ { "object": "LayoutImage IMG", "rect": [0, 0, 214, 232], - "reason": "disappeared" + "reason": "geometry" }, { "object": "InlineTextBox '\n'",
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll/invalidate-after-composited-scroll-of-window-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll/invalidate-after-composited-scroll-of-window-expected.txt index 0324f57..8600202 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll/invalidate-after-composited-scroll-of-window-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/scroll/invalidate-after-composited-scroll-of-window-expected.txt
@@ -7,9 +7,14 @@ "backgroundColor": "#FFFFFF", "paintInvalidations": [ { - "object": "LayoutBlockFlow HTML", + "object": "InlineTextBox 'Tests that invalidation of a div after scrolling invalidates just the div and no other area.'", + "rect": [8, 4908, 540, 19], + "reason": "appeared" + }, + { + "object": "LayoutBlockFlow DIV id='target'", "rect": [8, 2408, 100, 100], - "reason": "chunk appeared" + "reason": "background" } ], "transform": 1
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/single-line-cells-repeating-thead-break-inside-on-thead-only-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/single-line-cells-repeating-thead-break-inside-on-thead-only-expected.txt index 88e90e1..11aa65d 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/single-line-cells-repeating-thead-break-inside-on-thead-only-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/single-line-cells-repeating-thead-break-inside-on-thead-only-expected.txt
@@ -20,6 +20,11 @@ "object": "InlineTextBox 'Col 1'", "rect": [10, 74, 836, 19], "reason": "style change" + }, + { + "object": "InlineTextBox 'Col 1'", + "rect": [10, 74, 836, 19], + "reason": "style change" } ] },
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/table-shrink-row-repaint-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/table-shrink-row-repaint-expected.txt index 893e5c06..2343ed7 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/table-shrink-row-repaint-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/table-shrink-row-repaint-expected.txt
@@ -13,13 +13,48 @@ }, { "object": "LayoutTableCell TD", + "rect": [8, 782, 769, 60], + "reason": "geometry" + }, + { + "object": "LayoutTableCell TD", + "rect": [8, 742, 769, 60], + "reason": "geometry" + }, + { + "object": "LayoutTableCell TD", + "rect": [8, 722, 769, 60], + "reason": "geometry" + }, + { + "object": "LayoutTableCell TD", + "rect": [8, 682, 769, 60], + "reason": "geometry" + }, + { + "object": "LayoutTableCell TD", + "rect": [8, 662, 769, 60], + "reason": "geometry" + }, + { + "object": "LayoutTableCell TD", + "rect": [8, 622, 769, 60], + "reason": "geometry" + }, + { + "object": "LayoutTableCell TD", + "rect": [8, 602, 769, 60], + "reason": "geometry" + }, + { + "object": "LayoutTableCell TD", "rect": [8, 562, 769, 60], "reason": "geometry" }, { "object": "LayoutTableCell TD", "rect": [8, 542, 769, 60], - "reason": "appeared" + "reason": "geometry" }, { "object": "LayoutTableCell TD", @@ -29,7 +64,7 @@ { "object": "LayoutTableCell TD", "rect": [8, 482, 769, 60], - "reason": "appeared" + "reason": "geometry" }, { "object": "LayoutTableCell TD", @@ -39,7 +74,7 @@ { "object": "LayoutTableCell TD", "rect": [8, 422, 769, 60], - "reason": "appeared" + "reason": "geometry" }, { "object": "LayoutTableCell TD", @@ -77,6 +112,51 @@ "reason": "geometry" }, { + "object": "LayoutTableCell TD", + "rect": [8, 802, 769, 48], + "reason": "geometry" + }, + { + "object": "InlineTextBox '10'", + "rect": [13, 822, 16, 19], + "reason": "geometry" + }, + { + "object": "InlineTextBox '13'", + "rect": [13, 802, 16, 19], + "reason": "geometry" + }, + { + "object": "InlineTextBox '12'", + "rect": [13, 742, 16, 19], + "reason": "geometry" + }, + { + "object": "InlineTextBox '10'", + "rect": [13, 622, 16, 19], + "reason": "geometry" + }, + { + "object": "InlineTextBox '11'", + "rect": [13, 682, 15, 19], + "reason": "geometry" + }, + { + "object": "InlineTextBox '9'", + "rect": [13, 762, 8, 19], + "reason": "geometry" + }, + { + "object": "InlineTextBox '8'", + "rect": [13, 702, 8, 19], + "reason": "geometry" + }, + { + "object": "InlineTextBox '7'", + "rect": [13, 642, 8, 19], + "reason": "geometry" + }, + { "object": "InlineTextBox '6'", "rect": [13, 582, 8, 19], "reason": "geometry" @@ -84,7 +164,7 @@ { "object": "InlineTextBox '9'", "rect": [13, 562, 8, 19], - "reason": "appeared" + "reason": "geometry" }, { "object": "InlineTextBox '5'", @@ -94,7 +174,7 @@ { "object": "InlineTextBox '8'", "rect": [13, 502, 8, 19], - "reason": "appeared" + "reason": "geometry" }, { "object": "InlineTextBox '4'", @@ -104,7 +184,7 @@ { "object": "InlineTextBox '7'", "rect": [13, 442, 8, 19], - "reason": "appeared" + "reason": "geometry" }, { "object": "InlineTextBox '3'",
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/window-resize/window-resize-vertical-writing-mode-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/window-resize/window-resize-vertical-writing-mode-expected.txt index 3492a63..4a78c7f 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/window-resize/window-resize-vertical-writing-mode-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/window-resize/window-resize-vertical-writing-mode-expected.txt
@@ -57,6 +57,26 @@ "reason": "appeared" }, { + "object": "InlineTextBox 'KKKK'", + "rect": [10, 8, 920, 212], + "reason": "appeared" + }, + { + "object": "InlineTextBox 'LLLL'", + "rect": [10, 8, 920, 212], + "reason": "appeared" + }, + { + "object": "InlineTextBox 'MMMM'", + "rect": [10, 8, 920, 212], + "reason": "appeared" + }, + { + "object": "InlineTextBox 'NNNN'", + "rect": [10, 8, 920, 212], + "reason": "appeared" + }, + { "object": "Scrolling background of LayoutView #document", "rect": [0, 0, 600, 235], "reason": "background" @@ -131,21 +151,6 @@ "object": "Scrolling background of LayoutView #document", "rect": [0, 0, 939, 235], "reason": "background" - }, - { - "object": "InlineTextBox 'GGGG'", - "rect": [10, 8, 920, 212], - "reason": "disappeared" - }, - { - "object": "InlineTextBox 'HHHH'", - "rect": [10, 8, 920, 212], - "reason": "disappeared" - }, - { - "object": "InlineTextBox 'IIII JJJJ'", - "rect": [10, 8, 920, 212], - "reason": "disappeared" } ], "transform": 1 @@ -224,6 +229,41 @@ "reason": "disappeared" }, { + "object": "InlineTextBox 'GGGG'", + "rect": [10, 8, 390, 212], + "reason": "disappeared" + }, + { + "object": "InlineTextBox 'HHHH'", + "rect": [10, 8, 390, 212], + "reason": "disappeared" + }, + { + "object": "InlineTextBox 'IIII JJJJ'", + "rect": [10, 8, 390, 212], + "reason": "disappeared" + }, + { + "object": "InlineTextBox 'KKKK'", + "rect": [10, 8, 390, 212], + "reason": "disappeared" + }, + { + "object": "InlineTextBox 'LLLL'", + "rect": [10, 8, 390, 212], + "reason": "disappeared" + }, + { + "object": "InlineTextBox 'MMMM'", + "rect": [10, 8, 390, 212], + "reason": "disappeared" + }, + { + "object": "InlineTextBox 'NNNN'", + "rect": [10, 8, 390, 212], + "reason": "disappeared" + }, + { "object": "InlineTextBox 'AAAA BBBB CCCC'", "rect": [39, 8, 352, 562], "reason": "appeared"
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/echo-iframe.html b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/echo-iframe.html new file mode 100644 index 0000000..68f685034 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/echo-iframe.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script> +addEventListener('message', evt => { + evt.source.postMessage(evt.data, '*', [evt.data]); +}); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/helpers.js b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/helpers.js new file mode 100644 index 0000000..20ca51f --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/helpers.js
@@ -0,0 +1,81 @@ +// Create a ReadableStream that will pass the tests in +// testTransferredReadableStream(), below. +function createOriginalReadableStream() { + return new ReadableStream({ + start(controller) { + controller.enqueue('a'); + controller.close(); + } + }); +} + +// Common tests to roughly determine that |rs| is a correctly transferred +// version of a stream created by createOriginalReadableStream(). +function testTransferredReadableStream(rs) { + assert_equals(rs.constructor, ReadableStream, + 'rs should be a ReadableStream in this realm'); + assert_true(rs instanceof ReadableStream, + 'instanceof check should pass'); + + // Perform a brand-check on |rs| in the process of calling getReader(). + const reader = ReadableStream.prototype.getReader.call(rs); + + return reader.read().then(({value, done}) => { + assert_false(done, 'done should be false'); + assert_equals(value, 'a', 'value should be "a"'); + return reader.read(); + }).then(({value, done}) => { + assert_true(done, 'done should be true'); + }); +} + +function testMessage(msg) { + assert_array_equals(msg.ports, [], 'there should be no ports in the event'); + return testTransferredReadableStream(msg.data); +} + +function testMessageEvent(target) { + return new Promise((resolve, reject) => { + target.addEventListener('message', ev => { + try { + resolve(testMessage(ev)); + } catch(e) { + reject(e); + } + }, {once: true}); + }); +} + +function testMessageEventOrErrorMessage(target) { + return new Promise((resolve, reject) => { + target.addEventListener('message', ev => { + if (typeof ev.data === 'string') { + // Assume it's an error message and reject with it. + reject(ev.data); + return; + } + + try { + resolve(testMessage(ev)); + } catch(e) { + reject(e); + } + }, {once: true}); + }); +} + +function checkTestResults(target) { + return new Promise((resolve, reject) => { + target.onmessage = msg => { + // testharness.js sends us objects which we need to ignore. + if (typeof msg.data !== 'string') + return; + + if (msg.data === 'OK') { + resolve(); + } else { + reject(msg.data); + } + }; + }); +}
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/receiving-shared-worker.js b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/receiving-shared-worker.js new file mode 100644 index 0000000..84f779c --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/receiving-shared-worker.js
@@ -0,0 +1,11 @@ +'use strict'; +importScripts('/resources/testharness.js', 'helpers.js'); + +onconnect = evt => { + const port = evt.source; + const promise = testMessageEvent(port); + port.start(); + promise + .then(() => port.postMessage('OK')) + .catch(err => port.postMessage(`BAD: ${err}`)); +};
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/receiving-worker.js b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/receiving-worker.js new file mode 100644 index 0000000..4ebb9c5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/receiving-worker.js
@@ -0,0 +1,7 @@ +'use strict'; +importScripts('/resources/testharness.js', 'helpers.js'); + +const promise = testMessageEvent(self); +promise + .then(() => postMessage('OK')) + .catch(err => postMessage(`BAD: ${err}`));
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/sending-shared-worker.js b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/sending-shared-worker.js new file mode 100644 index 0000000..e579077 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/sending-shared-worker.js
@@ -0,0 +1,12 @@ +'use strict'; +importScripts('helpers.js'); + +onconnect = msg => { + const port = msg.source; + const orig = createOriginalReadableStream(); + try { + port.postMessage(orig, [orig]); + } catch (e) { + port.postMessage(e.message); + } +};
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/sending-worker.js b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/sending-worker.js new file mode 100644 index 0000000..0b79733 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/sending-worker.js
@@ -0,0 +1,5 @@ +'use strict'; +importScripts('helpers.js'); + +const orig = createOriginalReadableStream(); +postMessage(orig, [orig]);
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/service-worker-iframe.html b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/service-worker-iframe.html new file mode 100644 index 0000000..348d067 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/service-worker-iframe.html
@@ -0,0 +1,39 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="helpers.js"></script> +<script> +'use strict'; + +setup({ + explicit_done: true +}); + +function startTests() { + promise_test(() => { + const orig = createOriginalReadableStream(); + const promise = checkTestResults(navigator.serviceWorker); + navigator.serviceWorker.controller.postMessage(orig, [orig]); + assert_true(orig.locked, 'the original stream should be locked'); + return promise; + }, 'serviceWorker.controller.postMessage should be able to transfer a ' + + 'ReadableStream'); + + promise_test(() => { + const promise = testMessageEventOrErrorMessage(navigator.serviceWorker); + navigator.serviceWorker.controller.postMessage('SEND'); + return promise; + }, 'postMessage in a service worker should be able to transfer ReadableStream'); + + done(); +} + +// Delay running the tests until we get a message from the page telling us to. +// This is to work around an issue where testharness.js doesn't detect +// completion of the tests if they fail too early. +onmessage = msg => { + if (msg.data === 'explicit trigger') + startTests(); +}; + +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/service-worker.js b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/service-worker.js new file mode 100644 index 0000000..af76b6c1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/resources/service-worker.js
@@ -0,0 +1,30 @@ +'use strict'; +importScripts('/resources/testharness.js', 'helpers.js'); + +onmessage = msg => { + const client = msg.source; + if (msg.data === 'SEND') { + sendingTest(client); + } else { + receivingTest(msg, client); + } +}; + +function sendingTest(client) { + const orig = createOriginalReadableStream(); + try { + client.postMessage(orig, [orig]); + } catch (e) { + client.postMessage(e.message); + } +} + +function receivingTest(msg, client) { + try { + msg.waitUntil(testMessage(msg) + .then(() => client.postMessage('OK')) + .catch(e => client.postMessage(`BAD: ${e}`))); + } catch (e) { + client.postMessage(`BAD: ${e}`); + } +}
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/service-worker-expected.txt new file mode 100644 index 0000000..59e0c13 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/service-worker-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS service-worker +FAIL serviceWorker.controller.postMessage should be able to transfer a ReadableStream Failed to execute 'postMessage' on 'ServiceWorker': Value at index 0 does not have a transferable type. +FAIL postMessage in a service worker should be able to transfer ReadableStream promise_test: Unhandled rejection with value: "Failed to execute 'postMessage' on 'Client': Value at index 0 does not have a transferable type." +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/service-worker.html b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/service-worker.html new file mode 100644 index 0000000..5c94a56 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/service-worker.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/serviceworker/resources/test-helpers.js"></script> +<script> +'use strict'; + +const kServiceWorkerUrl = 'resources/service-worker.js'; +const kIframeUrl = 'resources/service-worker-iframe.html'; + +// A dummy test so that we can use the test-helpers.js functions +const test = async_test('service-worker'); + +function registerAndStart() { + return service_worker_unregister_and_register( + test, kServiceWorkerUrl, kIframeUrl) + .then(reg => wait_for_state(test, reg.installing, 'activated')) + .then(() => with_iframe(kIframeUrl, { auto_remove: true })) + .then(iframe => { + fetch_tests_from_window(iframe.contentWindow); + iframe.contentWindow.postMessage('explicit trigger', '*'); + return service_worker_unregister_and_done(test, kIframeUrl); + }); +} + +onload = registerAndStart; + +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/shared-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/shared-worker-expected.txt new file mode 100644 index 0000000..98f462dd --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/shared-worker-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +FAIL worker.postMessage should be able to transfer a ReadableStream Failed to execute 'postMessage' on 'MessagePort': Value at index 0 does not have a transferable type. +FAIL postMessage in a worker should be able to transfer a ReadableStream promise_test: Unhandled rejection with value: "Failed to execute 'postMessage' on 'MessagePort': Value at index 0 does not have a transferable type." +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/shared-worker.html b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/shared-worker.html new file mode 100644 index 0000000..cd04154 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/shared-worker.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/helpers.js"></script> +<script> +'use strict'; + +promise_test(t => { + const orig = createOriginalReadableStream(); + const w = new SharedWorker('resources/receiving-shared-worker.js'); + const promise = checkTestResults(w.port); + w.port.postMessage(orig, [orig]); + assert_true(orig.locked, 'the original stream should be locked'); + return promise; +}, 'worker.postMessage should be able to transfer a ReadableStream'); + +promise_test(t => { + const w = new SharedWorker('resources/sending-shared-worker.js'); + const promise = testMessageEventOrErrorMessage(w.port); + w.port.start(); + return promise; +}, 'postMessage in a worker should be able to transfer a ReadableStream'); + +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/window-expected.txt b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/window-expected.txt new file mode 100644 index 0000000..a60f534 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/window-expected.txt
@@ -0,0 +1,10 @@ +CONSOLE ERROR: line 43: Uncaught (in promise) Error: assert_array_equals: there should be no ports in the event lengths differ, expected 0 got 1 +CONSOLE ERROR: line 43: Uncaught (in promise) Error: assert_array_equals: there should be no ports in the event lengths differ, expected 0 got 1 +This is a testharness.js-based test. +Harness Error. harness_status.status = 1 , harness_status.message = assert_array_equals: there should be no ports in the event lengths differ, expected 0 got 1 +FAIL window.postMessage should be able to transfer a ReadableStream Failed to execute 'postMessage' on 'Window': Value at index 0 does not have a transferable type. +FAIL port.postMessage should be able to transfer a ReadableStream Failed to execute 'postMessage' on 'MessagePort': Value at index 0 does not have a transferable type. +FAIL the same ReadableStream posted multiple times should arrive together Failed to execute 'postMessage' on 'Window': Value at index 0 does not have a transferable type. +FAIL transfer to and from an iframe should work promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'postMessage' on 'Window': Value at index 0 does not have a transferable type." +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/window.html b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/window.html new file mode 100644 index 0000000..beaf548 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/window.html
@@ -0,0 +1,60 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/helpers.js"></script> +<script> +'use strict'; + +promise_test(t => { + const orig = createOriginalReadableStream(); + const promise = testMessageEvent(window); + postMessage(orig, '*', [orig]); + assert_true(orig.locked, 'the original stream should be locked'); + return promise; +}, 'window.postMessage should be able to transfer a ReadableStream'); + +promise_test(t => { + const orig = createOriginalReadableStream(); + const promise = new Promise(resolve => { + window.addEventListener('message', msg => { + const port = msg.data; + resolve(testMessageEvent(port)); + port.start(); + }, {once: true}); + }); + const mc = new MessageChannel(); + postMessage(mc.port1, '*', [mc.port1]); + mc.port2.postMessage(orig, [orig]); + mc.port2.close(); + assert_true(orig.locked, 'the original stream should be locked'); + return promise; +}, 'port.postMessage should be able to transfer a ReadableStream'); + +promise_test(t => { + const orig = createOriginalReadableStream(); + const promise = new Promise(resolve => { + addEventListener('message', t.step_func(evt => { + const [rs1, rs2] = evt.data; + assert_equals(rs1, rs2, 'both ReadableStreams should be the same object'); + resolve(); + }), {once: true}); + }); + postMessage([orig, orig], '*', [orig]); + return promise; +}, 'the same ReadableStream posted multiple times should arrive together'); + +const onloadPromise = new Promise(resolve => onload = resolve); + +promise_test(() => { + const orig = createOriginalReadableStream(); + const promise = testMessageEvent(window); + return onloadPromise.then(() => { + const echoIframe = document.querySelector('#echo'); + echoIframe.contentWindow.postMessage(orig, '*', [orig]); + return promise; + }); +}, 'transfer to and from an iframe should work'); +</script> + +<iframe id=echo src="resources/echo-iframe.html" style="display:none"></iframe>
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/worker-expected.txt new file mode 100644 index 0000000..5db3b14 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/worker-expected.txt
@@ -0,0 +1,6 @@ +CONSOLE ERROR: line 5: Uncaught TypeError: Failed to execute 'postMessage' on 'DedicatedWorkerGlobalScope': Value at index 0 does not have a transferable type. +This is a testharness.js-based test. +FAIL worker.postMessage should be able to transfer a ReadableStream Failed to execute 'postMessage' on 'Worker': Value at index 0 does not have a transferable type. +FAIL postMessage in a worker should be able to transfer a ReadableStream promise_test: Unhandled rejection with value: "error in worker" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/transferable/worker.html b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/worker.html new file mode 100644 index 0000000..9c9c8151 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/streams/transferable/worker.html
@@ -0,0 +1,35 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/helpers.js"></script> +<script> +'use strict'; + +promise_test(t => { + const orig = createOriginalReadableStream(); + const w = new Worker('resources/receiving-worker.js'); + t.add_cleanup(() => { + w.terminate(); + }); + const promise = new Promise((resolve, reject) => { + checkTestResults(w).then(resolve, reject); + w.onerror = () => reject('error in worker'); + }); + w.postMessage(orig, [orig]); + assert_true(orig.locked, 'the original stream should be locked'); + return promise; +}, 'worker.postMessage should be able to transfer a ReadableStream'); + +promise_test(t => { + const w = new Worker('resources/sending-worker.js'); + t.add_cleanup(() => { + w.terminate(); + }); + return new Promise((resolve, reject) => { + testMessageEvent(w).then(resolve, reject); + w.onerror = () => reject('error in worker'); + }); +}, 'postMessage in a worker should be able to transfer a ReadableStream'); + +</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/README.txt b/third_party/WebKit/LayoutTests/virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/README.txt deleted file mode 100644 index 2d32b16..0000000 --- a/third_party/WebKit/LayoutTests/virtual/off-main-thread-worker-script-fetch/external/wpt/referrer-policy/README.txt +++ /dev/null
@@ -1,2 +0,0 @@ -This directory is for testing off-the-main-thread top-level worker classic -script loading. See https://crbug.com/835717.
diff --git a/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/README.txt b/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/README.txt new file mode 100644 index 0000000..75ea5fe5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/README.txt
@@ -0,0 +1 @@ +Run the transferable streams tests with the feature enabled.
diff --git a/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/service-worker-expected.txt new file mode 100644 index 0000000..29b0b8cc --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/service-worker-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +PASS service-worker +PASS serviceWorker.controller.postMessage should be able to transfer a ReadableStream +PASS postMessage in a service worker should be able to transfer ReadableStream +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/shared-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/shared-worker-expected.txt new file mode 100644 index 0000000..708a2c8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/shared-worker-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS worker.postMessage should be able to transfer a ReadableStream +PASS postMessage in a worker should be able to transfer a ReadableStream +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/window-expected.txt b/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/window-expected.txt new file mode 100644 index 0000000..a7c252b --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/window-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +PASS window.postMessage should be able to transfer a ReadableStream +PASS port.postMessage should be able to transfer a ReadableStream +PASS the same ReadableStream posted multiple times should arrive together +PASS transfer to and from an iframe should work +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/worker-expected.txt new file mode 100644 index 0000000..708a2c8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/transferable-streams/http/tests/streams/transferable/worker-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS worker.postMessage should be able to transfer a ReadableStream +PASS postMessage in a worker should be able to transfer a ReadableStream +Harness: the test ran to completion. +
diff --git a/third_party/android_build_tools/bundletool/README.chromium b/third_party/android_build_tools/bundletool/README.chromium index 9cae0aff..5b33901 100644 --- a/third_party/android_build_tools/bundletool/README.chromium +++ b/third_party/android_build_tools/bundletool/README.chromium
@@ -1,6 +1,6 @@ Name: Android SDK bundletool Short Name: bundletool -Version: 0.6.2 +Version: 0.7.1 License: Apache Version 2.0 License File: NOT_SHIPPED Security Critical: No
diff --git a/third_party/android_build_tools/bundletool/cipd.yaml b/third_party/android_build_tools/bundletool/cipd.yaml index 2d6e626a..4da0986 100644 --- a/third_party/android_build_tools/bundletool/cipd.yaml +++ b/third_party/android_build_tools/bundletool/cipd.yaml
@@ -5,10 +5,10 @@ # Remember to increment the versions for the commands in this comment block. # Before creating a new CIPD package run the following to make sure the tag you # are adding does not already exist (otherwise you break the build): -# cipd describe chromium/third_party/android_tools_bundletool -version "version:0.6.2-cr0" +# cipd describe chromium/third_party/android_tools_bundletool -version "version:0.7.1-cr0" # To create CIPD package run the following command. -# cipd create --pkg-def cipd.yaml -tag version:0.6.2-cr0 +# cipd create --pkg-def cipd.yaml -tag version:0.7.1-cr0 package: chromium/third_party/android_tools_bundletool description: Android SDK tool to manage App Bundles data: - - file: bundletool-all-0.6.2.jar + - file: bundletool-all-0.7.1.jar
diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.gn index d7d99d5..8aec5e9c 100644 --- a/third_party/android_deps/BUILD.gn +++ b/third_party/android_deps/BUILD.gn
@@ -559,6 +559,12 @@ ] } +java_prebuilt("com_google_protobuf_protobuf_lite_java") { + jar_path = "libs/com_google_protobuf_protobuf_lite/protobuf-lite-3.0.1.jar" + output_name = "com_google_protobuf_protobuf_lite" + supports_android = true +} + java_prebuilt("com_squareup_javapoet_java") { jar_path = "libs/com_squareup_javapoet/javapoet-1.11.0.jar" output_name = "com_squareup_javapoet"
diff --git a/third_party/android_deps/additional_readme_paths.json b/third_party/android_deps/additional_readme_paths.json index fcbfb0a..9dc6610f 100644 --- a/third_party/android_deps/additional_readme_paths.json +++ b/third_party/android_deps/additional_readme_paths.json
@@ -55,6 +55,7 @@ "libs/com_google_googlejavaformat_google_java_format", "libs/com_google_guava_guava", "libs/com_google_j2objc_j2objc_annotations", + "libs/com_google_protobuf_protobuf_lite", "libs/com_squareup_javapoet", "libs/javax_annotation_jsr250_api", "libs/javax_inject_javax_inject",
diff --git a/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/LICENSE b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/LICENSE new file mode 100644 index 0000000..19b305b0 --- /dev/null +++ b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/LICENSE
@@ -0,0 +1,32 @@ +Copyright 2008 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Code generated by the Protocol Buffer compiler is owned by the owner +of the input file used when generating it. This code is not +standalone and requires a support library to be linked with it. This +support library is itself covered by the above license.
diff --git a/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/OWNERS b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/OWNERS new file mode 100644 index 0000000..7b571d97 --- /dev/null +++ b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/OWNERS
@@ -0,0 +1 @@ +file://third_party/android_deps/OWNERS \ No newline at end of file
diff --git a/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/README.chromium b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/README.chromium new file mode 100644 index 0000000..11d48fb2 --- /dev/null +++ b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/README.chromium
@@ -0,0 +1,13 @@ +Name: Protocol Buffers [Lite] +Short Name: protobuf-lite +URL: https://github.com/protocolbuffers/protobuf/blob/master/java/lite.md +Version: 3.0.1 +License: BSD +License File: LICENSE +Security Critical: yes + +Description: +A trimmed-down version of the Protocol Buffers library. + +Local Modifications: +No modifications.
diff --git a/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/cipd.yaml b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/cipd.yaml new file mode 100644 index 0000000..6e75f658 --- /dev/null +++ b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/cipd.yaml
@@ -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. + +# To create CIPD package run the following command. +# cipd create --pkg-def cipd.yaml -tag version:3.0.1-cr0 +package: chromium/third_party/android_deps/libs/com_google_protobuf_protobuf_lite +description: "Protocol Buffers [Lite]" +data: +- file: protobuf-lite-3.0.1.jar
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 53457e69..68a01f0 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -107,6 +107,12 @@ const base::Feature kRTCUnifiedPlanByDefault{"RTCUnifiedPlanByDefault", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables the site isolated Wasm code cache that is keyed on the resource URL +// and the origin lock of the renderer that is requesting the resource. When +// this flag is enabled, content/GeneratedCodeCache handles code cache requests. +const base::Feature kWasmCodeCache = {"WasmCodeCache", + base::FEATURE_DISABLED_BY_DEFAULT}; + const char kAutofillPreviewStyleExperimentBgColorParameterName[] = "bg_color"; const char kAutofillPreviewStyleExperimentColorParameterName[] = "color";
diff --git a/third_party/blink/common/messaging/transferable_message_struct_traits.cc b/third_party/blink/common/messaging/transferable_message_struct_traits.cc index 5652c5b..5100fa0 100644 --- a/third_party/blink/common/messaging/transferable_message_struct_traits.cc +++ b/third_party/blink/common/messaging/transferable_message_struct_traits.cc
@@ -14,15 +14,18 @@ Read(blink::mojom::TransferableMessage::DataView data, blink::TransferableMessage* out) { std::vector<mojo::ScopedMessagePipeHandle> ports; + std::vector<mojo::ScopedMessagePipeHandle> stream_channels; if (!data.ReadMessage(static_cast<blink::CloneableMessage*>(out)) || !data.ReadArrayBufferContentsArray(&out->array_buffer_contents_array) || !data.ReadImageBitmapContentsArray(&out->image_bitmap_contents_array) || - !data.ReadPorts(&ports) || + !data.ReadPorts(&ports) || !data.ReadStreamChannels(&stream_channels) || !data.ReadUserActivation(&out->user_activation)) { return false; } out->ports = blink::MessagePortChannel::CreateFromHandles(std::move(ports)); + out->stream_channels = + blink::MessagePortChannel::CreateFromHandles(std::move(stream_channels)); out->has_user_gesture = data.has_user_gesture(); return true; }
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn index 393dee4e..6071b57 100644 --- a/third_party/blink/public/common/BUILD.gn +++ b/third_party/blink/public/common/BUILD.gn
@@ -112,6 +112,10 @@ deps += [ ":font_unique_name_table_proto" ] } + if (is_mac) { + sources += [ "sandbox_support/sandbox_support_mac.h" ] + } + if (is_win) { sources += [ "dwrite_rasterizer_support/dwrite_rasterizer_support.h" ] }
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index 2074b09..1e1c9fa 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -34,6 +34,7 @@ BLINK_COMMON_EXPORT extern const base::Feature kMixedContentAutoupgrade; BLINK_COMMON_EXPORT extern const base::Feature kJankTracking; BLINK_COMMON_EXPORT extern const base::Feature kRTCUnifiedPlanByDefault; +BLINK_COMMON_EXPORT extern const base::Feature kWasmCodeCache; BLINK_COMMON_EXPORT extern const char kAutofillPreviewStyleExperimentBgColorParameterName[];
diff --git a/third_party/blink/public/common/messaging/transferable_message.h b/third_party/blink/public/common/messaging/transferable_message.h index 78a3e2bb..e58a41ae 100644 --- a/third_party/blink/public/common/messaging/transferable_message.h +++ b/third_party/blink/public/common/messaging/transferable_message.h
@@ -28,6 +28,8 @@ // Any ports being transferred as part of this message. std::vector<MessagePortChannel> ports; + // Channels used by transferred WHATWG streams (eg. ReadableStream). + std::vector<MessagePortChannel> stream_channels; // The contents of any ArrayBuffers being transferred as part of this message. std::vector<mojom::SerializedArrayBufferContentsPtr> array_buffer_contents_array;
diff --git a/third_party/blink/public/common/messaging/transferable_message_struct_traits.h b/third_party/blink/public/common/messaging/transferable_message_struct_traits.h index ca5d718..a6ad220d 100644 --- a/third_party/blink/public/common/messaging/transferable_message_struct_traits.h +++ b/third_party/blink/public/common/messaging/transferable_message_struct_traits.h
@@ -26,6 +26,11 @@ return blink::MessagePortChannel::ReleaseHandles(input.ports); } + static std::vector<mojo::ScopedMessagePipeHandle> stream_channels( + blink::TransferableMessage& input) { + return blink::MessagePortChannel::ReleaseHandles(input.stream_channels); + } + static std::vector<blink::mojom::SerializedArrayBufferContentsPtr> array_buffer_contents_array(blink::TransferableMessage& input) { return std::move(input.array_buffer_contents_array);
diff --git a/third_party/blink/public/common/sandbox_support/sandbox_support_mac.h b/third_party/blink/public/common/sandbox_support/sandbox_support_mac.h new file mode 100644 index 0000000..9123cce --- /dev/null +++ b/third_party/blink/public/common/sandbox_support/sandbox_support_mac.h
@@ -0,0 +1,43 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_SANDBOX_SUPPORT_SANDBOX_SUPPORT_MAC_H_ +#define THIRD_PARTY_BLINK_PUBLIC_COMMON_SANDBOX_SUPPORT_SANDBOX_SUPPORT_MAC_H_ + +namespace blink { + +// Named Mac system colors. Each of these corresponds to a selector on +// NSColor. +enum class MacSystemColorID { + kAlternateSelectedControl, + kControlBackground, + kControlDarkShadow, + kControlHighlight, + kControlLightHighlight, + kControlShadow, + kControlText, + kDisabledControlText, + kHeader, + kHighlight, + kKeyboardFocusIndicator, + kMenuBackground, + kScrollBar, + kSecondarySelectedControl, + kSelectedMenuItemText, + kSelectedText, + kSelectedTextBackground, + kShadow, + kText, + kWindowBackground, + kWindowFrame, + kWindowFrameText, + kCount, +}; + +constexpr size_t kMacSystemColorIDCount = + static_cast<size_t>(MacSystemColorID::kCount); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_SANDBOX_SUPPORT_SANDBOX_SUPPORT_MAC_H_
diff --git a/third_party/blink/public/mojom/messaging/transferable_message.mojom b/third_party/blink/public/mojom/messaging/transferable_message.mojom index f660019..e382d4e 100644 --- a/third_party/blink/public/mojom/messaging/transferable_message.mojom +++ b/third_party/blink/public/mojom/messaging/transferable_message.mojom
@@ -24,6 +24,8 @@ CloneableMessage message; // Any ports being transferred as part of this message. array<handle<message_pipe>> ports; + // Channels used to transfer WHATWG streams (eg. ReadableStream). + array<handle<message_pipe>> stream_channels; // Any ArrayBuffers being transferred as part of this message. array<SerializedArrayBufferContents> array_buffer_contents_array; // Any ImageBitmaps being transferred as part of this message.
diff --git a/third_party/blink/public/platform/mac/web_sandbox_support.h b/third_party/blink/public/platform/mac/web_sandbox_support.h index a2b67d5..4e1b27e2 100644 --- a/third_party/blink/public/platform/mac/web_sandbox_support.h +++ b/third_party/blink/public/platform/mac/web_sandbox_support.h
@@ -31,6 +31,9 @@ #ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MAC_WEB_SANDBOX_SUPPORT_H_ #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MAC_WEB_SANDBOX_SUPPORT_H_ +#include "third_party/blink/public/common/sandbox_support/sandbox_support_mac.h" +#include "third_party/skia/include/core/SkColor.h" + typedef struct CGFont* CGFontRef; namespace blink { @@ -52,6 +55,9 @@ virtual bool LoadFont(CTFontRef src_font, CGFontRef* out, uint32_t* font_id) = 0; + + // Returns the system's preferred value for a named color. + virtual SkColor GetSystemColor(MacSystemColorID) = 0; }; } // namespace blink
diff --git a/third_party/blink/public/platform/web_coalesced_input_event.h b/third_party/blink/public/platform/web_coalesced_input_event.h index e1bb3935..33785c7 100644 --- a/third_party/blink/public/platform/web_coalesced_input_event.h +++ b/third_party/blink/public/platform/web_coalesced_input_event.h
@@ -42,8 +42,6 @@ std::vector<const WebInputEvent*> GetPredictedEventsPointers() const; private: - // TODO(hans): Remove this once clang-cl knows to not inline dtors that - // call operator(), https://crbug.com/691714 struct BLINK_PLATFORM_EXPORT WebInputEventDeleter { void operator()(blink::WebInputEvent*) const; };
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index f76b0ffe..dfedb53f 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -91,6 +91,7 @@ BLINK_PLATFORM_EXPORT static void EnableBloatedRendererDetection(bool); BLINK_PLATFORM_EXPORT static void EnableCacheInlineScriptCode(bool); BLINK_PLATFORM_EXPORT static void EnableIsolatedCodeCache(bool); + BLINK_PLATFORM_EXPORT static void EnableWasmCodeCache(bool); BLINK_PLATFORM_EXPORT static void EnableCanvas2dImageChromium(bool); BLINK_PLATFORM_EXPORT static void EnableCSSHexAlphaColor(bool); BLINK_PLATFORM_EXPORT static void EnableCSSFragmentIdentifiers(bool);
diff --git a/third_party/blink/renderer/bindings/IDLExtendedAttributes.md b/third_party/blink/renderer/bindings/IDLExtendedAttributes.md index d14e324a..5e3fe1b 100644 --- a/third_party/blink/renderer/bindings/IDLExtendedAttributes.md +++ b/third_party/blink/renderer/bindings/IDLExtendedAttributes.md
@@ -20,7 +20,7 @@ Semantically, only certain extended attributes allow lists. Similarly, only certain extended attributes allow string literals. Extended attributes either take no value, take a required value, or take an optional value. -In the following explanations, _(i)_, _(m)_, _(s)_, _(a)_, _(p)_, _(c)_, _(d)_, and _(f)_ mean that a given extended attribute can be specified on interfaces, methods, special operations, attributes, parameters, constants, dictionaries, and callback functions respectively. For example, _(a,p)_ means that the IDL attribute can be specified on attributes and parameters. +In the following explanations, _(i)_, _(m)_, _(s)_, _(a)_, _(p)_, _(c)_, _(d)_, _(f)_, and _(t)_ mean that a given extended attribute can be specified on interfaces, methods, special operations, attributes, parameters, constants, dictionaries, callback functions, and types respectively. For example, _(a,p)_ means that the IDL attribute can be specified on attributes and parameters. *** note These restrictions are not enforced by the parser: extended attributes used in unsupported contexts will simply be ignored. @@ -155,23 +155,21 @@ Note that `blink::CEReactionsScope` must be constructed after `blink::ExceptionState`. -### [Clamp] _(a, p)_ +### [Clamp] _(t)_ Standard: [Clamp](https://heycam.github.io/webidl/#Clamp) Summary: `[Clamp]` indicates that when an ECMAScript Number is converted to the IDL type, out of range values will be clamped to the range of valid values, rather than using the operators that use a modulo operation (ToInt32, ToUint32, etc.). -Usage: The `[Clamp]` extended attribute MUST NOT appear on a read only attribute, or an attribute, operation argument or dictionary member that is not of an integer type. - -`[Clamp]` can be specified on writable attributes: +Usage: The `[Clamp]` extended attribute MUST appear on an integer type. ```webidl interface XXX { - [Clamp] attribute unsigned short attributeName; + attribute [Clamp] unsigned short attributeName; }; ``` -`[Clamp]` can be specified on extended attributes or methods arguments: +Annotated type with `[Clamp]` can be specified on extended attributes or methods arguments: ```webidl interface GraphicsContext { @@ -198,7 +196,7 @@ ```webidl [ - Constructor(float x, float y, DOMString str), + Constructor(float x, float y, DOMString str) ] interface XXX { ... @@ -214,8 +212,7 @@ The Blink implementation must have the following method as a constructor callback: ```c++ -scoped_refptr<XXX> XXX::create(float x, float y, String str) -{ +XXX* XXX::Create(float x, float y, const String& str) { ...; } ``` @@ -228,23 +225,21 @@ Currently `[Constructor(...)]` does not yet support optional arguments w/o defaults. It just supports optional `[Default=Undefined]`. *** -### [EnforceRange] _(a, p)_ +### [EnforceRange] _(t)_ Standard: [EnforceRange](https://heycam.github.io/webidl/#EnforceRange) Summary: `[EnforceRange]` indicates that when an ECMAScript Number is converted to the IDL type, out of range values will result in a TypeError exception being thrown. -Usage: The `[EnforceRange]` extended attribute MUST NOT appear on a read only attribute, or an attribute, operation argument or dictionary member that is not of an integer type. - -`[EnforceRange]` can be specified on writable attributes: +Usage: The `[EnforceRange]` extended attribute MUST appear on an integer type. ```webidl interface XXX { - [EnforceRange] attribute unsigned short attributeName; + attribute [EnforceRange] unsigned short attributeName; }; ``` -`[EnforceRange]` can be specified on extended attributes on methods arguments: +Annotated type with `[EnforceRange]` can be specified on extended attributes on methods arguments: ```webidl interface GraphicsContext { @@ -281,13 +276,13 @@ ```webidl [ - Exposed=DedicatedWorker, + Exposed=DedicatedWorker ] interface XXX { ... }; [ - Exposed=(Window,Worker), + Exposed=(Window,Worker) ] interface YYY { ... }; @@ -385,7 +380,7 @@ ```webidl [ - NoInterfaceObject, + NoInterfaceObject ] interface XXX { ... }; @@ -395,7 +390,7 @@ ```webidl [ - NoInterfaceObject, // testing interfaces do not appear on global objects + NoInterfaceObject // testing interfaces do not appear on global objects ] interface TestingInterfaceX { ... }; @@ -442,21 +437,21 @@ Specifically, a writable attribute, without `[Replaceable]`, behaves as follows: ```js -window.screenX; // Evaluates to 0 +window.screenX; // Evaluates to 0 window.screenX = "foo"; -window.screenX; // Evaluates to "foo" +window.screenX; // Evaluates to "foo" delete window.screenX; -window.screenX; // Evaluates to undefined. 0 is lost. +window.screenX; // Evaluates to undefined. 0 is lost. ``` A read only attribute, with `[Replaceable]`, behaves as follows: ```js -window.screenX; // Evaluates to 0 +window.screenX; // Evaluates to 0 window.screenX = "foo"; -window.screenX; // Evaluates to "foo" +window.screenX; // Evaluates to "foo" delete window.screenX; -window.screenX; // Evaluates to 0. 0 remains. +window.screenX; // Evaluates to 0. 0 remains. ``` Whether `[Replaceable]` should be specified or not depends on the spec of each attribute. @@ -515,16 +510,16 @@ This attribute has no effect on code generation and should simply be used in Blink IDL files if the specification uses it. Code to perform the transfer steps must be added to `V8ScriptValueSerializer` for types in `core/` or `V8ScriptValueDeserializerForModules` for types in `modules/`. -### [TreatNullAs] _(a,p)_ +### [TreatNullAs] _(t)_ Standard: [TreatNullAs](https://heycam.github.io/webidl/#TreatNullAs) Summary: `[TreatNullAs=EmptyString]` indicates that a JavaScript null is converted to `""` instead of `"null"`. -Usage: Can be specified on DOMString attributes or DOMString parameters only: +Usage: `[TreatNullAs=EmptyString]` must be specified on a DOMString type. ```webidl -[TreatNullAs=EmptyString] attribute DOMString str; +attribute [TreatNullAs=EmptyString] DOMString str; void func([TreatNullAs=Emptytring] DOMString str); ``` @@ -567,7 +562,7 @@ ```webidl [ - ActiveScriptWrappable, + ActiveScriptWrappable ] interface Foo { ... }; @@ -577,7 +572,7 @@ ```webidl [ - ActiveScriptWrappable, + ActiveScriptWrappable ] interface Foo {}; interface Bar : Foo {}; // inherits [ActiveScriptWrappable] from Foo @@ -588,10 +583,9 @@ If you use `[ActiveScriptWrappable]`, the corresponding Blink class needs to inherit ActiveScriptWrappable and override hasPendingActivity(). For example, in case of XMLHttpRequest, core/xml/XMLHttpRequest.h would look like this: ```c++ -class XMLHttpRequest : public ActiveScriptWrappable<XMLHttpRequest> -{ - // Returns true if the object needs to be kept alive. - bool hasPendingActivity() const override { return ...; } +class XMLHttpRequest : public ActiveScriptWrappable<XMLHttpRequest> { + // Returns true if the object needs to be kept alive. + bool HasPendingActivity() const override { return ...; } } ``` @@ -686,12 +680,12 @@ #### [CallWith=ThisValue] _(m)_ -`[CallWith=ThisValue]` only applies to methods in callback interfaces, and is used in only one place (CSSVariablesMapForEachCallback.idl). +`[CallWith=ThisValue]` is used in only one place (location.idl). IDL example: ```webidl -callback interface Example { +interface Example { [CallWith=ThisValue] boolean func(boolean a, boolean b); }; ``` @@ -703,7 +697,7 @@ ``` *** note -`[CallWith=...]` arguments are added at the _head_ of `XXX::create(...)'s` arguments, and ` [RaisesException]`'s `ExceptionState` argument is added at the _tail_ of `XXX::create(...)`'s arguments. +`[CallWith=...]` arguments are added at the _head_ of `XXX::Create(...)'s` arguments, and ` [RaisesException]`'s `ExceptionState` argument is added at the _tail_ of `XXX::Create(...)`'s arguments. *** #### [ConstructorCallWith] _(i)_ @@ -715,23 +709,18 @@ ```webidl [ Constructor(float x, float y, DOMString str), - ConstructorCallWith=ExecutionContext, + ConstructorCallWith=ExecutionContext ] interface XXX { ... }; ``` -Then XXX::create(...) can have the following signature - -*** note -**FIXME:** outdated -*** +Then XXX::Create(...) can have the following signature ```c++ -scoped_refptr<XXX> XXX::create(ExecutionContext* context, float x, float y, String str) -{ - ...; +XXX* XXX::Create(ExecutionContext* context, float x, float y, const String& str) { + ...; } ``` @@ -754,7 +743,7 @@ ] interface Mojo { ... }; ``` -When applied to an interface, the generated code for the relevant global object will include a public `installFeatureName()` method which can be called to install the interface on the global object. +When applied to an interface, the generated code for the relevant global object will include a public `InstallFeatureName()` method which can be called to install the interface on the global object. Note that `[ContextEnabled]` is not mututally exclusive to `[RuntimeEnabled]`, and a feature which may be enabled by either mechanism will be enabled if the appropriate `[RuntimeEnabled]` feature is enabled; _or_ if the appropriate `[ContextEnabled]` feature is enabled; _or_ if both are enabled. @@ -790,22 +779,20 @@ ```webidl interface XXX { - [Custom] void func(); - [Custom=CallEpilogue] void func2(); + [Custom] void func(); + [Custom=CallEpilogue] void func2(); }; ``` -You can write custom bindings in Source/bindings/v8/custom/V8XXXCustom.cpp: +You can write custom bindings in third_party/blink/renderer/bindings/{core,modules}/v8/custom/v8_xxx_custom.cc: ```c++ -void V8XXX::funcMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) -{ - ...; +void V8XXX::FuncMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) { + ...; } -void V8XXX::func2MethodEpilogueCustom(const v8::FunctionCallbackInfo<v8::Value>& info, V8XXX* impl) -{ - ...; +void V8XXX::Func2MethodEpilogueCustom(const v8::FunctionCallbackInfo<v8::Value>& info, V8XXX* impl) { + ...; } ``` @@ -820,9 +807,8 @@ You can write custom bindings in Source/bindings/v8/custom/V8XXXCustom.cpp: ```c++ -void V8XXX::strAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info) -{ - ...; +void V8XXX::StrAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info) { + ...; } ``` @@ -837,9 +823,8 @@ You can write custom bindings in Source/bindings/v8/custom/V8XXXCustom.cpp: ```c++ -void V8XXX::strAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info) -{ - ...; +void V8XXX::StrAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info) { + ...; } ``` @@ -897,18 +882,16 @@ You can write custom bindings as V8XXX::namedPropertyQuery(...) and V8XXX::namedPropertyEnumerator(...) in Source/bindings/v8/custom/V8XXXCustom.cpp: ```c++ -v8::Local<v8::Integer> V8XXX::namedPropertyQuery(v8::Local<v8::String> name, const v8::AccessorInfo& info) -{ - ...; +v8::Local<v8::Integer> V8XXX::NamedPropertyQuery(v8::Local<v8::String> name, const v8::AccessorInfo& info) { + ...; } -v8::Local<v8::Array> V8XXX::namedPropertyEnumerator(const v8::AccessorInfo& info) -{ - ...; +v8::Local<v8::Array> V8XXX::NamedPropertyEnumerator(const v8::AccessorInfo& info) { + ...; } ``` -#### [Custom=LegacyCallAsFunction] _(i) _deprecated_ +#### [Custom=LegacyCallAsFunction] _(i)_ _deprecated_ Summary: `[Custom=LegacyCallAsFunction]` allows you to write custom bindings for call(...) of a given interface. @@ -927,8 +910,7 @@ You can write custom `V8XXX::callAsFunctionCallback(...)` in Source/bindings/v8/custom/V8XXXCustom.cpp: ```c++ -v8::Local<v8::Value> V8XXX::callAsFunctionCallback(const v8::Arguments& args) -{ +v8::Local<v8::Value> V8XXX::CallAsFunctionCallback(const v8::Arguments& args) { ...; } ``` @@ -960,8 +942,8 @@ ```webidl interface HTMLFoo { - void func1(int a, int b, optional int c, optional int d); - void func2(int a, int b, [Default=Undefined] optional int c); + void func1(long a, long b, optional long c, optional long d); + void func2(long a, long b, [Default=Undefined] optional long c); }; ``` @@ -969,9 +951,9 @@ The difference between `optional` and `[Default=Undefined]` optional is whether the Blink implementation requires overloaded methods or not: without a default value, the Blink implementation must have overloaded C++ functions, while with a default value, the Blink implementation only needs a single C++ function. -In case of func1(...), if JavaScript calls func1(100, 200), then HTMLFoo::func1(int a, int b) is called in Blink. If JavaScript calls func1(100, 200, 300), then HTMLFoo::func1(int a, int b, int c) is called in Blink. If JavaScript calls func1(100, 200, 300, 400), then HTMLFoo::func1(int a, int b, int c, int d) is called in Blink. In other words, if the Blink implementation has overloaded methods, you can use `optional`. +In case of func1(...), if JavaScript calls func1(100, 200), then `HTMLFoo::func1(int a, int b)` is called in Blink. If JavaScript calls `func1(100, 200, 300)`, then `HTMLFoo::func1(int a, int b, int c)` is called in Blink. If JavaScript calls `func1(100, 200, 300, 400)`, then `HTMLFoo::func1(int a, int b, int c, int d)` is called in Blink. In other words, if the Blink implementation has overloaded methods, you can use `optional`. -In case of func2(...) which adds `[Default=Undefined]`, if JavaScript calls func2(100, 200), then it behaves as if JavaScript called func2(100, 200, undefined). Consequently, HTMLFoo::func2(int a, int b, int c) is called in Blink. 100 is passed to a, 200 is passed to b, and 0 is passed to c. (A JavaScript `undefined` is converted to 0, following the value conversion rule in the Web IDL spec; if it were a DOMString parameter, it would end up as the string `"undefined"`.) In this way, Blink needs to just implement func2(int a, int b, int c) and needs not to implement both func2(int a, int b) and func2(int a, int b, int c). +In case of func2(...) which adds `[Default=Undefined]`, if JavaScript calls `func2(100, 200)`, then it behaves as if JavaScript called `func2(100, 200, undefined)`. Consequently, `HTMLFoo::func2(int a, int b, int c)` is called in Blink. 100 is passed to `a`, 200 is passed to `b`, and 0 is passed to `c`. (A JavaScript `undefined` is converted to 0, following the value conversion rule in the Web IDL spec; if it were a DOMString parameter, it would end up as the string `"undefined"`.) In this way, Blink needs to just implement `func2(int a, int b, int c)` and needs not to implement both `func2(int a, int b)` and `func2(int a, int b, int c)`. ### [DeprecateAs] _(m, a, c)_ @@ -1024,12 +1006,6 @@ ### [NotEnumerable] _(m, a, s)_ -*** note -**FIXME:** docs out of date! -*** - -Specification: [The spec of Writable, Enumerable and Configurable (Section 8.6.1)](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf) - _not standard Web IDL extended attributes._ - Summary: Controls the enumerability of methods and attributes. Usage: `[NotEnumerable]` can be specified on methods and attributes @@ -1059,15 +1035,11 @@ For more information, see [RuntimeEnabledFeatures](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5) and [OriginTrialContext](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/blink/renderer/core/origin_trials/origin_trial_context.h). -*** note -**FIXME:** Currently, `[OriginTrialEnabled]` can only be applied to interfaces, attributes, and constants. Methods (including those generated by `iterable`, `setlike`, `maplike`, `serializer` and `stringifier`) are not supported. See [Bug 621641](https://crbug.com/621641). -*** - ### [RaisesException] _(i, m, a)_ Summary: Tells the code generator to append an `ExceptionState&` argument when calling the Blink implementation. -Implementations may use the methods on this parameter (e.g. `ExceptionState::throwDOMException`) to throw exceptions. +Implementations may use the methods on this parameter (e.g. `ExceptionState::ThrowDOMException`) to throw exceptions. Usage: `[RaisesException]` can be specified on methods and attributes, `[RaisesException=Getter]` and `[RaisesException=Setter]` can be specified on attributes, and `[RaisesException=Constructor]` can be specified on interfaces where `[Constructor]` is also specified. On methods and attributes, the IDL looks like: @@ -1083,32 +1055,32 @@ And the Blink implementations would look like: ```c++ -long XXX::count(ExceptionState& exceptionState) { - if (...) { - exceptionState.throwDOMException(TypeMismatchError, ...); - return; - } - ...; +long XXX::Count(ExceptionState& exception_state) { + if (...) { + exception_state.ThrowDOMException(TypeMismatchError, ...); + return; + } + ...; } -void XXX::setCount(long value, ExceptionState& exceptionState) { - if (...) { - exceptionState.throwDOMException(TypeMismatchError, ...); - return; - } - ...; +void XXX::SetCount(long value, ExceptionState& exception_state) { + if (...) { + exception_state.ThrowDOMException(TypeMismatchError, ...); + return; + } + ...; } -void XXX::foo(ExceptionState& exceptionState) { - if (...) { - exceptionState.throwDOMException(TypeMismatchError, ...); - return; - } - ...; +void XXX::foo(ExceptionState& exception_state) { + if (...) { + exception_state.ThrowDOMException(TypeMismatchError, ...); + return; + } + ...; }; ``` -If `[RaisesException=Constructor]` is specified on an interface and `[Constructor]` is also specified then an `ExceptionState&` argument is added when calling the `XXX::create(...)` constructor callback. +If `[RaisesException=Constructor]` is specified on an interface and `[Constructor]` is also specified then an `ExceptionState&` argument is added when calling the `XXX::Create(...)` constructor callback. ```webidl [ @@ -1123,14 +1095,13 @@ Blink needs to implement the following method as a constructor callback: ```c++ -scoped_refptr<XXX> XXX::create(float x, ExceptionState& exceptionState) -{ - ...; - if (...) { - exceptionState.throwDOMException(TypeMismatchError, ...); - return nullptr; - } - ...; +XXX* XXX::Create(float x, ExceptionState& exception_state) { + ...; + if (...) { + exception_state.ThrowDOMException(TypeMismatchError, ...); + return nullptr; + } + ...; } ``` @@ -1248,14 +1219,6 @@ Only when the feature is enabled at runtime (using a command line flag, for example, or when it is enabled only in certain platforms), the binding would be exposed to the web. -`[RuntimeEnabled]` _cannot_ be applied to arguments, as this changes signatures and method resolution and is both very confusing to reason about and implement. For example, what does it mean to mark a _required_ argument as `[RuntimeEnabled]`? You probably want to apply it only to optional arguments, which are equivalent to overloads. Thus instead apply `[RuntimeEnabled]` to the _method_, generally splitting a method in two. For example, instead of: - -```webidl -foo(long x, `[RuntimeEnabled=FeatureName]` optional long y); // Don't do this! -``` - -do: - ```webidl // Overload can be replaced with optional if `[RuntimeEnabled]` is removed foo(long x); @@ -1278,7 +1241,7 @@ Summary: For performance optimization, `[CachedAttribute]` indicates that a wrapped object should be cached on a DOM object. Rarely used. -Usage: `[CachedAttribute]` can be specified on attributes, and takes a required value, generally called is*Dirty (e.g. isValueDirty): +Usage: `[CachedAttribute]` can be specified on attributes, and takes a required value, generally called isXXXDirty (e.g. isValueDirty): ```webidl interface HTMLFoo { @@ -1325,23 +1288,20 @@ ```c++ // Called internally to update value -void Object::setValue(Type data) -{ - m_data = data; - m_attributeDirty = true; +void Object::SetValue(Type data) { + data_ = data; + attribute_dirty_ = true; } // Called by generated binding code -bool Object::isAttributeDirty() const -{ - return m_attributeDirty; +bool Object::IsAttributeDirty() const { + return attribute_dirty_; } -// Called by generated binding code if no value cached or isAttributeDirty() returns true -ScriptValue Object::attribute(ExecutionContext* context) -{ - m_attributeDirty = false; - return convertDataToScriptValue(m_data); +// Called by generated binding code if no value cached or IsAttributeDirty() returns true +ScriptValue Object::attribute(ExecutionContext* context) { + attribute_dirty_ = false; + return ConvertDataToScriptValue(data_); } ``` @@ -1363,7 +1323,7 @@ ```webidl [ - CheckSecurity=Receiver, + CheckSecurity=Receiver ] interface DOMWindow { Selection? getSelection(); }; @@ -1401,8 +1361,8 @@ ### [CrossOrigin] _(m, a)_ Summary: Allows cross-origin access to an attribute or method. Used for -implementing [CrossOriginProperties] from the spec in Location.idl and -Window.idl. +implementing [CrossOriginProperties] from the spec in location.idl and +window.idl. Usage for methods: ```webidl @@ -1459,16 +1419,15 @@ }; ``` -Then you can write custom bindings in Source/bindings/v8/custom/V8XXXConstructorCustom.cpp: +Then you can write custom bindings in third_party/blink/renderer/bindings/{core,modules}/v8/custom/v8_xxx_constructor_custom.cc: ```c++ -v8::Local<v8::Value> V8XXX::constructorCallback(const v8::Arguments& args) -{ - ...; +v8::Local<v8::Value> V8XXX::ConstructorCallback(const v8::Arguments& args) { + ...; } ``` -### [FlexibleArrayBufferView] +### [FlexibleArrayBufferView] _(p)_ Summary: `[FlexibleArrayBufferView]` wraps a parameter that is known to be an ArrayBufferView (or a subtype of, e.g. typed arrays) with a FlexibleArrayBufferView. @@ -1574,7 +1533,7 @@ To update the cached value (e.g. for HTMLFoo.bar) proceed as follows: ```c++ -V8PrivateProperty::getHTMLFooBarCachedAccessor().set(context, object, newValue); +V8PrivateProperty::GetHTMLFooBarCachedAccessor().Set(context, object, new_value); ``` @@ -1611,7 +1570,7 @@ ```webidl [ - DoNotCheckConstants, + DoNotCheckConstants ] interface XXX { const unsigned short NOT_FOUND_ERR = 12345; const unsigned short SYNTAX_ERR = 12346; @@ -1634,7 +1593,7 @@ ```webidl [ - ImplementedAs=DOMPath, + ImplementedAs=DOMPath ] interface Path { [ImplementedAs=classAttribute] attribute int class; [ImplementedAs=deleteFunction] void delete(); @@ -1664,7 +1623,6 @@ * `[ImmutablePrototype]` * `[LegacyInterfaceTypeChecking]` * `[LogAllWorlds]` -* `[OverrideBuiltins]` :: used on named accessors * `[PerWorldBindings]` :: interacts with `[LogActivity]` * `[WebAgentAPI]`
diff --git a/third_party/blink/renderer/bindings/core/v8/binding_security.cc b/third_party/blink/renderer/bindings/core/v8/binding_security.cc index f8cb3df..6eaccba 100644 --- a/third_party/blink/renderer/bindings/core/v8/binding_security.cc +++ b/third_party/blink/renderer/bindings/core/v8/binding_security.cc
@@ -60,6 +60,35 @@ namespace { +void ReportOrThrowSecurityError(const LocalDOMWindow* accessing_window, + const DOMWindow* target_window, + ExceptionState& exception_state) { + if (target_window) { + exception_state.ThrowSecurityError( + target_window->SanitizedCrossDomainAccessErrorMessage(accessing_window), + target_window->CrossDomainAccessErrorMessage(accessing_window)); + } else { + exception_state.ThrowSecurityError("Cross origin access was denied."); + } +} + +void ReportOrThrowSecurityError( + const LocalDOMWindow* accessing_window, + const DOMWindow* target_window, + BindingSecurity::ErrorReportOption reporting_option) { + if (reporting_option == BindingSecurity::ErrorReportOption::kDoNotReport) + return; + + if (accessing_window && target_window) { + accessing_window->PrintErrorMessage( + target_window->CrossDomainAccessErrorMessage(accessing_window)); + } else if (accessing_window) { + accessing_window->PrintErrorMessage("Cross origin access was denied."); + } else { + // Nowhere to report the error. + } +} + bool CanAccessWindowInternal(const LocalDOMWindow* accessing_window, const DOMWindow* target_window) { SECURITY_CHECK(!(target_window && target_window->GetFrame()) || @@ -101,29 +130,14 @@ return true; } +template <typename ExceptionStateOrErrorReportOption> bool CanAccessWindow(const LocalDOMWindow* accessing_window, const DOMWindow* target_window, - ExceptionState& exception_state) { + ExceptionStateOrErrorReportOption& error_report) { if (CanAccessWindowInternal(accessing_window, target_window)) return true; - if (target_window) - exception_state.ThrowSecurityError( - target_window->SanitizedCrossDomainAccessErrorMessage(accessing_window), - target_window->CrossDomainAccessErrorMessage(accessing_window)); - return false; -} - -bool CanAccessWindow(const LocalDOMWindow* accessing_window, - const DOMWindow* target_window, - BindingSecurity::ErrorReportOption reporting_option) { - if (CanAccessWindowInternal(accessing_window, target_window)) - return true; - - if (accessing_window && target_window && - reporting_option == BindingSecurity::ErrorReportOption::kReport) - accessing_window->PrintErrorMessage( - target_window->CrossDomainAccessErrorMessage(accessing_window)); + ReportOrThrowSecurityError(accessing_window, target_window, error_report); return false; } @@ -310,6 +324,14 @@ // Workers and worklets do not support multiple contexts, so both of // |accessing_context| and |target_context| must be windows at this point. + // remote_object->CreationContext() returns the empty handle. Remote contexts + // are unconditionally treated as cross origin. + if (target_context.IsEmpty()) { + ReportOrThrowSecurityError(ToLocalDOMWindow(accessing_context), nullptr, + error_report); + return false; + } + LocalFrame* target_frame = ToLocalFrameIfNotDetached(target_context); // TODO(dcheng): Why doesn't this code just use DOMWindows throughout? Can't // we just always use ToLocalDOMWindow(context)?
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h b/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h index 33d2b21f..a1360cd 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h +++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h
@@ -67,6 +67,7 @@ kOffscreenCanvasTransferTag = 'H', // index, width, height, id:uint32_t -> // OffscreenCanvas. For OffscreenCanvas // transfer + kReadableStreamTransferTag = 'r', // index:uint32_t kDOMPointTag = 'Q', // x:Double, y:Double, z:Double, w:Double kDOMPointReadOnlyTag = 'W', // x:Double, y:Double, z:Double, w:Double kDOMRectTag = 'E', // x:Double, y:Double, width:Double, height:Double
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc index 35b48ab..3678704 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc +++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
@@ -47,9 +47,12 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_message_port.h" #include "third_party/blink/renderer/bindings/core/v8/v8_mojo_handle.h" #include "third_party/blink/renderer/bindings/core/v8/v8_offscreen_canvas.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h" #include "third_party/blink/renderer/bindings/core/v8/v8_shared_array_buffer.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" #include "third_party/blink/renderer/core/messaging/message_port.h" +#include "third_party/blink/renderer/core/streams/readable_stream.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h" #include "third_party/blink/renderer/platform/bindings/dom_data_store.h" @@ -58,6 +61,7 @@ #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/blob/blob_data.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/shared_buffer.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/dtoa/utils.h" @@ -65,6 +69,7 @@ #include "third_party/blink/renderer/platform/wtf/text/string_buffer.h" #include "third_party/blink/renderer/platform/wtf/text/string_hash.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" namespace blink { @@ -373,6 +378,22 @@ } } +void SerializedScriptValue::TransferReadableStreams( + ScriptState* script_state, + const ReadableStreamArray& readable_streams, + ExceptionState& exception_state) { + auto* execution_context = ExecutionContext::From(script_state); + for (ReadableStream* readable_stream : readable_streams) { + mojo::MessagePipe pipe; + MessagePort* local_port = MessagePort::Create(*execution_context); + local_port->Entangle(std::move(pipe.handle0)); + readable_stream->Serialize(script_state, local_port, exception_state); + if (exception_state.HadException()) + return; + stream_channels_.push_back(MessagePortChannel(std::move(pipe.handle1))); + } +} + void SerializedScriptValue::TransferArrayBuffers( v8::Isolate* isolate, const ArrayBufferArray& array_buffers, @@ -529,6 +550,18 @@ return false; } transferables.offscreen_canvases.push_back(offscreen_canvas); + } else if (RuntimeEnabledFeatures::TransferableStreamsEnabled() && + V8ReadableStream::hasInstance(transferable_object, isolate)) { + ReadableStream* stream = V8ReadableStream::ToImpl( + v8::Local<v8::Object>::Cast(transferable_object)); + if (transferables.readable_streams.Contains(stream)) { + exception_state.ThrowDOMException( + DOMExceptionCode::kDataCloneError, + "ReadableStream at index " + String::Number(i) + + " is a duplicate of an earlier ReadableStream."); + return false; + } + transferables.readable_streams.push_back(stream); } else { exception_state.ThrowTypeError("Value at index " + String::Number(i) + " does not have a transferable type.");
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h index 68ebafe5..17ea019 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h +++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h
@@ -35,6 +35,7 @@ #include "base/containers/span.h" #include "base/optional.h" +#include "third_party/blink/public/common/messaging/message_port_channel.h" #include "third_party/blink/renderer/bindings/core/v8/native_value_traits.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/transferables.h" #include "third_party/blink/renderer/core/core_export.h" @@ -72,6 +73,7 @@ using ImageBitmapContentsArray = Vector<scoped_refptr<StaticBitmapImage>, 1>; using TransferredWasmModulesArray = WTF::Vector<v8::WasmCompiledModule::TransferrableModule>; + using MessagePortChannelArray = Vector<MessagePortChannel>; // Increment this for each incompatible change to the wire format. // Version 2: Added StringUCharTag for UChar v8 strings. @@ -254,6 +256,8 @@ } void SetImageBitmapContentsArray(ImageBitmapContentsArray contents); + MessagePortChannelArray& GetStreamChannels() { return stream_channels_; } + bool IsLockedToAgentCluster() const { return !wasm_modules_.IsEmpty() || !shared_array_buffers_contents_.IsEmpty(); @@ -288,6 +292,9 @@ void TransferOffscreenCanvas(v8::Isolate*, const OffscreenCanvasArray&, ExceptionState&); + void TransferReadableStreams(ScriptState*, + const ReadableStreamArray&, + ExceptionState&); void CloneSharedArrayBuffers(SharedArrayBufferArray&); DataBufferPtr data_buffer_; size_t data_buffer_size_ = 0; @@ -297,6 +304,10 @@ ArrayBufferContentsArray array_buffer_contents_array_; ImageBitmapContentsArray image_bitmap_contents_array_; + // |stream_channels_| is also single-use but is special-cased because it works + // with ServiceWorkers. + MessagePortChannelArray stream_channels_; + // These do not have one-use transferred contents, like the above. TransferredWasmModulesArray wasm_modules_; BlobDataHandleMap blob_data_handles_;
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h b/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h index 736199d..d50e3ae8 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h +++ b/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h
@@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/heap/heap_allocator.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" namespace blink { @@ -16,12 +17,14 @@ class OffscreenCanvas; class MessagePort; class MojoHandle; +class ReadableStream; using ArrayBufferArray = HeapVector<Member<DOMArrayBufferBase>>; using ImageBitmapArray = HeapVector<Member<ImageBitmap>>; using OffscreenCanvasArray = HeapVector<Member<OffscreenCanvas>>; using MessagePortArray = HeapVector<Member<MessagePort>>; using MojoHandleArray = HeapVector<Member<blink::MojoHandle>>; +using ReadableStreamArray = HeapVector<Member<ReadableStream>>; class CORE_EXPORT Transferables final { STACK_ALLOCATED(); @@ -35,6 +38,7 @@ OffscreenCanvasArray offscreen_canvases; MessagePortArray message_ports; MojoHandleArray mojo_handles; + ReadableStreamArray readable_streams; }; // Along with extending |Transferables| to hold a new kind of transferable
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc index 9a6554b..331fba6 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc +++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
@@ -25,8 +25,10 @@ #include "third_party/blink/renderer/core/messaging/message_port.h" #include "third_party/blink/renderer/core/mojo/mojo_handle.h" #include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h" +#include "third_party/blink/renderer/core/streams/readable_stream.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/date_math.h" namespace blink { @@ -168,8 +170,17 @@ } void V8ScriptValueDeserializer::Transfer() { - // Thre's nothing to transfer if the deserializer was not given an unpacked - // value. + if (RuntimeEnabledFeatures::TransferableStreamsEnabled()) { + // TODO(ricea): Make ExtendableMessageEvent store an + // UnpackedSerializedScriptValue like MessageEvent does, and then this + // special case won't be necessary. + transferred_stream_ports_ = MessagePort::EntanglePorts( + *ExecutionContext::From(script_state_), + serialized_script_value_->GetStreamChannels()); + } + + // There's nothing else to transfer if the deserializer was not given an + // unpacked value. if (!unpacked_value_) return; @@ -206,7 +217,8 @@ } ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject( - SerializationTag tag) { + SerializationTag tag, + ExceptionState& exception_state) { switch (tag) { case kBlobTag: { if (Version() < 3) @@ -499,6 +511,18 @@ canvas->SetFrameSinkId(client_id, sink_id); return canvas; } + case kReadableStreamTransferTag: { + if (!RuntimeEnabledFeatures::TransferableStreamsEnabled()) + return nullptr; + uint32_t index = 0; + if (!ReadUint32(&index) || !transferred_stream_ports_ || + index >= transferred_stream_ports_->size()) { + return nullptr; + } + return ReadableStream::Deserialize( + script_state_, (*transferred_stream_ports_)[index].Get(), + exception_state); + } default: break; } @@ -601,8 +625,11 @@ nullptr, nullptr); ScriptWrappable* wrappable = nullptr; SerializationTag tag = kVersionTag; - if (ReadTag(&tag)) - wrappable = ReadDOMObject(tag); + if (ReadTag(&tag)) { + wrappable = ReadDOMObject(tag, exception_state); + if (exception_state.HadException()) + return v8::MaybeLocal<v8::Object>(); + } if (!wrappable) { exception_state.ThrowDOMException(DOMExceptionCode::kDataCloneError, "Unable to deserialize cloned data.");
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h index c020791..665dcfe 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h +++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h
@@ -18,6 +18,7 @@ namespace blink { class DOMRectReadOnly; +class ExceptionState; class File; class UnpackedSerializedScriptValue; @@ -46,7 +47,7 @@ v8::Local<v8::Value> Deserialize(); protected: - virtual ScriptWrappable* ReadDOMObject(SerializationTag); + virtual ScriptWrappable* ReadDOMObject(SerializationTag, ExceptionState&); ScriptState* GetScriptState() const { return script_state_; } @@ -113,6 +114,8 @@ // Message ports which were transferred in. const MessagePortArray* transferred_message_ports_ = nullptr; + Member<MessagePortArray> transferred_stream_ports_; + // Blob info for blobs stored by index. const WebBlobInfoArray* blob_info_array_ = nullptr;
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc index dd2f4e0c..e14e083 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc +++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc
@@ -22,6 +22,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_message_port.h" #include "third_party/blink/renderer/bindings/core/v8/v8_mojo_handle.h" #include "third_party/blink/renderer/bindings/core/v8/v8_offscreen_canvas.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h" #include "third_party/blink/renderer/bindings/core/v8/v8_shared_array_buffer.h" #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" #include "third_party/blink/renderer/core/geometry/dom_matrix.h" @@ -33,8 +34,10 @@ #include "third_party/blink/renderer/core/geometry/dom_rect_read_only.h" #include "third_party/blink/renderer/core/html/canvas/image_data.h" #include "third_party/blink/renderer/core/mojo/mojo_handle.h" +#include "third_party/blink/renderer/core/streams/readable_stream.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h" #include "third_party/blink/renderer/platform/file_metadata.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/allocator/partitions.h" #include "third_party/blink/renderer/platform/wtf/date_math.h" #include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" @@ -163,6 +166,13 @@ isolate, transferables_->offscreen_canvases, exception_state); if (exception_state.HadException()) return; + + if (RuntimeEnabledFeatures::TransferableStreamsEnabled()) { + serialized_script_value_->TransferReadableStreams( + script_state_, transferables_->readable_streams, exception_state); + if (exception_state.HadException()) + return; + } } } @@ -452,6 +462,30 @@ WriteUint32(canvas->SinkId()); return true; } + if (wrapper_type_info == &V8ReadableStream::wrapperTypeInfo && + RuntimeEnabledFeatures::TransferableStreamsEnabled()) { + ReadableStream* stream = wrappable->ToImpl<ReadableStream>(); + size_t index = kNotFound; + if (transferables_) + index = transferables_->readable_streams.Find(stream); + if (index == kNotFound) { + exception_state.ThrowDOMException(DOMExceptionCode::kDataCloneError, + "A ReadableStream could not be cloned " + "because it was not transferred."); + return false; + } + if (stream->IsLocked(script_state_, exception_state).value_or(true)) { + if (exception_state.HadException()) + return false; + exception_state.ThrowDOMException( + DOMExceptionCode::kDataCloneError, + "A ReadableStream could not be cloned because it was locked"); + return false; + } + WriteTag(kReadableStreamTransferTag); + WriteUint32(static_cast<uint32_t>(index)); + return true; + } return false; }
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc index 41264e2..98c9a52 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
@@ -30,6 +30,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_message_port.h" #include "third_party/blink/renderer/bindings/core/v8/v8_mojo_handle.h" #include "third_party/blink/renderer/bindings/core/v8/v8_offscreen_canvas.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h" #include "third_party/blink/renderer/bindings/core/v8/v8_string_resource.h" #include "third_party/blink/renderer/core/fileapi/blob.h" #include "third_party/blink/renderer/core/fileapi/file.h" @@ -46,6 +47,7 @@ #include "third_party/blink/renderer/core/messaging/message_port.h" #include "third_party/blink/renderer/core/mojo/mojo_handle.h" #include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h" +#include "third_party/blink/renderer/core/streams/readable_stream.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/file_metadata.h" #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" @@ -1840,5 +1842,31 @@ ->IsTrue()); } +// Sanity check for transferring ReadableStreams. This is mostly tested via +// layout tests. +TEST(V8ScriptValueSerializerTest, RoundTripReadableStream) { + ScopedTransferableStreamsForTest enable_transferable_streams(true); + + V8TestingScope scope; + auto* isolate = scope.GetIsolate(); + auto* script_state = scope.GetScriptState(); + + auto* rs = ReadableStream::Create(script_state, ASSERT_NO_EXCEPTION); + v8::Local<v8::Value> wrapper = ToV8(rs, script_state); + Vector<ScriptValue> transferable_array = {ScriptValue(script_state, wrapper)}; + Transferables transferables; + ASSERT_TRUE(SerializedScriptValue::ExtractTransferables( + isolate, transferable_array, transferables, ASSERT_NO_EXCEPTION)); + v8::Local<v8::Value> result = + RoundTrip(wrapper, scope, &ASSERT_NO_EXCEPTION, &transferables); + EXPECT_TRUE(result->IsObject()); + ASSERT_TRUE(V8ReadableStream::hasInstance(result, isolate)); + ReadableStream* transferred = + V8ReadableStream::ToImpl(result.As<v8::Object>()); + EXPECT_NE(rs, transferred); + EXPECT_TRUE(rs->locked(script_state, ASSERT_NO_EXCEPTION)); + EXPECT_FALSE(transferred->locked(script_state, ASSERT_NO_EXCEPTION)); +} + } // namespace } // namespace blink
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc index e97e413..8840687 100644 --- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc +++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
@@ -21,11 +21,12 @@ namespace blink { ScriptWrappable* V8ScriptValueDeserializerForModules::ReadDOMObject( - SerializationTag tag) { + SerializationTag tag, + ExceptionState& exception_state) { // Give the core/ implementation a chance to try first. // If it didn't recognize the kind of wrapper, try the modules types. if (ScriptWrappable* wrappable = - V8ScriptValueDeserializer::ReadDOMObject(tag)) + V8ScriptValueDeserializer::ReadDOMObject(tag, exception_state)) return wrappable; switch (tag) {
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h index eab1e1f..fa33ae1 100644 --- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h +++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h
@@ -33,7 +33,7 @@ : V8ScriptValueDeserializer(script_state, std::move(value), options) {} protected: - ScriptWrappable* ReadDOMObject(SerializationTag) override; + ScriptWrappable* ReadDOMObject(SerializationTag, ExceptionState&) override; private: bool ReadOneByte(uint8_t* byte) {
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_property_subclass.cc.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_property_subclass.cc.tmpl index 3647ca6..838dccaf 100644 --- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_property_subclass.cc.tmpl +++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_property_subclass.cc.tmpl
@@ -13,9 +13,9 @@ {% endfor %} namespace blink { -namespace CSSLonghand { +namespace css_longhand { {{style_builder_functions(property, false)}} -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_property_subclass.h.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_property_subclass.h.tmpl index d73c1802..94e9ee3 100644 --- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_property_subclass.h.tmpl +++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_property_subclass.h.tmpl
@@ -14,7 +14,7 @@ {% endfor %} namespace blink { -namespace CSS{{property.namespace_group}} { +namespace css_{{property.namespace_group.lower()}} { {% if property.is_property %} // Implements the '{{property.name}}' CSS property @@ -130,7 +130,7 @@ {% endif %} }; -} // namespace CSS{{property.namespace_group}} +} // namespace css_{{property.namespace_group.lower()}} } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PROPERTIES_{{property.namespace_group.upper()}}_{{property_filename|upper}}_H_
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_unresolved_property.cc.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_unresolved_property.cc.tmpl index 7872196..56c9eb7 100644 --- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_unresolved_property.cc.tmpl +++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_unresolved_property.cc.tmpl
@@ -23,10 +23,10 @@ static constexpr Variable property_csspropertyvariable; {% for _, property_id, classname, namespace_group, _ in property_classes_by_property_id %} -static constexpr CSS{{namespace_group}}::{{classname}} property_{{property_id.lower()}}; +static constexpr css_{{namespace_group.lower()}}::{{classname}} property_{{property_id.lower()}}; {% endfor %} {% for _, property_id, classname, namespace_group, _ in alias_classes_by_property_id %} -static constexpr CSS{{namespace_group}}::{{classname}} property_{{property_id.lower()}}; +static constexpr css_{{namespace_group.lower()}}::{{classname}} property_{{property_id.lower()}}; {% endfor %} } // namespace
diff --git a/third_party/blink/renderer/core/css/properties/longhands/align_content_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/align_content_custom.cc index 2e1d8d38..3ffafa1 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/align_content_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/align_content_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* AlignContent::ParseSingleValue( CSSParserTokenRange& range, @@ -30,5 +30,5 @@ style.AlignContent()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/align_items_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/align_items_custom.cc index a1e5c76..e77d25d8 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/align_items_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/align_items_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* AlignItems::ParseSingleValue( CSSParserTokenRange& range, @@ -34,5 +34,5 @@ style.AlignItems()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/align_self_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/align_self_custom.cc index 50260e9..9565047 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/align_self_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/align_self_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* AlignSelf::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ style.AlignSelf()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/alignment_baseline_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/alignment_baseline_custom.cc index f725b6c3a..6ee34f48 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/alignment_baseline_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/alignment_baseline_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/alignment_baseline.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* AlignmentBaseline::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(svg_style.AlignmentBaseline()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/animation_delay_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/animation_delay_custom.cc index e53e54e..06dfd29 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/animation_delay_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/animation_delay_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/platform/geometry/length.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* AnimationDelay::ParseSingleValue( CSSParserTokenRange& range, @@ -37,5 +37,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/animation_direction_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/animation_direction_custom.cc index 49434d2..4deae2d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/animation_direction_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/animation_direction_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* AnimationDirection::ParseSingleValue( CSSParserTokenRange& range, @@ -48,5 +48,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/animation_duration_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/animation_duration_custom.cc index c8bcf4c..5158fb34 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/animation_duration_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/animation_duration_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/platform/geometry/length.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* AnimationDuration::ParseSingleValue( CSSParserTokenRange& range, @@ -37,5 +37,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/animation_fill_mode_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/animation_fill_mode_custom.cc index a6563b5b..e1fb860 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/animation_fill_mode_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/animation_fill_mode_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* AnimationFillMode::ParseSingleValue( CSSParserTokenRange& range, @@ -47,5 +47,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/animation_iteration_count_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/animation_iteration_count_custom.cc index 339d636..b0eaa447 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/animation_iteration_count_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/animation_iteration_count_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* AnimationIterationCount::ParseSingleValue( CSSParserTokenRange& range, @@ -49,5 +49,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/animation_name_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/animation_name_custom.cc index c23d3d48..8603f6ab 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/animation_name_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/animation_name_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* AnimationName::ParseSingleValue( CSSParserTokenRange& range, @@ -45,5 +45,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/animation_play_state_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/animation_play_state_custom.cc index c03fcc04..16e02578 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/animation_play_state_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/animation_play_state_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* AnimationPlayState::ParseSingleValue( CSSParserTokenRange& range, @@ -47,5 +47,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/animation_timing_function_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/animation_timing_function_custom.cc index e105268c..205f333 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/animation_timing_function_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/animation_timing_function_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* AnimationTimingFunction::ParseSingleValue( CSSParserTokenRange& range, @@ -36,5 +36,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/backdrop_filter_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/backdrop_filter_custom.cc index 4aef738..50302fd 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/backdrop_filter_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/backdrop_filter_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BackdropFilter::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ return ComputedStyleUtils::ValueForFilter(style, style.BackdropFilter()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/backface_visibility_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/backface_visibility_custom.cc index aa12196..7ef04f62 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/backface_visibility_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/backface_visibility_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/backface_visibility.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BackfaceVisibility::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -19,5 +19,5 @@ : CSSValueVisible); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/background_attachment_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/background_attachment_custom.cc index 885ebbb..e059133 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/background_attachment_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/background_attachment_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BackgroundAttachment::ParseSingleValue( CSSParserTokenRange& range, @@ -31,5 +31,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/background_blend_mode_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/background_blend_mode_custom.cc index ebbc299..08417ec 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/background_blend_mode_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/background_blend_mode_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BackgroundBlendMode::ParseSingleValue( CSSParserTokenRange& range, @@ -31,5 +31,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/background_clip_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/background_clip_custom.cc index 8b84a92..a2e80e5 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/background_clip_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/background_clip_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BackgroundClip::ParseSingleValue( CSSParserTokenRange& range, @@ -33,5 +33,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/background_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/background_color_custom.cc index 99a709e0..1fb8f509 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/background_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/background_color_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BackgroundColor::ParseSingleValue( CSSParserTokenRange& range, @@ -57,5 +57,5 @@ style, style.BackgroundColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/background_image_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/background_image_custom.cc index c391d99a..bc8afb10 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/background_image_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/background_image_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BackgroundImage::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ComputedStyleUtils::BackgroundImageOrWebkitMaskImage(fill_layer); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/background_origin_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/background_origin_custom.cc index 546e450..3b076d9 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/background_origin_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/background_origin_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BackgroundOrigin::ParseSingleValue( CSSParserTokenRange& range, @@ -33,5 +33,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/background_position_x_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/background_position_x_custom.cc index 487e770d..de6066d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/background_position_x_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/background_position_x_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BackgroundPositionX::ParseSingleValue( CSSParserTokenRange& range, @@ -33,5 +33,5 @@ style, curr_layer); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/background_position_y_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/background_position_y_custom.cc index dcb3aa8..f5a453c 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/background_position_y_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/background_position_y_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BackgroundPositionY::ParseSingleValue( CSSParserTokenRange& range, @@ -33,5 +33,5 @@ style, curr_layer); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/background_size_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/background_size_custom.cc index a93a395b..c426a54d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/background_size_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/background_size_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BackgroundSize::ParseSingleValue( CSSParserTokenRange& range, @@ -30,5 +30,5 @@ return ComputedStyleUtils::BackgroundImageOrWebkitMaskSize(style, fill_layer); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/baseline_shift_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/baseline_shift_custom.cc index 39b2c4ec..a16199c 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/baseline_shift_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/baseline_shift_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BaselineShift::ParseSingleValue( CSSParserTokenRange& range, @@ -77,5 +77,5 @@ } } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/block_size_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/block_size_custom.cc index cf1d1cb..56bba6c 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/block_size_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/block_size_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/layout/layout_object.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BlockSize::ParseSingleValue( CSSParserTokenRange& range, @@ -23,5 +23,5 @@ return layout_object && layout_object->IsBox(); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_block_end_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_block_end_color_custom.cc index 6e3191d1..f6639270 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_block_end_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_block_end_color_custom.cc
@@ -12,7 +12,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderBlockEndColor::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ return css_property_parser_helpers::ConsumeColor(range, context.Mode()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_block_end_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_block_end_width_custom.cc index 456c98b..e57415d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_block_end_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_block_end_width_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderBlockEndWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_block_start_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_block_start_color_custom.cc index b4ebfad4..ea96b89 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_block_start_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_block_start_color_custom.cc
@@ -12,7 +12,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderBlockStartColor::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ return css_property_parser_helpers::ConsumeColor(range, context.Mode()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_block_start_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_block_start_width_custom.cc index 9c605b3..8a15fcbc 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_block_start_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_block_start_width_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderBlockStartWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_bottom_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_bottom_color_custom.cc index bdd1a4d6..1935e6a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_bottom_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_bottom_color_custom.cc
@@ -15,7 +15,7 @@ class CSSParserLocalContext; class CSSParserTokenRange; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderBottomColor::ParseSingleValue( CSSParserTokenRange& range, @@ -47,5 +47,5 @@ style, style.BorderBottomColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_bottom_left_radius_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_bottom_left_radius_custom.cc index e953a6b..791b4cdc 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_bottom_left_radius_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_bottom_left_radius_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderBottomLeftRadius::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ style.BorderBottomLeftRadius(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_bottom_right_radius_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_bottom_right_radius_custom.cc index 68b9c1c..1eb8d4e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_bottom_right_radius_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_bottom_right_radius_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderBottomRightRadius::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ style.BorderBottomRightRadius(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_bottom_style_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_bottom_style_custom.cc index fbdec89..5b1894c 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_bottom_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_bottom_style_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/border_bottom_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderBottomStyle::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.BorderBottomStyle()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_bottom_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_bottom_width_custom.cc index 1b4d32c2..253c9b0 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_bottom_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_bottom_width_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderBottomWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -26,5 +26,5 @@ return ZoomAdjustedPixelValue(style.BorderBottomWidth(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_collapse_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_collapse_custom.cc index d815b21..d6a4bfdf 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_collapse_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_collapse_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderCollapse::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -20,5 +20,5 @@ return CSSIdentifierValue::Create(CSSValueSeparate); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_image_outset_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_image_outset_custom.cc index 687ee68..7f0185f 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_image_outset_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_image_outset_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderImageOutset::ParseSingleValue( CSSParserTokenRange& range, @@ -39,5 +39,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_image_repeat_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_image_repeat_custom.cc index b8d25b0f..96d7358 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_image_repeat_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_image_repeat_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderImageRepeat::ParseSingleValue( CSSParserTokenRange& range, @@ -33,5 +33,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_image_slice_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_image_slice_custom.cc index 4f0a6ad..62888d64 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_image_slice_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_image_slice_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderImageSlice::ParseSingleValue( CSSParserTokenRange& range, @@ -35,5 +35,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_image_source_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_image_source_custom.cc index 8385200..17622ae 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_image_source_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_image_source_custom.cc
@@ -12,7 +12,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderImageSource::ParseSingleValue( CSSParserTokenRange& range, @@ -44,5 +44,5 @@ state.GetStyleImage(CSSPropertyBorderImageSource, value)); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_image_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_image_width_custom.cc index df383141..6b3bd3bd 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_image_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_image_width_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderImageWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -39,5 +39,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_inline_end_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_inline_end_color_custom.cc index d781c6cf..4a76f43 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_inline_end_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_inline_end_color_custom.cc
@@ -12,7 +12,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderInlineEndColor::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ return css_property_parser_helpers::ConsumeColor(range, context.Mode()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_inline_end_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_inline_end_width_custom.cc index c2337c8..ce62e09e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_inline_end_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_inline_end_width_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderInlineEndWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_inline_start_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_inline_start_color_custom.cc index 02b93ce..35c9084 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_inline_start_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_inline_start_color_custom.cc
@@ -12,7 +12,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderInlineStartColor::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ return css_property_parser_helpers::ConsumeColor(range, context.Mode()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_inline_start_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_inline_start_width_custom.cc index 2fa823d..a9cdb5f 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_inline_start_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_inline_start_width_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderInlineStartWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_left_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_left_color_custom.cc index 93f247df..899c48f 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_left_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_left_color_custom.cc
@@ -15,7 +15,7 @@ class CSSParserLocalContext; class CSSParserTokenRange; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderLeftColor::ParseSingleValue( CSSParserTokenRange& range, @@ -47,5 +47,5 @@ style, style.BorderLeftColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_left_style_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_left_style_custom.cc index 5789b084..eca1f56 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_left_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_left_style_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/border_left_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderLeftStyle::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.BorderLeftStyle()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_left_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_left_width_custom.cc index 8c3fdc1..cccc0450 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_left_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_left_width_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderLeftWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -26,5 +26,5 @@ return ZoomAdjustedPixelValue(style.BorderLeftWidth(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_right_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_right_color_custom.cc index ed0890b..5adefc6 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_right_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_right_color_custom.cc
@@ -15,7 +15,7 @@ class CSSParserLocalContext; class CSSParserTokenRange; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderRightColor::ParseSingleValue( CSSParserTokenRange& range, @@ -47,5 +47,5 @@ style, style.BorderRightColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_right_style_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_right_style_custom.cc index eb04928..bb8bcde 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_right_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_right_style_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/border_right_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderRightStyle::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.BorderRightStyle()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_right_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_right_width_custom.cc index d493af5..9850f28e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_right_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_right_width_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderRightWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -26,5 +26,5 @@ return ZoomAdjustedPixelValue(style.BorderRightWidth(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_top_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_top_color_custom.cc index 4697c16..10319b50 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_top_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_top_color_custom.cc
@@ -15,7 +15,7 @@ class CSSParserLocalContext; class CSSParserTokenRange; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderTopColor::ParseSingleValue( CSSParserTokenRange& range, @@ -48,5 +48,5 @@ style, style.BorderTopColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_top_left_radius_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_top_left_radius_custom.cc index 6b7d8c7..7c01a8a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_top_left_radius_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_top_left_radius_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderTopLeftRadius::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ style.BorderTopLeftRadius(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_top_right_radius_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_top_right_radius_custom.cc index 6c768a8e..723f400 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_top_right_radius_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_top_right_radius_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderTopRightRadius::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ style.BorderTopRightRadius(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_top_style_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_top_style_custom.cc index 7b524a901..e00e4d0a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_top_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_top_style_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/border_top_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderTopStyle::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.BorderTopStyle()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/border_top_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/border_top_width_custom.cc index 9c926794..86419951 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/border_top_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/border_top_width_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BorderTopWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -26,5 +26,5 @@ return ZoomAdjustedPixelValue(style.BorderTopWidth(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/bottom_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/bottom_custom.cc index 255e85ab..7f22bfd6 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/bottom_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/bottom_custom.cc
@@ -15,7 +15,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Bottom::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -40,5 +40,5 @@ layout_object); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/box_shadow_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/box_shadow_custom.cc index 8105c12..0004a5d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/box_shadow_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/box_shadow_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BoxShadow::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ComputedStyleUtils::ValueForShadowList(style.BoxShadow(), style, true); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/box_sizing_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/box_sizing_custom.cc index 2ece767f..560b580 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/box_sizing_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/box_sizing_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BoxSizing::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -20,5 +20,5 @@ return CSSIdentifierValue::Create(CSSValueBorderBox); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/break_after_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/break_after_custom.cc index cc54c807..fdf5814 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/break_after_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/break_after_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/break_after.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BreakAfter::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.BreakAfter()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/break_before_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/break_before_custom.cc index 131cd9e6..7626cb7 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/break_before_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/break_before_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/break_before.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BreakBefore::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.BreakBefore()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/break_inside_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/break_inside_custom.cc index 118eb08..36c675b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/break_inside_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/break_inside_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/break_inside.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BreakInside::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.BreakInside()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/buffered_rendering_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/buffered_rendering_custom.cc index 8fb703f5..a65e2fb8 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/buffered_rendering_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/buffered_rendering_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/buffered_rendering.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* BufferedRendering::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(svg_style.BufferedRendering()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/caption_side_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/caption_side_custom.cc index 68b07a2..2617588 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/caption_side_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/caption_side_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/caption_side.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* CaptionSide::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.CaptionSide()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/caret_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/caret_color_custom.cc index b4fc047..48d4150 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/caret_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/caret_color_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* CaretColor::ParseSingleValue( CSSParserTokenRange& range, @@ -80,5 +80,5 @@ } } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/clear_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/clear_custom.cc index 2764653..2378439 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/clear_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/clear_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/clear.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Clear::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.Clear()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/clip_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/clip_custom.cc index 6577015..968d00a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/clip_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/clip_custom.cc
@@ -23,7 +23,7 @@ } } // namespace -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Clip::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -79,5 +79,5 @@ CSSQuadValue::kSerializeAsRect); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/clip_path_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/clip_path_custom.cc index b5d4ef59..c12fa9f5 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/clip_path_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/clip_path_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style/shape_clip_path_operation.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ClipPath::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -45,5 +45,5 @@ return CSSIdentifierValue::Create(CSSValueNone); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/clip_rule_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/clip_rule_custom.cc index 355a6a2c..dbdb989 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/clip_rule_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/clip_rule_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/clip_rule.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ClipRule::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(svg_style.ClipRule()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/color_custom.cc index b6fcd1a..75fb0a42 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/color_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Color::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -73,5 +73,5 @@ } } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/color_interpolation_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/color_interpolation_custom.cc index 73f1c30..473436e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/color_interpolation_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/color_interpolation_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/color_interpolation.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ColorInterpolation::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(svg_style.ColorInterpolation()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/color_interpolation_filters_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/color_interpolation_filters_custom.cc index 586a813..edbc601 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/color_interpolation_filters_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/color_interpolation_filters_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/color_interpolation_filters.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ColorInterpolationFilters::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(svg_style.ColorInterpolationFilters()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/color_rendering_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/color_rendering_custom.cc index 0fa6eec6..9c76a140 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/color_rendering_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/color_rendering_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/color_rendering.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ColorRendering::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(svg_style.ColorRendering()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/column_count_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/column_count_custom.cc index 9e270f3..629c19f 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/column_count_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/column_count_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ColumnCount::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/column_fill_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/column_fill_custom.cc index 5e5ac88..01b60be1d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/column_fill_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/column_fill_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/column_fill.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ColumnFill::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.GetColumnFill()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/column_gap_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/column_gap_custom.cc index 518317a..e84fc9d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/column_gap_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/column_gap_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ColumnGap::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ComputedStyleUtils::ValueForGapLength(style.ColumnGap(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/column_rule_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/column_rule_color_custom.cc index fa65a278..95f128af 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/column_rule_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/column_rule_color_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ColumnRuleColor::ParseSingleValue( CSSParserTokenRange& range, @@ -42,5 +42,5 @@ style, style.ColumnRuleColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/column_rule_style_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/column_rule_style_custom.cc index 0813b5d5..bace7dd 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/column_rule_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/column_rule_style_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/column_rule_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ColumnRuleStyle::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.ColumnRuleStyle()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/column_rule_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/column_rule_width_custom.cc index 2306bf3..1dce9d4 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/column_rule_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/column_rule_width_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ColumnRuleWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ZoomAdjustedPixelValue(style.ColumnRuleWidth(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/column_span_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/column_span_custom.cc index 55a3bd1..030e7a8 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/column_span_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/column_span_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ColumnSpan::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ : CSSValueNone); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/column_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/column_width_custom.cc index 7e5d16d..d8f23451 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/column_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/column_width_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ColumnWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ZoomAdjustedPixelValue(style.ColumnWidth(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/contain_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/contain_custom.cc index a45aff1..c5ea792 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/contain_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/contain_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { // none | strict | content | [ layout || style || paint || size ] const CSSValue* Contain::ParseSingleValue(CSSParserTokenRange& range, @@ -66,5 +66,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/content_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/content_custom.cc index 7134ae59..ee8e477a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/content_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/content_custom.cc
@@ -71,7 +71,7 @@ } } // namespace -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Content::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -212,5 +212,5 @@ state.Style()->SetContent(first_content); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/counter_increment_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/counter_increment_custom.cc index 5be9aef..d93128e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/counter_increment_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/counter_increment_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const int kCounterIncrementDefaultValue = 1; @@ -30,5 +30,5 @@ return ComputedStyleUtils::ValueForCounterDirectives(style, true); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/counter_reset_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/counter_reset_custom.cc index 3237b64..04a48a0 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/counter_reset_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/counter_reset_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const int kCounterResetDefaultValue = 0; @@ -30,5 +30,5 @@ return ComputedStyleUtils::ValueForCounterDirectives(style, false); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/cursor_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/cursor_custom.cc index 97c53d4..4b93b78a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/cursor_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/cursor_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Cursor::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -132,5 +132,5 @@ } } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/cx_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/cx_custom.cc index 297eec4..517c04c 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/cx_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/cx_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Cx::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -27,5 +27,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/cy_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/cy_custom.cc index 7d7b3cb44..97b5a99f 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/cy_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/cy_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Cy::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -27,5 +27,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/d_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/d_custom.cc index e91310e4..c24d8c194 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/d_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/d_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* D::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext&, @@ -27,5 +27,5 @@ return CSSIdentifierValue::Create(CSSValueNone); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/direction_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/direction_custom.cc index 7cd95e7..13c8483 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/direction_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/direction_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/direction.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Direction::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -22,5 +22,5 @@ ToCSSIdentifierValue(value).ConvertTo<TextDirection>()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/display_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/display_custom.cc index 047e8e6..123540f 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/display_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/display_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Display::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -92,5 +92,5 @@ state.Style()->SetDisplayLayoutCustomName(layout_function_value.GetName()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/dominant_baseline_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/dominant_baseline_custom.cc index 85123ec..cb4b455 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/dominant_baseline_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/dominant_baseline_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/dominant_baseline.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* DominantBaseline::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(svg_style.DominantBaseline()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/empty_cells_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/empty_cells_custom.cc index d129093..cefac2d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/empty_cells_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/empty_cells_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/empty_cells.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* EmptyCells::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.EmptyCells()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/fill_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/fill_custom.cc index ba5226a..f266db3 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/fill_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/fill_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Fill::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -27,5 +27,5 @@ svg_style.FillPaint(), style.GetColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/fill_opacity_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/fill_opacity_custom.cc index 594a2de..4ff579ef 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/fill_opacity_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/fill_opacity_custom.cc
@@ -11,7 +11,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FillOpacity::ParseSingleValue( CSSParserTokenRange& range, @@ -30,5 +30,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/fill_rule_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/fill_rule_custom.cc index c496cdf..90e993e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/fill_rule_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/fill_rule_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/fill_rule.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FillRule::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(svg_style.FillRule()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/filter_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/filter_custom.cc index 2140c11e..74313572 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/filter_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/filter_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Filter::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -27,5 +27,5 @@ return ComputedStyleUtils::ValueForFilter(style, style.Filter()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/flex_basis_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/flex_basis_custom.cc index 1369851e..f186c40 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/flex_basis_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/flex_basis_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FlexBasis::ParseSingleValue( CSSParserTokenRange& range, @@ -32,5 +32,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/flex_direction_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/flex_direction_custom.cc index 47f5aa5..50bd003 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/flex_direction_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/flex_direction_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/flex_direction.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FlexDirection::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.FlexDirection()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/flex_grow_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/flex_grow_custom.cc index fae137d..7636c88 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/flex_grow_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/flex_grow_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/platform/geometry/length.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FlexGrow::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext&, @@ -28,5 +28,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/flex_shrink_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/flex_shrink_custom.cc index a406e8f..6268696 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/flex_shrink_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/flex_shrink_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/platform/geometry/length.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FlexShrink::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/flex_wrap_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/flex_wrap_custom.cc index 2c604c9..4ecb245 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/flex_wrap_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/flex_wrap_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/flex_wrap.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FlexWrap::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.FlexWrap()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/float_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/float_custom.cc index 1f9c40b..3eacdda 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/float_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/float_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Float::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -20,5 +20,5 @@ return CSSIdentifierValue::Create(style.Floating()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/flood_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/flood_color_custom.cc index 091bd25..6885c49 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/flood_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/flood_color_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FloodColor::ParseSingleValue( CSSParserTokenRange& range, @@ -37,5 +37,5 @@ style.FloodColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/flood_opacity_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/flood_opacity_custom.cc index 03566ca4..768b47f 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/flood_opacity_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/flood_opacity_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FloodOpacity::ParseSingleValue( CSSParserTokenRange& range, @@ -27,5 +27,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/font_family_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/font_family_custom.cc index da2afab..e417f75 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/font_family_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/font_family_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FontFamily::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ return ComputedStyleUtils::ValueForFontFamily(style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/font_feature_settings_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/font_feature_settings_custom.cc index e9d8670..68ddb3d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/font_feature_settings_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/font_feature_settings_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FontFeatureSettings::ParseSingleValue( CSSParserTokenRange& range, @@ -38,5 +38,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/font_kerning_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/font_kerning_custom.cc index 56d6511..3d7d64c 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/font_kerning_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/font_kerning_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FontKerning::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -18,5 +18,5 @@ return CSSIdentifierValue::Create(style.GetFontDescription().GetKerning()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/font_size_adjust_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/font_size_adjust_custom.cc index e204eff..182ee12 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/font_size_adjust_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/font_size_adjust_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FontSizeAdjust::ParseSingleValue( CSSParserTokenRange& range, @@ -36,5 +36,5 @@ return CSSIdentifierValue::Create(CSSValueNone); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/font_size_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/font_size_custom.cc index 5ba3807..c7949a25 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/font_size_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/font_size_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FontSize::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -30,5 +30,5 @@ return ComputedStyleUtils::ValueForFontSize(style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/font_stretch_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/font_stretch_custom.cc index f395ac4..e84ab2b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/font_stretch_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/font_stretch_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FontStretch::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ return ComputedStyleUtils::ValueForFontStretch(style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/font_style_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/font_style_custom.cc index c86a7fe7..0fece06 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/font_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/font_style_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FontStyle::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ return ComputedStyleUtils::ValueForFontStyle(style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/font_variant_caps_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/font_variant_caps_custom.cc index 089b553..d129401 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/font_variant_caps_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/font_variant_caps_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FontVariantCaps::ParseSingleValue( CSSParserTokenRange& range, @@ -31,5 +31,5 @@ return ComputedStyleUtils::ValueForFontVariantCaps(style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/font_variant_east_asian_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/font_variant_east_asian_custom.cc index 637fee0d..4fad3ff 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/font_variant_east_asian_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/font_variant_east_asian_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FontVariantEastAsian::ParseSingleValue( CSSParserTokenRange& range, @@ -38,5 +38,5 @@ return ComputedStyleUtils::ValueForFontVariantEastAsian(style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/font_variant_ligatures_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/font_variant_ligatures_custom.cc index 49a87a87..3d0f7921 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/font_variant_ligatures_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/font_variant_ligatures_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FontVariantLigatures::ParseSingleValue( CSSParserTokenRange& range, @@ -38,5 +38,5 @@ return ComputedStyleUtils::ValueForFontVariantLigatures(style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/font_variant_numeric_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/font_variant_numeric_custom.cc index 4f36040..999082a7 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/font_variant_numeric_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/font_variant_numeric_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FontVariantNumeric::ParseSingleValue( CSSParserTokenRange& range, @@ -38,5 +38,5 @@ return ComputedStyleUtils::ValueForFontVariantNumeric(style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/font_variation_settings_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/font_variation_settings_custom.cc index 8d668b3d..96c5224f 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/font_variation_settings_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/font_variation_settings_custom.cc
@@ -42,7 +42,7 @@ } } // namespace -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FontVariationSettings::ParseSingleValue( CSSParserTokenRange& range, @@ -82,5 +82,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/font_weight_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/font_weight_custom.cc index 5bd0379..45f37e6d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/font_weight_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/font_weight_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* FontWeight::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ return ComputedStyleUtils::ValueForFontWeight(style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/grid_auto_columns_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/grid_auto_columns_custom.cc index 882e59c..b1cf05a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/grid_auto_columns_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/grid_auto_columns_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* GridAutoColumns::ParseSingleValue( CSSParserTokenRange& range, @@ -37,5 +37,5 @@ return ComputedStyleUtils::ValueForGridTrackSizeList(kForColumns, style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/grid_auto_flow_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/grid_auto_flow_custom.cc index fe3bbb8..5120a20 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/grid_auto_flow_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/grid_auto_flow_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* GridAutoFlow::ParseSingleValue( CSSParserTokenRange& range, @@ -69,5 +69,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/grid_auto_rows_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/grid_auto_rows_custom.cc index bbb2ebd..cb690bf 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/grid_auto_rows_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/grid_auto_rows_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* GridAutoRows::ParseSingleValue( CSSParserTokenRange& range, @@ -30,5 +30,5 @@ return ComputedStyleUtils::ValueForGridTrackSizeList(kForRows, style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/grid_column_end_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/grid_column_end_custom.cc index 759134a..7ac7e97 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/grid_column_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/grid_column_end_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* GridColumnEnd::ParseSingleValue( CSSParserTokenRange& range, @@ -27,5 +27,5 @@ return ComputedStyleUtils::ValueForGridPosition(style.GridColumnEnd()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/grid_column_start_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/grid_column_start_custom.cc index 91fccf7..d1a3682 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/grid_column_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/grid_column_start_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* GridColumnStart::ParseSingleValue( CSSParserTokenRange& range, @@ -27,5 +27,5 @@ return ComputedStyleUtils::ValueForGridPosition(style.GridColumnStart()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/grid_row_end_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/grid_row_end_custom.cc index 5ea365b..df82567 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/grid_row_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/grid_row_end_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* GridRowEnd::ParseSingleValue( CSSParserTokenRange& range, @@ -27,5 +27,5 @@ return ComputedStyleUtils::ValueForGridPosition(style.GridRowEnd()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/grid_row_start_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/grid_row_start_custom.cc index 4a80dda..c7263362a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/grid_row_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/grid_row_start_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* GridRowStart::ParseSingleValue( CSSParserTokenRange& range, @@ -27,5 +27,5 @@ return ComputedStyleUtils::ValueForGridPosition(style.GridRowStart()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/grid_template_areas_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/grid_template_areas_custom.cc index 5b45c81..17aee7d45 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/grid_template_areas_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/grid_template_areas_custom.cc
@@ -16,7 +16,7 @@ #include "third_party/blink/renderer/core/style/grid_area.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* GridTemplateAreas::ParseSingleValue( CSSParserTokenRange& range, @@ -109,5 +109,5 @@ grid_template_areas_value.ColumnCount()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/grid_template_columns_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/grid_template_columns_custom.cc index 2124e3e..629599b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/grid_template_columns_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/grid_template_columns_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* GridTemplateColumns::ParseSingleValue( CSSParserTokenRange& range, @@ -36,5 +36,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/grid_template_rows_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/grid_template_rows_custom.cc index 1242f6a..5fff8e5 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/grid_template_rows_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/grid_template_rows_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* GridTemplateRows::ParseSingleValue( CSSParserTokenRange& range, @@ -36,5 +36,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/height_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/height_custom.cc index 9385514..4c843c3 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/height_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/height_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Height::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -39,5 +39,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/hyphens_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/hyphens_custom.cc index d38676b1..126d040 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/hyphens_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/hyphens_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/hyphens.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Hyphens::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.GetHyphens()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/image_orientation_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/image_orientation_custom.cc index 5475e6b3..83946507 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/image_orientation_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/image_orientation_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ImageOrientation::ParseSingleValue( CSSParserTokenRange& range, @@ -40,5 +40,5 @@ return CSSPrimitiveValue::Create(0, CSSPrimitiveValue::UnitType::kDegrees); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/image_rendering_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/image_rendering_custom.cc index 2afb6b39..75bd3729 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/image_rendering_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/image_rendering_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/image_rendering.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ImageRendering::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.ImageRendering()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/inline_size_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/inline_size_custom.cc index c1ecec8..0352962 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/inline_size_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/inline_size_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/layout/layout_object.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* InlineSize::ParseSingleValue( CSSParserTokenRange& range, @@ -23,5 +23,5 @@ return layout_object && layout_object->IsBox(); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/inset_block_end_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/inset_block_end_custom.cc index 085374c..fa897cf 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/inset_block_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/inset_block_end_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* InsetBlockEnd::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/inset_block_start_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/inset_block_start_custom.cc index c938d3f..0e86d55 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/inset_block_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/inset_block_start_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* InsetBlockStart::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/inset_inline_end_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/inset_inline_end_custom.cc index 983ff861..fb265c3 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/inset_inline_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/inset_inline_end_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* InsetInlineEnd::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/inset_inline_start_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/inset_inline_start_custom.cc index 07de82f..dd4b9b0b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/inset_inline_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/inset_inline_start_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* InsetInlineStart::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/isolation_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/isolation_custom.cc index 7e3a507..4e27da4 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/isolation_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/isolation_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/isolation.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Isolation::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.Isolation()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/justify_content_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/justify_content_custom.cc index 562e06d..0bada6e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/justify_content_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/justify_content_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* JustifyContent::ParseSingleValue( CSSParserTokenRange& range, @@ -35,5 +35,5 @@ style.JustifyContent()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/justify_items_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/justify_items_custom.cc index 2f9d3dea..327401e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/justify_items_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/justify_items_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* JustifyItems::ParseSingleValue( CSSParserTokenRange& range, @@ -58,5 +58,5 @@ : style.JustifyItems()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/justify_self_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/justify_self_custom.cc index 8860d6a..68e1386 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/justify_self_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/justify_self_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* JustifySelf::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ style.JustifySelf()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/left_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/left_custom.cc index 6dceaf9..e9f4074e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/left_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/left_custom.cc
@@ -15,7 +15,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Left::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -40,5 +40,5 @@ layout_object); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/letter_spacing_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/letter_spacing_custom.cc index 0214ca7..612ec5b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/letter_spacing_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/letter_spacing_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* LetterSpacing::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ZoomAdjustedPixelValue(style.LetterSpacing(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/lighting_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/lighting_color_custom.cc index 90e6e0ae..761f4f8b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/lighting_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/lighting_color_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* LightingColor::ParseSingleValue( CSSParserTokenRange& range, @@ -37,5 +37,5 @@ style.LightingColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/line_break_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/line_break_custom.cc index 010d62a..c980562 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/line_break_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/line_break_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/line_break.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* LineBreak::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.GetLineBreak()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/line_height_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/line_height_custom.cc index e92eeef..585a3f2b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/line_height_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/line_height_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* LineHeight::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ return ComputedStyleUtils::ValueForLineHeight(style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/line_height_step_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/line_height_step_custom.cc index 1cf4233..68f5ca4 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/line_height_step_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/line_height_step_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* LineHeightStep::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ZoomAdjustedPixelValue(style.LineHeightStep(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/list_style_image_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/list_style_image_custom.cc index 4b4e795d..597e989 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/list_style_image_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/list_style_image_custom.cc
@@ -11,7 +11,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ListStyleImage::ParseSingleValue( CSSParserTokenRange& range, @@ -37,5 +37,5 @@ state.GetStyleImage(CSSPropertyListStyleImage, value)); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/list_style_position_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/list_style_position_custom.cc index 984c134..f723f944 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/list_style_position_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/list_style_position_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/list_style_position.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ListStylePosition::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.ListStylePosition()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/list_style_type_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/list_style_type_custom.cc index 766f0ec..1e76b7a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/list_style_type_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/list_style_type_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/list_style_type.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ListStyleType::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.ListStyleType()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/margin_block_end_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/margin_block_end_custom.cc index 0992ecd..75e8af0 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/margin_block_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/margin_block_end_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MarginBlockEnd::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/margin_block_start_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/margin_block_start_custom.cc index 19f185c2..92934df9 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/margin_block_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/margin_block_start_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MarginBlockStart::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/margin_bottom_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/margin_bottom_custom.cc index 4fefd39..ed92280 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/margin_bottom_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/margin_bottom_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MarginBottom::ParseSingleValue( CSSParserTokenRange& range, @@ -45,5 +45,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/margin_inline_end_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/margin_inline_end_custom.cc index 6df3e46a..ac895c4 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/margin_inline_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/margin_inline_end_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MarginInlineEnd::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/margin_inline_start_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/margin_inline_start_custom.cc index 52f605bb..058c503 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/margin_inline_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/margin_inline_start_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MarginInlineStart::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/margin_left_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/margin_left_custom.cc index 552dc1e..24e7d79 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/margin_left_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/margin_left_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MarginLeft::ParseSingleValue( CSSParserTokenRange& range, @@ -45,5 +45,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/margin_right_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/margin_right_custom.cc index a629261..6740f711 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/margin_right_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/margin_right_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MarginRight::ParseSingleValue( CSSParserTokenRange& range, @@ -59,5 +59,5 @@ return ZoomAdjustedPixelValue(value, style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/margin_top_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/margin_top_custom.cc index 7b2c22ae..7cac20e2 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/margin_top_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/margin_top_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MarginTop::ParseSingleValue( CSSParserTokenRange& range, @@ -44,5 +44,5 @@ return ZoomAdjustedPixelValue(ToLayoutBox(layout_object)->MarginTop(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/marker_end_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/marker_end_custom.cc index 2b7c51b..092e27b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/marker_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/marker_end_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MarkerEnd::ParseSingleValue( CSSParserTokenRange& range, @@ -31,5 +31,5 @@ return ComputedStyleUtils::ValueForSVGResource(svg_style.MarkerEndResource()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/marker_mid_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/marker_mid_custom.cc index 55859c8..e6f75ae 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/marker_mid_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/marker_mid_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MarkerMid::ParseSingleValue( CSSParserTokenRange& range, @@ -31,5 +31,5 @@ return ComputedStyleUtils::ValueForSVGResource(svg_style.MarkerMidResource()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/marker_start_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/marker_start_custom.cc index 3b6e3f0..8fcf23a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/marker_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/marker_start_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MarkerStart::ParseSingleValue( CSSParserTokenRange& range, @@ -32,5 +32,5 @@ svg_style.MarkerStartResource()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/mask_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/mask_custom.cc index 6ebbef8..c891a09 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/mask_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/mask_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Mask::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -30,5 +30,5 @@ return ComputedStyleUtils::ValueForSVGResource(svg_style.MaskerResource()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/mask_source_type_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/mask_source_type_custom.cc index ede51c9..70c72ab0 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/mask_source_type_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/mask_source_type_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MaskSourceType::ParseSingleValue( CSSParserTokenRange& range, @@ -42,5 +42,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/mask_type_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/mask_type_custom.cc index bde23df..ce1c69b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/mask_type_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/mask_type_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/mask_type.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MaskType::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(svg_style.MaskType()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/max_block_size_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/max_block_size_custom.cc index 66b75f2..caaad31ad7 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/max_block_size_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/max_block_size_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MaxBlockSize::ParseSingleValue( CSSParserTokenRange& range, @@ -16,5 +16,5 @@ return css_parsing_utils::ConsumeMaxWidthOrHeight(range, context); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/max_height_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/max_height_custom.cc index 9266783..76456f5d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/max_height_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/max_height_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MaxHeight::ParseSingleValue( CSSParserTokenRange& range, @@ -31,5 +31,5 @@ return ComputedStyleUtils::ZoomAdjustedPixelValueForLength(max_height, style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/max_inline_size_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/max_inline_size_custom.cc index d0aff74..b0a8c1d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/max_inline_size_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/max_inline_size_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MaxInlineSize::ParseSingleValue( CSSParserTokenRange& range, @@ -16,5 +16,5 @@ return css_parsing_utils::ConsumeMaxWidthOrHeight(range, context); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/max_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/max_width_custom.cc index 382b1794..5dd083db 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/max_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/max_width_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MaxWidth::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -30,5 +30,5 @@ return ComputedStyleUtils::ZoomAdjustedPixelValueForLength(max_width, style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/min_block_size_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/min_block_size_custom.cc index 74b5883..b5b6278 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/min_block_size_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/min_block_size_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MinBlockSize::ParseSingleValue( CSSParserTokenRange& range, @@ -17,5 +17,5 @@ return css_parsing_utils::ConsumeWidthOrHeight(range, context); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/min_height_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/min_height_custom.cc index 5e58ad9..0f91093 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/min_height_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/min_height_custom.cc
@@ -13,7 +13,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MinHeight::ParseSingleValue( CSSParserTokenRange& range, @@ -35,5 +35,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/min_inline_size_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/min_inline_size_custom.cc index f4fb992..3f207f0 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/min_inline_size_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/min_inline_size_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MinInlineSize::ParseSingleValue( CSSParserTokenRange& range, @@ -17,5 +17,5 @@ return css_parsing_utils::ConsumeWidthOrHeight(range, context); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/min_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/min_width_custom.cc index 2526e69..a332e0a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/min_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/min_width_custom.cc
@@ -13,7 +13,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MinWidth::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -34,5 +34,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/mix_blend_mode_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/mix_blend_mode_custom.cc index e6453fd8..601297a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/mix_blend_mode_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/mix_blend_mode_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/mix_blend_mode.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* MixBlendMode::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.GetBlendMode()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/object_fit_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/object_fit_custom.cc index fe43af9..13856d7 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/object_fit_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/object_fit_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/object_fit.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ObjectFit::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.GetObjectFit()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/object_position_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/object_position_custom.cc index ebdc69b..52edd49 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/object_position_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/object_position_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ObjectPosition::ParseSingleValue( CSSParserTokenRange& range, @@ -36,5 +36,5 @@ CSSValuePair::kKeepIdenticalValues); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/offset_anchor_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/offset_anchor_custom.cc index e679a19c..f1d20ee3 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/offset_anchor_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/offset_anchor_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { using namespace css_property_parser_helpers; @@ -36,5 +36,5 @@ return ComputedStyleUtils::ValueForPosition(style.OffsetAnchor(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/offset_distance_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/offset_distance_custom.cc index a6643e7..fe0f5b0f 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/offset_distance_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/offset_distance_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/platform/geometry/length.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* OffsetDistance::ParseSingleValue( CSSParserTokenRange& range, @@ -30,5 +30,5 @@ style.OffsetDistance(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/offset_path_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/offset_path_custom.cc index 94c882d3..3146325 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/offset_path_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/offset_path_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* OffsetPath::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ return CSSIdentifierValue::Create(CSSValueNone); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/offset_position_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/offset_position_custom.cc index 9f8bd92..f7fa82f 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/offset_position_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/offset_position_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { using namespace css_property_parser_helpers; @@ -41,5 +41,5 @@ return ComputedStyleUtils::ValueForPosition(style.OffsetPosition(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/offset_rotate_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/offset_rotate_custom.cc index 4014437..de1a31d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/offset_rotate_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/offset_rotate_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* OffsetRotate::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/opacity_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/opacity_custom.cc index bc9a588..39e52b6 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/opacity_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/opacity_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Opacity::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -26,5 +26,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/order_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/order_custom.cc index 486df3d..b8e95bf 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/order_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/order_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Order::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -26,5 +26,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/orphans_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/orphans_custom.cc index 066451a..468c68c 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/orphans_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/orphans_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Orphans::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -26,5 +26,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/outline_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/outline_color_custom.cc index 2b91acb2..aebb8f0 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/outline_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/outline_color_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* OutlineColor::ParseSingleValue( CSSParserTokenRange& range, @@ -45,5 +45,5 @@ style, style.OutlineColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/outline_offset_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/outline_offset_custom.cc index a723a40..a83f5a13 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/outline_offset_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/outline_offset_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* OutlineOffset::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ return ZoomAdjustedPixelValue(style.OutlineOffset(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/outline_style_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/outline_style_custom.cc index 85ebb28..dabcba1 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/outline_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/outline_style_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* OutlineStyle::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -41,5 +41,5 @@ state.Style()->SetOutlineStyle(identifier_value.ConvertTo<EBorderStyle>()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/outline_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/outline_width_custom.cc index f11a147..ce38ee0 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/outline_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/outline_width_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* OutlineWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ZoomAdjustedPixelValue(style.OutlineWidth(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/overflow_anchor_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/overflow_anchor_custom.cc index 44c9069..7bd0665 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/overflow_anchor_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/overflow_anchor_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/overflow_anchor.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* OverflowAnchor::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.OverflowAnchor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/overflow_wrap_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/overflow_wrap_custom.cc index dc9adb5..9bf7fe5 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/overflow_wrap_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/overflow_wrap_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/overflow_wrap.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* OverflowWrap::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.OverflowWrap()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/overflow_x_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/overflow_x_custom.cc index bc9b1e08..46213f1 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/overflow_x_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/overflow_x_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/overflow_x.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* OverflowX::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.OverflowX()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/overflow_y_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/overflow_y_custom.cc index 267cf121..f006aee 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/overflow_y_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/overflow_y_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/overflow_y.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* OverflowY::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.OverflowY()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/overscroll_behavior_x_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/overscroll_behavior_x_custom.cc index b175e01..257dd525 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/overscroll_behavior_x_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/overscroll_behavior_x_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/overscroll_behavior_x.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* OverscrollBehaviorX::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.OverscrollBehaviorX()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/overscroll_behavior_y_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/overscroll_behavior_y_custom.cc index ce62081c..69800af 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/overscroll_behavior_y_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/overscroll_behavior_y_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/overscroll_behavior_y.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* OverscrollBehaviorY::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.OverscrollBehaviorY()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/padding_block_end_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/padding_block_end_custom.cc index a1bd7f2..499c6ea 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/padding_block_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/padding_block_end_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* PaddingBlockEnd::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/padding_block_start_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/padding_block_start_custom.cc index d499a56..ebfbe2bc 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/padding_block_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/padding_block_start_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* PaddingBlockStart::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/padding_bottom_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/padding_bottom_custom.cc index ff0b238c..9154c408 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/padding_bottom_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/padding_bottom_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* PaddingBottom::ParseSingleValue( CSSParserTokenRange& range, @@ -44,5 +44,5 @@ ToLayoutBox(layout_object)->ComputedCSSPaddingBottom(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/padding_inline_end_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/padding_inline_end_custom.cc index b469364..714efdb9 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/padding_inline_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/padding_inline_end_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* PaddingInlineEnd::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/padding_inline_start_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/padding_inline_start_custom.cc index 23bc4c7..5e9e128 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/padding_inline_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/padding_inline_start_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* PaddingInlineStart::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/padding_left_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/padding_left_custom.cc index fd6184b..9620b07 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/padding_left_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/padding_left_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* PaddingLeft::ParseSingleValue( CSSParserTokenRange& range, @@ -44,5 +44,5 @@ ToLayoutBox(layout_object)->ComputedCSSPaddingLeft(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/padding_right_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/padding_right_custom.cc index 0d1fc9598..848f041 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/padding_right_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/padding_right_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* PaddingRight::ParseSingleValue( CSSParserTokenRange& range, @@ -44,5 +44,5 @@ ToLayoutBox(layout_object)->ComputedCSSPaddingRight(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/padding_top_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/padding_top_custom.cc index df617e6..4624004 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/padding_top_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/padding_top_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* PaddingTop::ParseSingleValue( CSSParserTokenRange& range, @@ -44,5 +44,5 @@ ToLayoutBox(layout_object)->ComputedCSSPaddingTop(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/page_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/page_custom.cc index 09bdedac..68be30e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/page_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/page_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Page::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -17,5 +17,5 @@ return css_property_parser_helpers::ConsumeCustomIdent(range, context); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/paint_order_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/paint_order_custom.cc index a3c6a6b..6a0e2fd 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/paint_order_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/paint_order_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* PaintOrder::ParseSingleValue( CSSParserTokenRange& range, @@ -102,5 +102,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/perspective_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/perspective_custom.cc index cf609be25..19f423c3 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/perspective_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/perspective_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Perspective::ParseSingleValue( CSSParserTokenRange& range, @@ -48,5 +48,5 @@ return ZoomAdjustedPixelValue(style.Perspective(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/perspective_origin_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/perspective_origin_custom.cc index 43c40d6..dc142e7 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/perspective_origin_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/perspective_origin_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* PerspectiveOrigin::ParseSingleValue( CSSParserTokenRange& range, @@ -58,5 +58,5 @@ } } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/pointer_events_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/pointer_events_custom.cc index c501f1a..f7b56248 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/pointer_events_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/pointer_events_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/pointer_events.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* PointerEvents::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.PointerEvents()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/position_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/position_custom.cc index 1b4c438..68fc098a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/position_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/position_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/position.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Position::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -21,5 +21,5 @@ state.Style()->SetPosition(state.ParentStyle()->GetPosition()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/quotes_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/quotes_custom.cc index 63a78c5..9524d5e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/quotes_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/quotes_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Quotes::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -53,5 +53,5 @@ return CSSIdentifierValue::Create(CSSValueNone); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/r_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/r_custom.cc index 013f3f8..7f3111a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/r_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/r_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* R::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -27,5 +27,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/resize_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/resize_custom.cc index 646a4d6..f2cefd9 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/resize_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/resize_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/frame/web_feature.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Resize::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -37,5 +37,5 @@ state.Style()->SetResize(r); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/right_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/right_custom.cc index 4afff5e4..3ea4279 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/right_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/right_custom.cc
@@ -15,7 +15,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Right::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -40,5 +40,5 @@ layout_object); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/rotate_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/rotate_custom.cc index 8c2a4742..69367f2 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/rotate_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/rotate_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Rotate::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -100,5 +100,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/row_gap_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/row_gap_custom.cc index 1bebe44..5b5c1df1 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/row_gap_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/row_gap_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* RowGap::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -28,5 +28,5 @@ return ComputedStyleUtils::ValueForGapLength(style.RowGap(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/rx_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/rx_custom.cc index c78143a..231414c 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/rx_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/rx_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Rx::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -29,5 +29,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/ry_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/ry_custom.cc index 3f309368..d8f95008 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/ry_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/ry_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Ry::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -29,5 +29,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scale_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scale_custom.cc index c367f25..461a180 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scale_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scale_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Scale::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -58,5 +58,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_behavior_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_behavior_custom.cc index 16f8119..ece75e0 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_behavior_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_behavior_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/scroll_behavior.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollBehavior::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.GetScrollBehavior()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_customization_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_customization_custom.cc index 907c6275..8f1e4e4 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_customization_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_customization_custom.cc
@@ -32,7 +32,7 @@ } } // namespace -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollCustomization::ParseSingleValue( CSSParserTokenRange& range, @@ -69,5 +69,5 @@ style.ScrollCustomization()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_end_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_end_custom.cc index 32c0f47..a835df3 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_end_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollMarginBlockEnd::ParseSingleValue( CSSParserTokenRange& range, @@ -20,5 +20,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_start_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_start_custom.cc index 0ad90c1..472e5b7 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_block_start_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollMarginBlockStart::ParseSingleValue( CSSParserTokenRange& range, @@ -20,5 +20,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_bottom_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_bottom_custom.cc index cefb9fea..978ebde 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_bottom_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_bottom_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollMarginBottom::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ZoomAdjustedPixelValue(style.ScrollMarginBottom(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_end_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_end_custom.cc index dfd3761..7f17fd3 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_end_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollMarginInlineEnd::ParseSingleValue( CSSParserTokenRange& range, @@ -20,5 +20,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_start_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_start_custom.cc index e6d8d9ee..cab85ff 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_inline_start_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollMarginInlineStart::ParseSingleValue( CSSParserTokenRange& range, @@ -20,5 +20,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_left_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_left_custom.cc index 9de5464..a7fe021 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_left_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_left_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollMarginLeft::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ZoomAdjustedPixelValue(style.ScrollMarginLeft(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_right_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_right_custom.cc index dceb668..9769d15 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_right_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_right_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollMarginRight::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ZoomAdjustedPixelValue(style.ScrollMarginRight(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_top_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_top_custom.cc index 21ecb58..5a9a4d4 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_top_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_margin_top_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollMarginTop::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ZoomAdjustedPixelValue(style.ScrollMarginTop(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_end_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_end_custom.cc index 9b0c856..d4d9484 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_end_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollPaddingBlockEnd::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_start_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_start_custom.cc index 695ee2e..1a2ae5d0 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_block_start_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollPaddingBlockStart::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_bottom_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_bottom_custom.cc index 7938e01..fbce2ba 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_bottom_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_bottom_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollPaddingBottom::ParseSingleValue( CSSParserTokenRange& range, @@ -30,5 +30,5 @@ style.ScrollPaddingBottom(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_end_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_end_custom.cc index 0502483..9bb8dd6 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_end_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollPaddingInlineEnd::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_start_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_start_custom.cc index 73b272c..ee82bf5 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_inline_start_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollPaddingInlineStart::ParseSingleValue( CSSParserTokenRange& range, @@ -21,5 +21,5 @@ css_property_parser_helpers::UnitlessQuirk::kForbid); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_left_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_left_custom.cc index 340850c..d0a38cc 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_left_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_left_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollPaddingLeft::ParseSingleValue( CSSParserTokenRange& range, @@ -30,5 +30,5 @@ style.ScrollPaddingLeft(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_right_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_right_custom.cc index 06f80fe..987d1dc 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_right_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_right_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollPaddingRight::ParseSingleValue( CSSParserTokenRange& range, @@ -30,5 +30,5 @@ style.ScrollPaddingRight(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_top_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_top_custom.cc index 73e98797..6636efca 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_top_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_padding_top_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollPaddingTop::ParseSingleValue( CSSParserTokenRange& range, @@ -30,5 +30,5 @@ style.ScrollPaddingTop(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_snap_align_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_snap_align_custom.cc index 9ca4737..3fc3e66 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_snap_align_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_snap_align_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollSnapAlign::ParseSingleValue( CSSParserTokenRange& range, @@ -42,5 +42,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_snap_stop_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_snap_stop_custom.cc index 072376f..38b7955 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_snap_stop_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_snap_stop_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/scroll_snap_stop.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollSnapStop::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.ScrollSnapStop()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/scroll_snap_type_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/scroll_snap_type_custom.cc index 9801c87..edc61c33 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/scroll_snap_type_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/scroll_snap_type_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ScrollSnapType::ParseSingleValue( CSSParserTokenRange& range, @@ -44,5 +44,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/shape_image_threshold_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/shape_image_threshold_custom.cc index 54f3fc1..b9a90b4 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/shape_image_threshold_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/shape_image_threshold_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ShapeImageThreshold::ParseSingleValue( CSSParserTokenRange& range, @@ -27,5 +27,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/shape_margin_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/shape_margin_custom.cc index 036a917..a541cd5 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/shape_margin_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/shape_margin_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ShapeMargin::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ return CSSValue::Create(style.ShapeMargin(), style.EffectiveZoom()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/shape_outside_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/shape_outside_custom.cc index 8599e22..27434eaa 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/shape_outside_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/shape_outside_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { using namespace css_property_parser_helpers; @@ -47,5 +47,5 @@ return ComputedStyleUtils::ValueForShape(style, style.ShapeOutside()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/shape_rendering_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/shape_rendering_custom.cc index 901f7de5..707fc51 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/shape_rendering_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/shape_rendering_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/shape_rendering.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ShapeRendering::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(svg_style.ShapeRendering()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/size_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/size_custom.cc index 5dccd38..1c6af681 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/size_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/size_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { static CSSValue* ConsumePageSize(CSSParserTokenRange& range) { return css_property_parser_helpers::ConsumeIdent< @@ -147,5 +147,5 @@ state.Style()->SetPageSize(size); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/speak_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/speak_custom.cc index 74983d0f..46db889 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/speak_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/speak_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/speak.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Speak::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.Speak()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/stop_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/stop_color_custom.cc index f270c84..ff92bf9 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/stop_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/stop_color_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* StopColor::ParseSingleValue( CSSParserTokenRange& range, @@ -36,5 +36,5 @@ return ComputedStyleUtils::CurrentColorOrValidColor(style, style.StopColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/stop_opacity_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/stop_opacity_custom.cc index 77fef5a..8c34280 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/stop_opacity_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/stop_opacity_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* StopOpacity::ParseSingleValue( CSSParserTokenRange& range, @@ -27,5 +27,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/stroke_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/stroke_custom.cc index f65f7f0..2a48ffc 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/stroke_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/stroke_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Stroke::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -27,5 +27,5 @@ svg_style.StrokePaint(), style.GetColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/stroke_dasharray_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/stroke_dasharray_custom.cc index 56a426d..214fb673 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/stroke_dasharray_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/stroke_dasharray_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* StrokeDasharray::ParseSingleValue( CSSParserTokenRange& range, @@ -44,5 +44,5 @@ *svg_style.StrokeDashArray(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/stroke_dashoffset_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/stroke_dashoffset_custom.cc index ada21b2..c0e1406 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/stroke_dashoffset_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/stroke_dashoffset_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* StrokeDashoffset::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ style.StrokeDashOffset(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/stroke_linecap_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/stroke_linecap_custom.cc index 72f6939..97d000a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/stroke_linecap_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/stroke_linecap_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/stroke_linecap.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* StrokeLinecap::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(svg_style.CapStyle()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/stroke_linejoin_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/stroke_linejoin_custom.cc index 1ee5aa39..74dc509 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/stroke_linejoin_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/stroke_linejoin_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/stroke_linejoin.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* StrokeLinejoin::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(svg_style.JoinStyle()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/stroke_miterlimit_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/stroke_miterlimit_custom.cc index 42460b53..ba2f77b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/stroke_miterlimit_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/stroke_miterlimit_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* StrokeMiterlimit::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/stroke_opacity_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/stroke_opacity_custom.cc index f2c6a86..0f4f7ff 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/stroke_opacity_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/stroke_opacity_custom.cc
@@ -11,7 +11,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* StrokeOpacity::ParseSingleValue( CSSParserTokenRange& range, @@ -30,5 +30,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/stroke_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/stroke_width_custom.cc index 1e9a8ead..7c90d53 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/stroke_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/stroke_width_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* StrokeWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -33,5 +33,5 @@ return CSSValue::Create(length, style.EffectiveZoom()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/tab_size_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/tab_size_custom.cc index 03d2fddd..6ff737c2 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/tab_size_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/tab_size_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TabSize::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -34,5 +34,5 @@ : CSSPrimitiveValue::UnitType::kPixels); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/table_layout_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/table_layout_custom.cc index 33527a3..028428c4 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/table_layout_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/table_layout_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/table_layout.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TableLayout::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.TableLayout()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_align_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_align_custom.cc index 4b614bd..4377366 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_align_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_align_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/text_align.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextAlign::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -43,5 +43,5 @@ } } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_align_last_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_align_last_custom.cc index ff84175..37a2daf 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_align_last_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_align_last_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/text_align_last.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextAlignLast::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.TextAlignLast()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_anchor_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_anchor_custom.cc index 4ab7953..b6fe998 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_anchor_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_anchor_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/text_anchor.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextAnchor::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(svg_style.TextAnchor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_combine_upright_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_combine_upright_custom.cc index f219d0d4..36087bf3 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_combine_upright_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_combine_upright_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/text_combine_upright.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextCombineUpright::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.TextCombine()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_decoration_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_decoration_color_custom.cc index e4bdf62..e7d5215 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_decoration_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_decoration_color_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextDecorationColor::ParseSingleValue( CSSParserTokenRange& range, @@ -38,5 +38,5 @@ style, style.TextDecorationColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_decoration_line_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_decoration_line_custom.cc index ab669cd..c6b25d1 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_decoration_line_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_decoration_line_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextDecorationLine::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ style.GetTextDecoration()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_decoration_skip_ink_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_decoration_skip_ink_custom.cc index ff99185..b7786fcf 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_decoration_skip_ink_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_decoration_skip_ink_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextDecorationSkipInk::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -20,5 +20,5 @@ style.TextDecorationSkipInk()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_decoration_style_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_decoration_style_custom.cc index 19bd6b59..b5afc9a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_decoration_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_decoration_style_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextDecorationStyle::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -20,5 +20,5 @@ style.TextDecorationStyle()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_indent_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_indent_custom.cc index 163e0ba2..a581d1e6 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_indent_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_indent_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextIndent::ParseSingleValue( CSSParserTokenRange& range, @@ -122,5 +122,5 @@ state.Style()->SetTextIndentType(text_indent_type_value); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_justify_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_justify_custom.cc index 3d90c41..14ea467 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_justify_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_justify_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/text_justify.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextJustify::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.GetTextJustify()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_orientation_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_orientation_custom.cc index 80680e0..e07fff1 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_orientation_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_orientation_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/text_orientation.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextOrientation::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -22,5 +22,5 @@ ToCSSIdentifierValue(value).ConvertTo<ETextOrientation>()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_overflow_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_overflow_custom.cc index 3a2b259..7d8863c 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_overflow_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_overflow_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextOverflow::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -20,5 +20,5 @@ return CSSIdentifierValue::Create(CSSValueClip); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_rendering_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_rendering_custom.cc index e06ef36..7dba689 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_rendering_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_rendering_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextRendering::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -18,5 +18,5 @@ return CSSIdentifierValue::Create(style.GetFontDescription().TextRendering()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_shadow_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_shadow_custom.cc index 153013d..2c4a857 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_shadow_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_shadow_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextShadow::ParseSingleValue( CSSParserTokenRange& range, @@ -30,5 +30,5 @@ false); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_size_adjust_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_size_adjust_custom.cc index 1156435..865b9276 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_size_adjust_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_size_adjust_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextSizeAdjust::ParseSingleValue( CSSParserTokenRange& range, @@ -35,5 +35,5 @@ CSSPrimitiveValue::UnitType::kPercentage); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_transform_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_transform_custom.cc index 84332fa..2a2a0f7d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_transform_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_transform_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/text_transform.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TextTransform::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.TextTransform()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_underline_position_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_underline_position_custom.cc index 56c3747..912e260 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_underline_position_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_underline_position_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { // auto | [ under || [ left | right ] ] const CSSValue* TextUnderlinePosition::ParseSingleValue( @@ -70,5 +70,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/top_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/top_custom.cc index dbf804b1..3432849 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/top_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/top_custom.cc
@@ -15,7 +15,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Top::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -40,5 +40,5 @@ layout_object); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/touch_action_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/touch_action_custom.cc index a5a84b0..57897d6 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/touch_action_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/touch_action_custom.cc
@@ -33,7 +33,7 @@ } } // namespace -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TouchAction::ParseSingleValue( CSSParserTokenRange& range, @@ -74,5 +74,5 @@ return ComputedStyleUtils::TouchActionFlagsToCSSValue(style.GetTouchAction()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/transform_box_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/transform_box_custom.cc index 137c2b0..50dfff86 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/transform_box_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/transform_box_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/transform_box.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TransformBox::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.TransformBox()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/transform_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/transform_custom.cc index 1aa9aad..e419eb8 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/transform_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/transform_custom.cc
@@ -14,7 +14,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Transform::ParseSingleValue( CSSParserTokenRange& range, @@ -37,5 +37,5 @@ return ComputedStyleUtils::ComputedTransform(layout_object, style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/transform_origin_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/transform_origin_custom.cc index f813c3f9..e5fd8d9 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/transform_origin_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/transform_origin_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TransformOrigin::ParseSingleValue( CSSParserTokenRange& range, @@ -71,5 +71,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/transform_style_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/transform_style_custom.cc index e167986..60712b2 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/transform_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/transform_style_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/transform_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TransformStyle::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -19,5 +19,5 @@ : CSSValueFlat); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/transition_delay_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/transition_delay_custom.cc index d5e95c7f..55a077e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/transition_delay_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/transition_delay_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/platform/geometry/length.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TransitionDelay::ParseSingleValue( CSSParserTokenRange& range, @@ -37,5 +37,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/transition_duration_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/transition_duration_custom.cc index c8f342b9..dadf1e0 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/transition_duration_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/transition_duration_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/platform/geometry/length.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TransitionDuration::ParseSingleValue( CSSParserTokenRange& range, @@ -37,5 +37,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/transition_property_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/transition_property_custom.cc index 6b2d78c6..407674c7 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/transition_property_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/transition_property_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TransitionProperty::ParseSingleValue( CSSParserTokenRange& range, @@ -39,5 +39,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/transition_timing_function_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/transition_timing_function_custom.cc index 1b74cf8..50b2a1d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/transition_timing_function_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/transition_timing_function_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* TransitionTimingFunction::ParseSingleValue( CSSParserTokenRange& range, @@ -36,5 +36,5 @@ return value; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/translate_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/translate_custom.cc index 0929e52..e513d0e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/translate_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/translate_custom.cc
@@ -14,7 +14,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Translate::ParseSingleValue( CSSParserTokenRange& range, @@ -78,5 +78,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/unicode_bidi_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/unicode_bidi_custom.cc index 847227c..8680d3e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/unicode_bidi_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/unicode_bidi_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/unicode_bidi.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* UnicodeBidi::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.GetUnicodeBidi()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/user_select_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/user_select_custom.cc index 2c72d4e..5fca6fe 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/user_select_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/user_select_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/user_select.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* UserSelect::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.UserSelect()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/vector_effect_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/vector_effect_custom.cc index 24509297..2c65fd5 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/vector_effect_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/vector_effect_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/vector_effect.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* VectorEffect::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(svg_style.VectorEffect()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/vertical_align_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/vertical_align_custom.cc index de2fea1..33acfa7 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/vertical_align_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/vertical_align_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* VerticalAlign::ParseSingleValue( CSSParserTokenRange& range, @@ -80,5 +80,5 @@ } } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/visibility_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/visibility_custom.cc index 674c338..bf661350 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/visibility_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/visibility_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/visibility.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Visibility::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.Visibility()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_app_region_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_app_region_custom.cc index acf27da..b14f67f6 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_app_region_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_app_region_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitAppRegion::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -38,5 +38,5 @@ state.GetDocument().SetHasAnnotatedRegions(true); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_appearance_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_appearance_custom.cc index 15407ff..e548064b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_appearance_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_appearance_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitAppearance::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -18,5 +18,5 @@ return CSSIdentifierValue::Create(style.Appearance()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_border_horizontal_spacing_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_border_horizontal_spacing_custom.cc index 11cce08..965ce1c 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_border_horizontal_spacing_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_border_horizontal_spacing_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitBorderHorizontalSpacing::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ZoomAdjustedPixelValue(style.HorizontalBorderSpacing(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_border_image_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_border_image_custom.cc index 9f0b6e0e..ae40d893 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_border_image_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_border_image_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitBorderImage::ParseSingleValue( CSSParserTokenRange& range, @@ -35,5 +35,5 @@ state.Style()->SetBorderImage(image); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_border_vertical_spacing_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_border_vertical_spacing_custom.cc index 6dc3191..b0fd820 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_border_vertical_spacing_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_border_vertical_spacing_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitBorderVerticalSpacing::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ return ZoomAdjustedPixelValue(style.VerticalBorderSpacing(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_align_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_align_custom.cc index faeb97d..5541d46 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_align_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_align_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_box_align.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitBoxAlign::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.BoxAlign()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_decoration_break_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_decoration_break_custom.cc index f2e3bfc..25bc591 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_decoration_break_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_decoration_break_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitBoxDecorationBreak::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -20,5 +20,5 @@ return CSSIdentifierValue::Create(CSSValueClone); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_direction_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_direction_custom.cc index 9b65e12..9c27821 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_direction_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_direction_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_box_direction.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitBoxDirection::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.BoxDirection()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_flex_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_flex_custom.cc index e3738d7..5504909e 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_flex_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_flex_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitBoxFlex::ParseSingleValue( CSSParserTokenRange& range, @@ -27,5 +27,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_ordinal_group_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_ordinal_group_custom.cc index cc8496b2..502aaef 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_ordinal_group_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_ordinal_group_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitBoxOrdinalGroup::ParseSingleValue( CSSParserTokenRange& range, @@ -27,5 +27,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_orient_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_orient_custom.cc index 82dd04f1..ec1ace9 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_orient_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_orient_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_box_orient.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitBoxOrient::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.BoxOrient()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_pack_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_pack_custom.cc index 9d8c74f..834b6e3 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_pack_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_pack_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_box_pack.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitBoxPack::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.BoxPack()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_reflect_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_reflect_custom.cc index 34af86c..187e7478 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_box_reflect_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_box_reflect_custom.cc
@@ -43,7 +43,7 @@ } } // namespace -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitBoxReflect::ParseSingleValue( CSSParserTokenRange& range, @@ -61,5 +61,5 @@ return ComputedStyleUtils::ValueForReflection(style.BoxReflect(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_font_size_delta_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_font_size_delta_custom.cc index 0e67da6..ed33b92 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_font_size_delta_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_font_size_delta_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitFontSizeDelta::ParseSingleValue( CSSParserTokenRange& range, @@ -19,5 +19,5 @@ css_property_parser_helpers::UnitlessQuirk::kAllow); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_font_smoothing_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_font_smoothing_custom.cc index c6239aa..7efe52b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_font_smoothing_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_font_smoothing_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitFontSmoothing::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -18,5 +18,5 @@ return CSSIdentifierValue::Create(style.GetFontDescription().FontSmoothing()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_highlight_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_highlight_custom.cc index c00c8fe..04f5bc2 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_highlight_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_highlight_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitHighlight::ParseSingleValue( CSSParserTokenRange& range, @@ -31,5 +31,5 @@ return CSSStringValue::Create(style.Highlight()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_hyphenate_character_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_hyphenate_character_custom.cc index 65a47bc..8009063 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_hyphenate_character_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_hyphenate_character_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitHyphenateCharacter::ParseSingleValue( CSSParserTokenRange& range, @@ -31,5 +31,5 @@ return CSSStringValue::Create(style.HyphenationString()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_line_break_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_line_break_custom.cc index e294089..3e56971 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_line_break_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_line_break_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_line_break.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitLineBreak::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.GetLineBreak()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_line_clamp_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_line_clamp_custom.cc index f7edba3..6bb0bb1b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_line_clamp_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_line_clamp_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitLineClamp::ParseSingleValue( CSSParserTokenRange& range, @@ -30,5 +30,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_locale_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_locale_custom.cc index 11bf67a0..e603549f 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_locale_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_locale_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitLocale::ParseSingleValue( CSSParserTokenRange& range, @@ -42,5 +42,5 @@ } } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_after_collapse_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_after_collapse_custom.cc index 985fbc80..cc9a583 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_after_collapse_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_after_collapse_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_margin_after_collapse.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMarginAfterCollapse::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.MarginAfterCollapse()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_before_collapse_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_before_collapse_custom.cc index 10fb470..d5aed0b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_before_collapse_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_before_collapse_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_margin_before_collapse.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMarginBeforeCollapse::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.MarginBeforeCollapse()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_bottom_collapse_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_bottom_collapse_custom.cc index 3965797b..096a6a5 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_bottom_collapse_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_bottom_collapse_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_margin_bottom_collapse.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMarginBottomCollapse::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.MarginAfterCollapse()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_top_collapse_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_top_collapse_custom.cc index c2b5350e1..b249f9a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_top_collapse_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_margin_top_collapse_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_margin_top_collapse.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMarginTopCollapse::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.MarginBeforeCollapse()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_outset_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_outset_custom.cc index c17e666..f06733d 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_outset_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_outset_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMaskBoxImageOutset::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ style.MaskBoxImage().Outset(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_repeat_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_repeat_custom.cc index b04e5dc..814a43b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_repeat_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_repeat_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMaskBoxImageRepeat::ParseSingleValue( CSSParserTokenRange& range, @@ -27,5 +27,5 @@ return ComputedStyleUtils::ValueForNinePieceImageRepeat(style.MaskBoxImage()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_slice_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_slice_custom.cc index 30b1741c..93383d2 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_slice_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_slice_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMaskBoxImageSlice::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ return ComputedStyleUtils::ValueForNinePieceImageSlice(style.MaskBoxImage()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_source_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_source_custom.cc index 0ceff06..dae0afee 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_source_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_source_custom.cc
@@ -11,7 +11,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMaskBoxImageSource::ParseSingleValue( CSSParserTokenRange& range, @@ -37,5 +37,5 @@ state.GetStyleImage(CSSPropertyWebkitMaskBoxImageSource, value)); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_width_custom.cc index 2639fa5b0..5480dac2 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_box_image_width_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMaskBoxImageWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -28,5 +28,5 @@ style.MaskBoxImage().BorderSlices(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_clip_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_clip_custom.cc index 9e72f77..6b4721c4 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_clip_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_clip_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMaskClip::ParseSingleValue( CSSParserTokenRange& range, @@ -36,5 +36,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_composite_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_composite_custom.cc index 6350106..65aa267 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_composite_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_composite_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMaskComposite::ParseSingleValue( CSSParserTokenRange& range, @@ -31,5 +31,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_image_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_image_custom.cc index 68a4b0d..07f34cb 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_image_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_image_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMaskImage::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ComputedStyleUtils::BackgroundImageOrWebkitMaskImage(fill_layer); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_origin_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_origin_custom.cc index 69f75db9..1ef8a4b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_origin_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_origin_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMaskOrigin::ParseSingleValue( CSSParserTokenRange& range, @@ -36,5 +36,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_position_x_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_position_x_custom.cc index 04b94b8..5de6d2e0 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_position_x_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_position_x_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMaskPositionX::ParseSingleValue( CSSParserTokenRange& range, @@ -33,5 +33,5 @@ style, curr_layer); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_position_y_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_position_y_custom.cc index 8d61e283..1327489a9 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_position_y_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_position_y_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMaskPositionY::ParseSingleValue( CSSParserTokenRange& range, @@ -33,5 +33,5 @@ style, curr_layer); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_size_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_size_custom.cc index d26288a..2f6565b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_size_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_mask_size_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitMaskSize::ParseSingleValue( CSSParserTokenRange& range, @@ -30,5 +30,5 @@ return ComputedStyleUtils::BackgroundImageOrWebkitMaskSize(style, fill_layer); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_perspective_origin_x_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_perspective_origin_x_custom.cc index 5fd5eaea..8b2599d0 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_perspective_origin_x_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_perspective_origin_x_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css_value_keywords.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitPerspectiveOriginX::ParseSingleValue( CSSParserTokenRange& range, @@ -20,5 +20,5 @@ range, context.Mode()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_perspective_origin_y_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_perspective_origin_y_custom.cc index 32532f0172..3b4020f 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_perspective_origin_y_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_perspective_origin_y_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css_value_keywords.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitPerspectiveOriginY::ParseSingleValue( CSSParserTokenRange& range, @@ -20,5 +20,5 @@ range, context.Mode()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_print_color_adjust_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_print_color_adjust_custom.cc index fd9a805f..6f2f4de 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_print_color_adjust_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_print_color_adjust_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_print_color_adjust.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitPrintColorAdjust::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.PrintColorAdjust()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_rtl_ordering_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_rtl_ordering_custom.cc index 7b95186..7419992 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_rtl_ordering_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_rtl_ordering_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_rtl_ordering.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitRtlOrdering::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -18,5 +18,5 @@ : CSSValueLogical); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_ruby_position_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_ruby_position_custom.cc index 79cfda5..27992bae 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_ruby_position_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_ruby_position_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_ruby_position.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitRubyPosition::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.GetRubyPosition()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_tap_highlight_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_tap_highlight_color_custom.cc index 21f937d..f438a4b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_tap_highlight_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_tap_highlight_color_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitTapHighlightColor::ParseSingleValue( CSSParserTokenRange& range, @@ -37,5 +37,5 @@ style, style.TapHighlightColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_combine_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_combine_custom.cc index d4c3ec4..ba24bd2 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_combine_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_combine_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitTextCombine::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -20,5 +20,5 @@ return CSSIdentifierValue::Create(style.TextCombine()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_decorations_in_effect_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_decorations_in_effect_custom.cc index 37ef5ec0..af03a24 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_decorations_in_effect_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_decorations_in_effect_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitTextDecorationsInEffect::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ style.TextDecorationsInEffect()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_color_custom.cc index 320c1dd..fa835640 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_color_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitTextEmphasisColor::ParseSingleValue( CSSParserTokenRange& range, @@ -39,5 +39,5 @@ style, style.TextEmphasisColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_position_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_position_custom.cc index 37033f0..68079e5a9 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_position_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_position_custom.cc
@@ -13,7 +13,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { // [ over | under ] && [ right | left ]? // If [ right | left ] is omitted, it defaults to right. @@ -92,5 +92,5 @@ return list; } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_style_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_style_custom.cc index 2a02906..6468e778 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_style_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitTextEmphasisStyle::ParseSingleValue( CSSParserTokenRange& range, @@ -137,5 +137,5 @@ } } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_fill_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_fill_color_custom.cc index d61b991..bb214a6 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_fill_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_fill_color_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitTextFillColor::ParseSingleValue( CSSParserTokenRange& range, @@ -39,5 +39,5 @@ style.TextFillColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_orientation_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_orientation_custom.cc index fa32fe3..354ead77 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_orientation_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_orientation_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitTextOrientation::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -26,5 +26,5 @@ ToCSSIdentifierValue(value).ConvertTo<ETextOrientation>()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_security_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_security_custom.cc index 4388ee02..4fc247e1 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_security_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_security_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_text_security.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitTextSecurity::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.TextSecurity()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_stroke_color_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_stroke_color_custom.cc index 33d0bfa9..1da797d6 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_stroke_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_stroke_color_custom.cc
@@ -13,7 +13,7 @@ class CSSParserLocalContext; -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitTextStrokeColor::ParseSingleValue( CSSParserTokenRange& range, @@ -42,5 +42,5 @@ style.TextStrokeColor()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_stroke_width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_stroke_width_custom.cc index b5ccbdf..5623d1b 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_stroke_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_stroke_width_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitTextStrokeWidth::ParseSingleValue( CSSParserTokenRange& range, @@ -29,5 +29,5 @@ return ZoomAdjustedPixelValue(style.TextStrokeWidth(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_transform_origin_x_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_transform_origin_x_custom.cc index 0d1263a..5b3f9696 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_transform_origin_x_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_transform_origin_x_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css_value_keywords.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitTransformOriginX::ParseSingleValue( CSSParserTokenRange& range, @@ -20,5 +20,5 @@ range, context.Mode()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_transform_origin_y_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_transform_origin_y_custom.cc index 96317b7..0d0d1f3f 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_transform_origin_y_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_transform_origin_y_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/css_value_keywords.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitTransformOriginY::ParseSingleValue( CSSParserTokenRange& range, @@ -20,5 +20,5 @@ range, context.Mode()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_transform_origin_z_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_transform_origin_z_custom.cc index 41deb18f..d417dd4 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_transform_origin_z_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_transform_origin_z_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitTransformOriginZ::ParseSingleValue( CSSParserTokenRange& range, @@ -18,5 +18,5 @@ kValueRangeAll); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_user_drag_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_user_drag_custom.cc index 0ddc3d4..284a76c6 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_user_drag_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_user_drag_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_user_drag.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitUserDrag::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.UserDrag()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_user_modify_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_user_modify_custom.cc index 27ea953..f0ee863 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_user_modify_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_user_modify_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_user_modify.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitUserModify::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.UserModify()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_writing_mode_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_writing_mode_custom.cc index 1aa5e106..bfa1244 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_writing_mode_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_writing_mode_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/webkit_writing_mode.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WebkitWritingMode::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -22,5 +22,5 @@ ToCSSIdentifierValue(value).ConvertTo<blink::WritingMode>()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/white_space_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/white_space_custom.cc index 5ee7802..d3536122 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/white_space_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/white_space_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/white_space.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WhiteSpace::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.WhiteSpace()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/widows_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/widows_custom.cc index 7ae3782..cded023 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/widows_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/widows_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Widows::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -26,5 +26,5 @@ CSSPrimitiveValue::UnitType::kNumber); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/width_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/width_custom.cc index a2f6eec8..e48fb20 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/width_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Width::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -39,5 +39,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/will_change_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/will_change_custom.cc index ef9162f..aefee07 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/will_change_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/will_change_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WillChange::ParseSingleValue( CSSParserTokenRange& range, @@ -132,5 +132,5 @@ will_change_contents || state.ParentStyle()->SubtreeWillChangeContents()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/word_break_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/word_break_custom.cc index 90d0875..e1ebe16 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/word_break_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/word_break_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/word_break.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WordBreak::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -16,5 +16,5 @@ return CSSIdentifierValue::Create(style.WordBreak()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/word_spacing_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/word_spacing_custom.cc index 8d8414d..8c0b3067 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/word_spacing_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/word_spacing_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/zoom_adjusted_pixel_value.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WordSpacing::ParseSingleValue( CSSParserTokenRange& range, @@ -26,5 +26,5 @@ return ZoomAdjustedPixelValue(style.WordSpacing(), style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/writing_mode_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/writing_mode_custom.cc index 36b2dd68..7c73eff 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/writing_mode_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/writing_mode_custom.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/css/properties/longhands/writing_mode.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* WritingMode::CSSValueFromComputedStyleInternal( const ComputedStyle& style, @@ -22,5 +22,5 @@ ToCSSIdentifierValue(value).ConvertTo<blink::WritingMode>()); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/x_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/x_custom.cc index fb6309e..2716601 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/x_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/x_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* X::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -27,5 +27,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/y_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/y_custom.cc index 944186b5..eaa456c 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/y_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/y_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Y::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -27,5 +27,5 @@ style); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/z_index_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/z_index_custom.cc index 2acc461..966179c 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/z_index_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/z_index_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* ZIndex::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -31,5 +31,5 @@ CSSPrimitiveValue::UnitType::kInteger); } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/zoom_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/zoom_custom.cc index 941d4ac0..269a610 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/zoom_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/zoom_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSLonghand { +namespace css_longhand { const CSSValue* Zoom::ParseSingleValue(CSSParserTokenRange& range, const CSSParserContext& context, @@ -80,5 +80,5 @@ } } -} // namespace CSSLonghand +} // namespace css_longhand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/animation_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/animation_custom.cc index b0b004e..eb60bd5 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/animation_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/animation_custom.cc
@@ -52,7 +52,7 @@ } } // namespace -namespace CSSShorthand { +namespace css_shorthand { bool Animation::ParseShorthand( bool important, @@ -137,5 +137,5 @@ return list; } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/background_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/background_custom.cc index f1a7f88..a0cd224 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/background_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/background_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool Background::ParseShorthand( bool important, @@ -31,5 +31,5 @@ style, layout_object, styled_node, allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/background_position_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/background_position_custom.cc index 2c6a5e11..cef5bc7 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/background_position_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/background_position_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BackgroundPosition::ParseShorthand( bool important, @@ -50,5 +50,5 @@ *this, style, &style.BackgroundLayers()); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/background_repeat_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/background_repeat_custom.cc index 68aef2a..61a9742 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/background_repeat_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/background_repeat_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BackgroundRepeat::ParseShorthand( bool important, @@ -55,5 +55,5 @@ &style.BackgroundLayers()); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_block_color_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_block_color_custom.cc index 82c7ebbc..1304f37 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_block_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_block_color_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderBlockColor::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_block_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_block_custom.cc index 89834f445..9279753 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_block_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_block_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderBlock::ParseShorthand( bool important, @@ -53,5 +53,5 @@ return value_start; } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_block_end_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_block_end_custom.cc index 8138c1e..78b27a6 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_block_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_block_end_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderBlockEnd::ParseShorthand( bool important, @@ -20,5 +20,5 @@ borderBlockEndShorthand(), important, context, range, properties); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_block_start_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_block_start_custom.cc index 120467b..0b725a37 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_block_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_block_start_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderBlockStart::ParseShorthand( bool important, @@ -20,5 +20,5 @@ borderBlockStartShorthand(), important, context, range, properties); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_block_style_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_block_style_custom.cc index 2e23196..66ad0ee 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_block_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_block_style_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderBlockStyle::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_block_width_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_block_width_custom.cc index 6379c26..bde08ce8 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_block_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_block_width_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderBlockWidth::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_bottom_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_bottom_custom.cc index 247c80c..1c27bc3 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_bottom_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_bottom_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderBottom::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_color_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_color_custom.cc index 5173bb5..92abd04 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_color_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderColor::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_custom.cc index 15fd2cb..9ac731d0 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool Border::ParseShorthand( bool important, @@ -62,5 +62,5 @@ return value; } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_image_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_image_custom.cc index 1bcfa32..7928f69 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_image_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_image_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderImage::ParseShorthand( bool important, @@ -76,5 +76,5 @@ return ComputedStyleUtils::ValueForNinePieceImage(style.BorderImage(), style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_inline_color_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_inline_color_custom.cc index 4440acf1..675514b 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_inline_color_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_inline_color_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderInlineColor::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_inline_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_inline_custom.cc index f57db5e..3d8d791 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_inline_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_inline_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderInline::ParseShorthand( bool important, @@ -53,5 +53,5 @@ return value_start; } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_inline_end_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_inline_end_custom.cc index 5d70bef..bac8986 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_inline_end_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_inline_end_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderInlineEnd::ParseShorthand( bool important, @@ -20,5 +20,5 @@ borderInlineEndShorthand(), important, context, range, properties); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_inline_start_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_inline_start_custom.cc index fbe0036..28a3635 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_inline_start_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_inline_start_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderInlineStart::ParseShorthand( bool important, @@ -20,5 +20,5 @@ borderInlineStartShorthand(), important, context, range, properties); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_inline_style_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_inline_style_custom.cc index 04c3537e..c559d95 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_inline_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_inline_style_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderInlineStyle::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_inline_width_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_inline_width_custom.cc index 1d8237f..76577f27 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_inline_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_inline_width_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderInlineWidth::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_left_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_left_custom.cc index 92ed3ff..af9b336c 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_left_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_left_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderLeft::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_radius_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_radius_custom.cc index 90ee04c3..5f0b7591 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_radius_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_radius_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderRadius::ParseShorthand( bool important, @@ -65,5 +65,5 @@ return ComputedStyleUtils::ValueForBorderRadiusShorthand(style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_right_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_right_custom.cc index cf7da5f..0075cff9 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_right_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_right_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderRight::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_spacing_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_spacing_custom.cc index 100f4fe..73ed905 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_spacing_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_spacing_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderSpacing::ParseShorthand( bool important, @@ -56,5 +56,5 @@ return list; } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_style_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_style_custom.cc index aecd7290..bbbd07c 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_style_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderStyle::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_top_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_top_custom.cc index f721ae42..1dd99d0 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_top_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_top_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderTop::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/border_width_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/border_width_custom.cc index a1685dc..7d8b7b3 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/border_width_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/border_width_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool BorderWidth::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/column_rule_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/column_rule_custom.cc index 2eacf85..7f05677 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/column_rule_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/column_rule_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool ColumnRule::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/columns_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/columns_custom.cc index 3560d67..5968080 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/columns_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/columns_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool Columns::ParseShorthand( bool important, @@ -56,5 +56,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/flex_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/flex_custom.cc index c4ac5e4..443787e 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/flex_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/flex_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool Flex::ParseShorthand(bool important, CSSParserTokenRange& range, @@ -106,5 +106,5 @@ flexShorthand(), style, layout_object, styled_node, allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/flex_flow_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/flex_flow_custom.cc index 1dabf72..4289d1d 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/flex_flow_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/flex_flow_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool FlexFlow::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/font_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/font_custom.cc index 79eec34..1150e5de 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/font_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/font_custom.cc
@@ -225,7 +225,7 @@ } } // namespace -namespace CSSShorthand { +namespace css_shorthand { bool Font::ParseShorthand(bool important, CSSParserTokenRange& range, @@ -247,5 +247,5 @@ return ComputedStyleUtils::ValueForFont(style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/font_variant_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/font_variant_custom.cc index 0ffc8e93..e4fab73 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/font_variant_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/font_variant_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool FontVariant::ParseShorthand( bool important, @@ -124,5 +124,5 @@ style, layout_object, styled_node, allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/gap_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/gap_custom.cc index aa4b6f25..47016d2 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/gap_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/gap_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool Gap::ParseShorthand(bool important, CSSParserTokenRange& range, @@ -46,5 +46,5 @@ gapShorthand(), style, layout_object, styled_node, allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/grid_area_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/grid_area_custom.cc index de8982c8..493bc85c 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/grid_area_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/grid_area_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool GridArea::ParseShorthand( bool important, @@ -91,5 +91,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/grid_column_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/grid_column_custom.cc index 15dd0ec9..94884442 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/grid_column_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/grid_column_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool GridColumn::ParseShorthand( bool important, @@ -56,5 +56,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/grid_column_gap_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/grid_column_gap_custom.cc index 18c4fa02..e40ef50 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/grid_column_gap_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/grid_column_gap_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool GridColumnGap::ParseShorthand( bool important, @@ -40,5 +40,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/grid_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/grid_custom.cc index 38d29c8..ac57385e 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/grid_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/grid_custom.cc
@@ -39,7 +39,7 @@ } } // namespace -namespace CSSShorthand { +namespace css_shorthand { bool Grid::ParseShorthand(bool important, CSSParserTokenRange& range, @@ -203,5 +203,5 @@ gridShorthand(), style, layout_object, styled_node, allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/grid_gap_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/grid_gap_custom.cc index 5faa979..a78285a 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/grid_gap_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/grid_gap_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool GridGap::ParseShorthand( bool important, @@ -49,5 +49,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/grid_row_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/grid_row_custom.cc index 40c1fa1..11877a4f 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/grid_row_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/grid_row_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool GridRow::ParseShorthand( bool important, @@ -54,5 +54,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/grid_row_gap_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/grid_row_gap_custom.cc index c247ec4..3a35691a 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/grid_row_gap_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/grid_row_gap_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool GridRowGap::ParseShorthand( bool important, @@ -40,5 +40,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/grid_template_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/grid_template_custom.cc index b65b9d2..514539f 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/grid_template_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/grid_template_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool GridTemplate::ParseShorthand( bool important, @@ -66,5 +66,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/inset_block_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/inset_block_custom.cc index 883ee97..078558e 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/inset_block_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/inset_block_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool InsetBlock::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/inset_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/inset_custom.cc index ef6f54d..d7cf29c 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/inset_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/inset_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool Inset::ParseShorthand( bool important, @@ -32,5 +32,5 @@ insetShorthand(), style, layout_object, styled_node, allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/inset_inline_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/inset_inline_custom.cc index 7fc415c..7d04665 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/inset_inline_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/inset_inline_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool InsetInline::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/list_style_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/list_style_custom.cc index e8578ef..0c99adbf 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/list_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/list_style_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool ListStyle::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/margin_block_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/margin_block_custom.cc index c57d781..ffb1a79 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/margin_block_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/margin_block_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool MarginBlock::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/margin_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/margin_custom.cc index 3006f43..03334831 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/margin_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/margin_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool Margin::ParseShorthand( bool important, @@ -42,5 +42,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/margin_inline_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/margin_inline_custom.cc index 7c834b7..deb0ef9 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/margin_inline_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/margin_inline_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool MarginInline::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/marker_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/marker_custom.cc index f486aee..5f304bfb 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/marker_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/marker_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool Marker::ParseShorthand( bool important, @@ -35,5 +35,5 @@ return true; } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/offset_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/offset_custom.cc index bc1d51d8..81169ef4 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/offset_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/offset_custom.cc
@@ -15,7 +15,7 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool Offset::ParseShorthand( bool important, @@ -138,5 +138,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/outline_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/outline_custom.cc index 124d054..48fc568b 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/outline_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/outline_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool Outline::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/overflow_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/overflow_custom.cc index d51884fa..47d279ac 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/overflow_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/overflow_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool Overflow::ParseShorthand( bool important, @@ -76,5 +76,5 @@ return list; } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/overscroll_behavior_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/overscroll_behavior_custom.cc index c73015e..92e2ceaa 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/overscroll_behavior_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/overscroll_behavior_custom.cc
@@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool OverscrollBehavior::ParseShorthand( bool important, @@ -33,5 +33,5 @@ return list; } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/padding_block_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/padding_block_custom.cc index ef55191..580b8a0 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/padding_block_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/padding_block_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool PaddingBlock::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/padding_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/padding_custom.cc index 67e314b..c4442989 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/padding_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/padding_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool Padding::ParseShorthand( bool important, @@ -42,5 +42,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/padding_inline_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/padding_inline_custom.cc index 1b11483..b60986b88 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/padding_inline_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/padding_inline_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool PaddingInline::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/page_break_after_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/page_break_after_custom.cc index ddbcf76..44e8dd9 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/page_break_after_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/page_break_after_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool PageBreakAfter::ParseShorthand( bool important, @@ -41,5 +41,5 @@ return ComputedStyleUtils::ValueForPageBreakBetween(style.BreakAfter()); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/page_break_before_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/page_break_before_custom.cc index 0838f8a..a9958fb 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/page_break_before_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/page_break_before_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool PageBreakBefore::ParseShorthand( bool important, @@ -41,5 +41,5 @@ return ComputedStyleUtils::ValueForPageBreakBetween(style.BreakBefore()); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/page_break_inside_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/page_break_inside_custom.cc index d33eaee3..0860022 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/page_break_inside_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/page_break_inside_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool PageBreakInside::ParseShorthand( bool important, @@ -40,5 +40,5 @@ return ComputedStyleUtils::ValueForPageBreakInside(style.BreakInside()); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/place_content_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/place_content_custom.cc index cf85319..99c29aa 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/place_content_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/place_content_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool PlaceContent::ParseShorthand( bool important, @@ -67,5 +67,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/place_items_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/place_items_custom.cc index 7a757979..c7b6c2fb 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/place_items_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/place_items_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool PlaceItems::ParseShorthand( bool important, @@ -66,5 +66,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/place_self_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/place_self_custom.cc index 2ea788f0..c4683c9 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/place_self_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/place_self_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool PlaceSelf::ParseShorthand( bool important, @@ -66,5 +66,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/scroll_margin_block_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/scroll_margin_block_custom.cc index e882489..9b2f504 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/scroll_margin_block_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/scroll_margin_block_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool ScrollMarginBlock::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/scroll_margin_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/scroll_margin_custom.cc index 8aabf05..3cf8b9c 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/scroll_margin_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/scroll_margin_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool ScrollMargin::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/scroll_margin_inline_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/scroll_margin_inline_custom.cc index 755a98a..1c8b2b7 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/scroll_margin_inline_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/scroll_margin_inline_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool ScrollMarginInline::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/scroll_padding_block_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/scroll_padding_block_custom.cc index f5ec80f..f3c70674 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/scroll_padding_block_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/scroll_padding_block_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool ScrollPaddingBlock::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/scroll_padding_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/scroll_padding_custom.cc index a00ad1f9..2075592e 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/scroll_padding_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/scroll_padding_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool ScrollPadding::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/scroll_padding_inline_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/scroll_padding_inline_custom.cc index ecbe5d03..414a582 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/scroll_padding_inline_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/scroll_padding_inline_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool ScrollPaddingInline::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/text_decoration_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/text_decoration_custom.cc index 72cdae9..9aefde62 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/text_decoration_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/text_decoration_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool TextDecoration::ParseShorthand( bool important, @@ -33,5 +33,5 @@ allow_visited_style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/transition_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/transition_custom.cc index adac90f..e68f627 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/transition_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/transition_custom.cc
@@ -37,7 +37,7 @@ } } // namespace -namespace CSSShorthand { +namespace css_shorthand { bool Transition::ParseShorthand( bool important, @@ -114,5 +114,5 @@ return list; } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/webkit_column_break_after_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/webkit_column_break_after_custom.cc index 030ff2f..bd9fad4 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/webkit_column_break_after_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/webkit_column_break_after_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool WebkitColumnBreakAfter::ParseShorthand( bool important, @@ -41,5 +41,5 @@ style.BreakAfter()); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/webkit_column_break_before_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/webkit_column_break_before_custom.cc index a1083ba..cd9807b 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/webkit_column_break_before_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/webkit_column_break_before_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool WebkitColumnBreakBefore::ParseShorthand( bool important, @@ -41,5 +41,5 @@ style.BreakBefore()); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/webkit_column_break_inside_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/webkit_column_break_inside_custom.cc index 20bea89e..8265c94 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/webkit_column_break_inside_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/webkit_column_break_inside_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool WebkitColumnBreakInside::ParseShorthand( bool important, @@ -41,5 +41,5 @@ style.BreakInside()); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/webkit_margin_collapse_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/webkit_margin_collapse_custom.cc index 08b4e58..abb474f6 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/webkit_margin_collapse_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/webkit_margin_collapse_custom.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool WebkitMarginCollapse::ParseShorthand( bool important, @@ -51,5 +51,5 @@ return true; } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_box_image_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_box_image_custom.cc index ee46d27..5bc3049 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_box_image_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_box_image_custom.cc
@@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool WebkitMaskBoxImage::ParseShorthand( bool important, @@ -71,5 +71,5 @@ style); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_custom.cc index 4cb075b5..5656c807 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_custom.cc
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool WebkitMask::ParseShorthand( bool important, @@ -19,5 +19,5 @@ local_context, properties); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_position_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_position_custom.cc index 7aa1a8c4..d074664 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_position_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_position_custom.cc
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool WebkitMaskPosition::ParseShorthand( bool important, @@ -50,5 +50,5 @@ *this, style, &style.MaskLayers()); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_repeat_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_repeat_custom.cc index 61294d5..5850005 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_repeat_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/webkit_mask_repeat_custom.cc
@@ -13,7 +13,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool WebkitMaskRepeat::ParseShorthand( bool important, @@ -55,5 +55,5 @@ &style.MaskLayers()); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/webkit_text_emphasis_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/webkit_text_emphasis_custom.cc index 88c8e06..ad53227 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/webkit_text_emphasis_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/webkit_text_emphasis_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool WebkitTextEmphasis::ParseShorthand( bool important, @@ -20,5 +20,5 @@ webkitTextEmphasisShorthand(), important, context, range, properties); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/webkit_text_stroke_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/webkit_text_stroke_custom.cc index 631791fde..3ed0b96 100644 --- a/third_party/blink/renderer/core/css/properties/shorthands/webkit_text_stroke_custom.cc +++ b/third_party/blink/renderer/core/css/properties/shorthands/webkit_text_stroke_custom.cc
@@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/style_property_shorthand.h" namespace blink { -namespace CSSShorthand { +namespace css_shorthand { bool WebkitTextStroke::ParseShorthand( bool important, @@ -20,5 +20,5 @@ webkitTextStrokeShorthand(), important, context, range, properties); } -} // namespace CSSShorthand +} // namespace css_shorthand } // namespace blink
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc index 0da4cbed..9ddfc76 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -118,8 +118,6 @@ using namespace html_names; -ComputedStyle* StyleResolver::style_not_yet_available_; - static CSSPropertyValueSet* LeftToRightDeclaration() { DEFINE_STATIC_LOCAL(Persistent<MutableCSSPropertyValueSet>, left_to_right_decl, @@ -688,24 +686,6 @@ DCHECK(GetDocument().GetFrame()); DCHECK(GetDocument().GetSettings()); - // Once an element has a layout object or non-layout style, we don't try to - // destroy it, since that means it could be rendering already and we cannot - // arbitrarily change its style during loading. - if (!GetDocument().IsRenderingReady() && !element->GetLayoutObject() && - !element->NonLayoutObjectComputedStyle()) { - if (!style_not_yet_available_) { - auto style = ComputedStyle::Create(); - style->AddRef(); - style_not_yet_available_ = style.get(); - style_not_yet_available_->SetDisplay(EDisplay::kNone); - style_not_yet_available_->GetFont().Update( - GetDocument().GetStyleEngine().GetFontSelector()); - } - - GetDocument().SetHasNodesWithPlaceholderStyle(); - return style_not_yet_available_; - } - GetDocument().GetStyleEngine().IncStyleForElementCount(); INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(), elements_styled, 1);
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.h b/third_party/blink/renderer/core/css/resolver/style_resolver.h index a84ffa57..112aa5b 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.h +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.h
@@ -128,11 +128,6 @@ void SetResizedForViewportUnits(); void ClearResizedForViewportUnits(); - // Exposed for ComputedStyle::IsStyleAvailable(). - static ComputedStyle* StyleNotYetAvailable() { - return style_not_yet_available_; - } - void SetRuleUsageTracker(StyleRuleUsageTracker*); void UpdateMediaType(); @@ -282,8 +277,6 @@ Document& GetDocument() const { return *document_; } bool WasViewportResized() const { return was_viewport_resized_; } - static ComputedStyle* style_not_yet_available_; - MatchedPropertiesCache matched_properties_cache_; Member<Document> document_; SelectorFilter selector_filter_;
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index ec6a6ecb..60f42a1 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -91,7 +91,10 @@ public: IgnoringPendingStylesheet(StyleEngine& engine) - : scope_(&engine.ignore_pending_stylesheets_, true) {} + : scope_(&engine.ignore_pending_stylesheets_, + !RuntimeEnabledFeatures::CSSInBodyDoesNotBlockPaintEnabled()) { + } + private: base::AutoReset<bool> scope_; };
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.cc b/third_party/blink/renderer/core/display_lock/display_lock_context.cc index 3c077a1e6..af573b1 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "third_party/blink/renderer/core/display_lock/display_lock_context.h" + #include "third_party/blink/renderer/bindings/core/v8/v8_display_lock_callback.h" #include "third_party/blink/renderer/core/display_lock/display_lock_suspended_handle.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -65,6 +66,8 @@ const char* LifecycleUpdateStateToString( DisplayLockContext::LifecycleUpdateState state) { switch (state) { + case DisplayLockContext::kNeedsStyle: + return "kNeedsStyle"; case DisplayLockContext::kNeedsLayout: return "kNeedsLayout"; case DisplayLockContext::kNeedsPrePaint: @@ -283,11 +286,26 @@ state_ = kDisconnected; } -bool DisplayLockContext::ShouldLayout() const { +bool DisplayLockContext::ShouldStyle() const { SCOPED_LOGGER(__PRETTY_FUNCTION__); return state_ >= kCommitting; } +void DisplayLockContext::DidStyle() { + SCOPED_LOGGER(__PRETTY_FUNCTION__); + if (state_ != kCommitting) + return; + + if (lifecycle_update_state_ <= kNeedsStyle) + lifecycle_update_state_ = kNeedsLayout; +} + +bool DisplayLockContext::ShouldLayout() const { + SCOPED_LOGGER(__PRETTY_FUNCTION__); + return std::tie(state_, lifecycle_update_state_) >= + std::tuple<State, LifecycleUpdateState>(kCommitting, kNeedsLayout); +} + void DisplayLockContext::DidLayout() { SCOPED_LOGGER(__PRETTY_FUNCTION__); if (state_ != kCommitting) @@ -299,7 +317,8 @@ bool DisplayLockContext::ShouldPrePaint() const { SCOPED_LOGGER(__PRETTY_FUNCTION__); - return state_ >= kCommitting && lifecycle_update_state_ >= kNeedsPrePaint; + return std::tie(state_, lifecycle_update_state_) >= + std::tuple<State, LifecycleUpdateState>(kCommitting, kNeedsPrePaint); } void DisplayLockContext::DidPrePaint() { @@ -307,13 +326,17 @@ if (state_ != kCommitting) return; + // Since we should be under containment, we should have a layer. If we don't, + // then paint might not happen and we'll never resolve. + DCHECK(element_->GetLayoutObject()->HasLayer()); if (lifecycle_update_state_ <= kNeedsPrePaint) lifecycle_update_state_ = kNeedsPaint; } bool DisplayLockContext::ShouldPaint() const { SCOPED_LOGGER(__PRETTY_FUNCTION__); - return state_ >= kCommitting && lifecycle_update_state_ >= kNeedsPaint; + return std::tie(state_, lifecycle_update_state_) >= + std::tuple<State, LifecycleUpdateState>(kCommitting, kNeedsPaint); } void DisplayLockContext::DidPaint() { @@ -344,12 +367,23 @@ void DisplayLockContext::StartCommit() { SCOPED_LOGGER(__PRETTY_FUNCTION__); state_ = kCommitting; - lifecycle_update_state_ = kNeedsLayout; + lifecycle_update_state_ = kNeedsStyle; + + // Ensure that we can reach this element for style if needed. + if (element_->NeedsStyleRecalc() || element_->ChildNeedsStyleRecalc()) + element_->MarkAncestorsWithChildNeedsStyleRecalc(); + else + DidStyle(); + + // Also ensure we reach it for layout. + // TODO(vmpstr): This should just mark the ancestor chain if needed. element_->GetLayoutObject()->SetNeedsLayout( LayoutInvalidationReason::kDisplayLockCommitting); if (auto* parent = element_->GetLayoutObject()->Parent()) { parent->SetNeedsLayout(LayoutInvalidationReason::kDisplayLockCommitting); } + + // Schedule an animation to perform the lifecycle phases. element_->GetDocument().GetPage()->Animator().ScheduleVisualUpdate( element_->GetDocument().GetFrame()); DCHECK(element_->GetLayoutObject());
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.h b/third_party/blink/renderer/core/display_lock/display_lock_context.h index 2fc28d8..e559092 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.h +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.h
@@ -37,6 +37,7 @@ }; enum LifecycleUpdateState { + kNeedsStyle, kNeedsLayout, kNeedsPrePaint, kNeedsPaint, @@ -83,6 +84,8 @@ Element* lockedElement() const; // Lifecycle observation / state functions. + bool ShouldStyle() const; + void DidStyle(); bool ShouldLayout() const; void DidLayout(); bool ShouldPrePaint() const;
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index d1b6ad7..07687374 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -2145,24 +2145,33 @@ #if DCHECK_IS_ON() static void AssertLayoutTreeUpdated(Node& root) { - for (Node& node : NodeTraversal::InclusiveDescendantsOf(root)) { - DCHECK(!node.NeedsStyleRecalc()); - DCHECK(!node.ChildNeedsStyleRecalc()); - DCHECK(!node.NeedsReattachLayoutTree()); - DCHECK(!node.ChildNeedsReattachLayoutTree()); - DCHECK(!node.ChildNeedsDistributionRecalc()); - DCHECK(!node.NeedsStyleInvalidation()); - DCHECK(!node.ChildNeedsStyleInvalidation()); - DCHECK(!node.GetForceReattachLayoutTree()); + Node* node = &root; + while (node) { + if (RuntimeEnabledFeatures::DisplayLockingEnabled() && + node->IsElementNode() && + ToElement(node)->StyleRecalcBlockedByDisplayLock()) { + node = NodeTraversal::NextSkippingChildren(*node); + continue; + } + + DCHECK(!node->NeedsStyleRecalc()); + DCHECK(!node->ChildNeedsStyleRecalc()); + DCHECK(!node->NeedsReattachLayoutTree()); + DCHECK(!node->ChildNeedsReattachLayoutTree()); + DCHECK(!node->ChildNeedsDistributionRecalc()); + DCHECK(!node->NeedsStyleInvalidation()); + DCHECK(!node->ChildNeedsStyleInvalidation()); + DCHECK(!node->GetForceReattachLayoutTree()); // Make sure there is no node which has a LayoutObject, but doesn't have a // parent in a flat tree. If there is such a node, we forgot to detach the // node. DocumentNode is only an exception. - DCHECK((node.IsDocumentNode() || !node.GetLayoutObject() || - FlatTreeTraversal::Parent(node))) - << node; + DCHECK((node->IsDocumentNode() || !node->GetLayoutObject() || + FlatTreeTraversal::Parent(*node))) + << *node; - if (ShadowRoot* shadow_root = node.GetShadowRoot()) + if (ShadowRoot* shadow_root = node->GetShadowRoot()) AssertLayoutTreeUpdated(*shadow_root); + node = NodeTraversal::Next(*node); } } #endif @@ -2533,6 +2542,10 @@ // lets us get reasonable answers. The long term solution to this problem is // to instead suspend JavaScript execution. void Document::UpdateStyleAndLayoutTreeIgnorePendingStylesheets() { + if (RuntimeEnabledFeatures::CSSInBodyDoesNotBlockPaintEnabled()) { + UpdateStyleAndLayoutTree(); + return; + } if (Lifecycle().LifecyclePostponed()) return; // See comment for equivalent CHECK in Document::UpdateStyleAndLayoutTree. @@ -2574,7 +2587,8 @@ LocalFrameView* local_view = View(); if (local_view) local_view->WillStartForcedLayout(); - UpdateStyleAndLayoutTreeIgnorePendingStylesheets(); + if (!RuntimeEnabledFeatures::CSSInBodyDoesNotBlockPaintEnabled()) + UpdateStyleAndLayoutTreeIgnorePendingStylesheets(); UpdateStyleAndLayout(); if (local_view) {
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 17cce6b..846d8c41 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2208,6 +2208,11 @@ void Element::RecalcStyle(StyleRecalcChange change) { DCHECK(GetDocument().InStyleRecalc()); DCHECK(!GetDocument().Lifecycle().InDetach()); + + if (StyleRecalcBlockedByDisplayLock()) + return; + NotifyDisplayLockDidRecalcStyle(); + // If we are re-attaching in a Shadow DOM v0 tree, we recalc down to the // distributed nodes to propagate kReattach down the flat tree (See // V0InsertionPoint::DidRecalcStyle). That means we may have a shadow- @@ -3557,6 +3562,8 @@ } DisplayLockContext* Element::GetDisplayLockContext() const { + if (!RuntimeEnabledFeatures::DisplayLockingEnabled()) + return nullptr; return HasRareData() ? GetElementRareData()->GetDisplayLockContext() : nullptr; } @@ -5094,4 +5101,14 @@ : nullptr; } +bool Element::StyleRecalcBlockedByDisplayLock() const { + auto* context = GetDisplayLockContext(); + return context && !context->ShouldStyle(); +} + +void Element::NotifyDisplayLockDidRecalcStyle() { + if (auto* context = GetDisplayLockContext()) + context->DidStyle(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index 28550728..110d7c9 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -892,6 +892,8 @@ ScriptPromise acquireDisplayLock(ScriptState*, V8DisplayLockCallback*); DisplayLockContext* GetDisplayLockContext() const; + bool StyleRecalcBlockedByDisplayLock() const; + protected: Element(const QualifiedName& tag_name, Document*, ConstructionType); @@ -1102,6 +1104,8 @@ void DetachAttrNodeFromElementWithValue(Attr*, const AtomicString& value); void DetachAttrNodeAtIndex(Attr*, wtf_size_t index); + void NotifyDisplayLockDidRecalcStyle(); + Member<ElementData> element_data_; };
diff --git a/third_party/blink/renderer/core/dom/flat_tree_node_data.h b/third_party/blink/renderer/core/dom/flat_tree_node_data.h index aa0f0caf..96d9883 100644 --- a/third_party/blink/renderer/core/dom/flat_tree_node_data.h +++ b/third_party/blink/renderer/core/dom/flat_tree_node_data.h
@@ -16,6 +16,11 @@ class FlatTreeNodeData final : public GarbageCollected<FlatTreeNodeData> { public: FlatTreeNodeData() {} + void Clear() { + assigned_slot_ = nullptr; + previous_in_assigned_nodes_ = nullptr; + next_in_assigned_nodes_ = nullptr; + } void Trace(Visitor*); private: @@ -32,6 +37,7 @@ Node* PreviousInAssignedNodes() { return previous_in_assigned_nodes_; } Node* NextInAssignedNodes() { return next_in_assigned_nodes_; } + friend class FlatTreeTraversal; friend class HTMLSlotElement; WeakMember<HTMLSlotElement> assigned_slot_;
diff --git a/third_party/blink/renderer/core/dom/flat_tree_traversal.cc b/third_party/blink/renderer/core/dom/flat_tree_traversal.cc index dd75d326..92e6ec3 100644 --- a/third_party/blink/renderer/core/dom/flat_tree_traversal.cc +++ b/third_party/blink/renderer/core/dom/flat_tree_traversal.cc
@@ -27,6 +27,8 @@ #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" #include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/core/dom/flat_tree_node_data.h" +#include "third_party/blink/renderer/core/dom/slot_assignment.h" #include "third_party/blink/renderer/core/html/html_shadow_element.h" #include "third_party/blink/renderer/core/html/html_slot_element.h" @@ -114,14 +116,28 @@ Node* FlatTreeTraversal::TraverseSiblingsForV1HostChild( const Node& node, TraversalDirection direction) { - // TODO(crbug.com/906494): Use flat_tree_node_data::assigned_slot to avoid - // hashmap lookup - HTMLSlotElement* slot = node.AssignedSlot(); - if (!slot) + ShadowRoot* shadow_root = node.ParentElementShadowRoot(); + DCHECK(shadow_root); + if (!shadow_root->HasSlotAssignment()) { + // The shadow root doesn't have any slot. return nullptr; - return direction == kTraversalDirectionForward - ? slot->AssignedNodeNextTo(node) - : slot->AssignedNodePreviousTo(node); + } + shadow_root->GetSlotAssignment().RecalcAssignment(); + + FlatTreeNodeData* flat_tree_node_data = node.GetFlatTreeNodeData(); + if (!flat_tree_node_data) { + // This node has never been assigned to any slot. + return nullptr; + } + if (flat_tree_node_data->AssignedSlot()) { + return direction == kTraversalDirectionForward + ? flat_tree_node_data->NextInAssignedNodes() + : flat_tree_node_data->PreviousInAssignedNodes(); + } + // This node is not assigned to any slot. + DCHECK(!flat_tree_node_data->NextInAssignedNodes()); + DCHECK(!flat_tree_node_data->PreviousInAssignedNodes()); + return nullptr; } Node* FlatTreeTraversal::TraverseSiblingsForV0Distribution(
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc index ed0465d..d9852b61 100644 --- a/third_party/blink/renderer/core/dom/node.cc +++ b/third_party/blink/renderer/core/dom/node.cc
@@ -48,6 +48,7 @@ #include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h" #include "third_party/blink/renderer/core/dom/events/event_dispatcher.h" #include "third_party/blink/renderer/core/dom/events/event_listener.h" +#include "third_party/blink/renderer/core/dom/flat_tree_node_data.h" #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" #include "third_party/blink/renderer/core/dom/get_root_node_options.h" #include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h" @@ -1103,6 +1104,14 @@ ancestor->SetChildNeedsStyleRecalc(); if (ancestor->NeedsStyleRecalc()) break; + // If we reach a locked ancestor, we should abort since the ancestor marking + // will be done when the lock is committed. + if (RuntimeEnabledFeatures::DisplayLockingEnabled()) { + if (ancestor->IsElementNode() && + ToElement(ancestor)->StyleRecalcBlockedByDisplayLock()) { + break; + } + } } if (!isConnected()) return; @@ -1110,6 +1119,23 @@ // early return here is a performance optimization. if (parent_dirty) return; + + // If we're in a locked subtree, then we should not update the style recalc + // roots. These would be updated when we commit the lock. + // TODO(vmpstr): There's currently no easy way to determine whether we're in a + // locked subtree other than navigating up the ancestor chain. We can probably + // do better and only do this walk if there is in fact a lock somewhere in the + // document. + if (RuntimeEnabledFeatures::DisplayLockingEnabled()) { + for (auto* ancestor_copy = ancestor; ancestor_copy; + ancestor_copy = ancestor_copy->ParentOrShadowHostNode()) { + if (ancestor_copy->IsElementNode() && + ToElement(ancestor_copy)->StyleRecalcBlockedByDisplayLock()) { + return; + } + } + } + GetDocument().GetStyleEngine().UpdateStyleRecalcRoot(ancestor, this); GetDocument().ScheduleLayoutTreeUpdateIfNeeded(); } @@ -1254,10 +1280,15 @@ return EnsureRareData().EnsureFlatTreeNodeData(); } -FlatTreeNodeData& Node::GetFlatTreeNodeData() const { - DCHECK(HasRareData()); - DCHECK(RareData()->GetFlatTreeNodeData()); - return *RareData()->GetFlatTreeNodeData(); +FlatTreeNodeData* Node::GetFlatTreeNodeData() const { + if (!HasRareData()) + return nullptr; + return RareData()->GetFlatTreeNodeData(); +} + +void Node::ClearFlatTreeNodeData() { + if (FlatTreeNodeData* data = GetFlatTreeNodeData()) + data->Clear(); } bool Node::IsDescendantOf(const Node* other) const {
diff --git a/third_party/blink/renderer/core/dom/node.h b/third_party/blink/renderer/core/dom/node.h index acfe760..32e30eb5 100644 --- a/third_party/blink/renderer/core/dom/node.h +++ b/third_party/blink/renderer/core/dom/node.h
@@ -466,6 +466,9 @@ void SetNeedsStyleRecalc(StyleChangeType, const StyleChangeReasonForTracing&); void ClearNeedsStyleRecalc(); + // Propagates a dirty bit breadcrumb for this element up the ancestor chain. + void MarkAncestorsWithChildNeedsStyleRecalc(); + bool NeedsReattachLayoutTree() const { return GetFlag(kNeedsReattachLayoutTree); } @@ -777,9 +780,9 @@ NodeListsNodeData* NodeLists(); void ClearNodeLists(); - // EnsureFlatTreeNodeData() must be called beforehand - FlatTreeNodeData& GetFlatTreeNodeData() const; + FlatTreeNodeData* GetFlatTreeNodeData() const; FlatTreeNodeData& EnsureFlatTreeNodeData(); + void ClearFlatTreeNodeData(); virtual bool WillRespondToMouseMoveEvents(); virtual bool WillRespondToMouseClickEvents(); @@ -1003,7 +1006,6 @@ void SetTreeScope(TreeScope* scope) { tree_scope_ = scope; } - void MarkAncestorsWithChildNeedsStyleRecalc(); static void MarkAncestorsWithChildNeedsStyleRecalc(Node* child) { child->MarkAncestorsWithChildNeedsStyleRecalc(); }
diff --git a/third_party/blink/renderer/core/dom/shadow_root.h b/third_party/blink/renderer/core/dom/shadow_root.h index 5d4a9223..9da2e37 100644 --- a/third_party/blink/renderer/core/dom/shadow_root.h +++ b/third_party/blink/renderer/core/dom/shadow_root.h
@@ -127,6 +127,8 @@ return *slot_assignment_; } + bool HasSlotAssignment() { return slot_assignment_; } + HTMLSlotElement* AssignedSlotFor(const Node&); void DidAddSlot(HTMLSlotElement&); void DidChangeHostChildSlotName(const AtomicString& old_value,
diff --git a/third_party/blink/renderer/core/dom/slot_assignment.cc b/third_party/blink/renderer/core/dom/slot_assignment.cc index fc6aa2d..f80d52a 100644 --- a/third_party/blink/renderer/core/dom/slot_assignment.cc +++ b/third_party/blink/renderer/core/dom/slot_assignment.cc
@@ -269,10 +269,7 @@ if (slot) { slot->AppendAssignedNode(child); } else { - // TODO(crbug.com/906494) Clear child's flat_tree_node_data here, which - // should be useful for shortcut in flat tree traversal later; we can skip - // hashmap lookup (node->slot) there if we know the node doesn't have - // an assigned slot. + child.ClearFlatTreeNodeData(); child.LazyReattachIfAttached(); } }
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc index fb762ba..e000dcc 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc +++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc
@@ -85,8 +85,14 @@ using TextIteratorType = TextIteratorInFlatTree; }; -class TextIteratorTest : public EditingTestBase { +class TextIteratorTest : public testing::WithParamInterface<bool>, + private ScopedLayoutNGForTest, + public EditingTestBase { protected: + TextIteratorTest() : ScopedLayoutNGForTest(GetParam()) {} + + bool LayoutNGEnabled() const { return GetParam(); } + template <typename Tree> std::string Iterate(const TextIteratorBehavior& = TextIteratorBehavior()); @@ -98,6 +104,11 @@ Range* GetBodyRange() const; + int TestRangeLength(const std::string& selection_text) { + return TextIterator::RangeLength( + SetSelectionTextToBody(selection_text).ComputeRange()); + } + private: template <typename Tree> std::string IterateWithIterator(typename Tree::TextIteratorType&); @@ -141,24 +152,9 @@ return range; } -class ParameterizedTextIteratorTest : public testing::WithParamInterface<bool>, - private ScopedLayoutNGForTest, - public TextIteratorTest { - public: - ParameterizedTextIteratorTest() : ScopedLayoutNGForTest(GetParam()) {} +INSTANTIATE_TEST_CASE_P(All, TextIteratorTest, testing::Bool()); - protected: - bool LayoutNGEnabled() const { return GetParam(); } - - int TestRangeLength(const std::string& selection_text) { - return TextIterator::RangeLength( - SetSelectionTextToBody(selection_text).ComputeRange()); - } -}; - -INSTANTIATE_TEST_CASE_P(All, ParameterizedTextIteratorTest, testing::Bool()); - -TEST_F(TextIteratorTest, BitStackOverflow) { +TEST_P(TextIteratorTest, BitStackOverflow) { const unsigned kBitsInWord = sizeof(unsigned) * 8; BitStack bs; @@ -170,14 +166,14 @@ EXPECT_TRUE(bs.Top()); } -TEST_F(TextIteratorTest, BasicIteration) { +TEST_P(TextIteratorTest, BasicIteration) { static const char* input = "<p>Hello, \ntext</p><p>iterator.</p>"; SetBodyContent(input); EXPECT_EQ("[Hello, ][text][\n][\n][iterator.]", Iterate<DOMTree>()); EXPECT_EQ("[Hello, ][text][\n][\n][iterator.]", Iterate<FlatTree>()); } -TEST_F(TextIteratorTest, EmitsSmallXForTextSecurity) { +TEST_P(TextIteratorTest, EmitsSmallXForTextSecurity) { InsertStyleElement("s {-webkit-text-security:disc;}"); SetBodyContent("abc<s>foo</s>baz"); // E2 80 A2 is U+2022 BULLET @@ -191,28 +187,28 @@ Iterate<FlatTree>(TextIteratorBehavior())); } -TEST_F(TextIteratorTest, IgnoreAltTextInTextControls) { +TEST_P(TextIteratorTest, IgnoreAltTextInTextControls) { static const char* input = "<p>Hello <input type='text' value='value'>!</p>"; SetBodyContent(input); EXPECT_EQ("[Hello ][][!]", Iterate<DOMTree>(EmitsImageAltTextBehavior())); EXPECT_EQ("[Hello ][][!]", Iterate<FlatTree>(EmitsImageAltTextBehavior())); } -TEST_F(TextIteratorTest, DisplayAltTextInImageControls) { +TEST_P(TextIteratorTest, DisplayAltTextInImageControls) { static const char* input = "<p>Hello <input type='image' alt='alt'>!</p>"; SetBodyContent(input); EXPECT_EQ("[Hello ][alt][!]", Iterate<DOMTree>(EmitsImageAltTextBehavior())); EXPECT_EQ("[Hello ][alt][!]", Iterate<FlatTree>(EmitsImageAltTextBehavior())); } -TEST_F(TextIteratorTest, NotEnteringTextControls) { +TEST_P(TextIteratorTest, NotEnteringTextControls) { static const char* input = "<p>Hello <input type='text' value='input'>!</p>"; SetBodyContent(input); EXPECT_EQ("[Hello ][][!]", Iterate<DOMTree>()); EXPECT_EQ("[Hello ][][!]", Iterate<FlatTree>()); } -TEST_F(TextIteratorTest, EnteringTextControlsWithOption) { +TEST_P(TextIteratorTest, EnteringTextControlsWithOption) { static const char* input = "<p>Hello <input type='text' value='input'>!</p>"; SetBodyContent(input); EXPECT_EQ("[Hello ][\n][input][!]", @@ -221,7 +217,7 @@ Iterate<FlatTree>(EntersTextControlsBehavior())); } -TEST_F(TextIteratorTest, EnteringTextControlsWithOptionComplex) { +TEST_P(TextIteratorTest, EnteringTextControlsWithOptionComplex) { static const char* input = "<input type='text' value='Beginning of range'><div><div><input " "type='text' value='Under DOM nodes'></div></div><input type='text' " @@ -233,7 +229,7 @@ Iterate<FlatTree>(EntersTextControlsBehavior())); } -TEST_F(TextIteratorTest, NotEnteringShadowTree) { +TEST_P(TextIteratorTest, NotEnteringShadowTree) { static const char* body_content = "<div>Hello, <span id='host'>text</span> iterator.</div>"; static const char* shadow_content = "<span>shadow</span>"; @@ -246,7 +242,7 @@ EXPECT_EQ("[Hello, ][shadow][ iterator.]", Iterate<FlatTree>()); } -TEST_F(TextIteratorTest, NotEnteringShadowTreeWithNestedShadowTrees) { +TEST_P(TextIteratorTest, NotEnteringShadowTreeWithNestedShadowTrees) { static const char* body_content = "<div>Hello, <span id='host-in-document'>text</span> iterator.</div>"; static const char* shadow_content1 = @@ -262,7 +258,7 @@ Iterate<FlatTree>()); } -TEST_F(TextIteratorTest, NotEnteringShadowTreeWithContentInsertionPoint) { +TEST_P(TextIteratorTest, NotEnteringShadowTreeWithContentInsertionPoint) { static const char* body_content = "<div>Hello, <span id='host'>text</span> iterator.</div>"; static const char* shadow_content = @@ -275,7 +271,7 @@ EXPECT_EQ("[Hello, ][shadow ][text][ iterator.]", Iterate<FlatTree>()); } -TEST_F(TextIteratorTest, EnteringShadowTreeWithOption) { +TEST_P(TextIteratorTest, EnteringShadowTreeWithOption) { static const char* body_content = "<div>Hello, <span id='host'>text</span> iterator.</div>"; static const char* shadow_content = "<span>shadow</span>"; @@ -290,7 +286,7 @@ Iterate<FlatTree>(EntersOpenShadowRootsBehavior())); } -TEST_F(TextIteratorTest, EnteringShadowTreeWithNestedShadowTreesWithOption) { +TEST_P(TextIteratorTest, EnteringShadowTreeWithNestedShadowTreesWithOption) { static const char* body_content = "<div>Hello, <span id='host-in-document'>text</span> iterator.</div>"; static const char* shadow_content1 = @@ -307,7 +303,7 @@ Iterate<FlatTree>(EntersOpenShadowRootsBehavior())); } -TEST_F(TextIteratorTest, +TEST_P(TextIteratorTest, EnteringShadowTreeWithContentInsertionPointWithOption) { static const char* body_content = "<div>Hello, <span id='host'>text</span> iterator.</div>"; @@ -327,7 +323,7 @@ Iterate<FlatTree>(EntersOpenShadowRootsBehavior())); } -TEST_F(TextIteratorTest, StartingAtNodeInShadowRoot) { +TEST_P(TextIteratorTest, StartingAtNodeInShadowRoot) { static const char* body_content = "<div id='outer'>Hello, <span id='host'>text</span> iterator.</div>"; static const char* shadow_content = @@ -352,7 +348,7 @@ EntersOpenShadowRootsBehavior())); } -TEST_F(TextIteratorTest, FinishingAtNodeInShadowRoot) { +TEST_P(TextIteratorTest, FinishingAtNodeInShadowRoot) { static const char* body_content = "<div id='outer'>Hello, <span id='host'>text</span> iterator.</div>"; static const char* shadow_content = @@ -377,7 +373,7 @@ EntersOpenShadowRootsBehavior())); } -TEST_F(TextIteratorTest, FullyClipsContents) { +TEST_P(TextIteratorTest, FullyClipsContents) { static const char* body_content = "<div style='overflow: hidden; width: 200px; height: 0;'>" "I'm invisible" @@ -387,7 +383,7 @@ EXPECT_EQ("", Iterate<FlatTree>()); } -TEST_F(TextIteratorTest, IgnoresContainerClip) { +TEST_P(TextIteratorTest, IgnoresContainerClip) { static const char* body_content = "<div style='overflow: hidden; width: 200px; height: 0;'>" "<div>I'm not visible</div>" @@ -401,7 +397,7 @@ EXPECT_EQ("[but I am!]", Iterate<FlatTree>()); } -TEST_F(TextIteratorTest, FullyClippedContentsDistributed) { +TEST_P(TextIteratorTest, FullyClippedContentsDistributed) { static const char* body_content = "<div id='host'>" "<div>Am I visible?</div>" @@ -420,7 +416,7 @@ EXPECT_EQ("", Iterate<FlatTree>(EntersOpenShadowRootsBehavior())); } -TEST_F(TextIteratorTest, IgnoresContainersClipDistributed) { +TEST_P(TextIteratorTest, IgnoresContainersClipDistributed) { static const char* body_content = "<div id='host' style='overflow: hidden; width: 200px; height: 0;'>" "<div>Nobody can find me!</div>" @@ -441,7 +437,7 @@ Iterate<FlatTree>(EntersOpenShadowRootsBehavior())); } -TEST_F(TextIteratorTest, EmitsReplacementCharForInput) { +TEST_P(TextIteratorTest, EmitsReplacementCharForInput) { static const char* body_content = "<div contenteditable='true'>" "Before" @@ -455,7 +451,7 @@ Iterate<FlatTree>(EmitsObjectReplacementCharacterBehavior())); } -TEST_F(TextIteratorTest, RangeLengthWithReplacedElements) { +TEST_P(TextIteratorTest, RangeLengthWithReplacedElements) { static const char* body_content = "<div id='div' contenteditable='true'>1<img src='foo.png'>3</div>"; SetBodyContent(body_content); @@ -467,7 +463,7 @@ EXPECT_EQ(3, TextIterator::RangeLength(range)); } -TEST_F(TextIteratorTest, RangeLengthInMultilineSpan) { +TEST_P(TextIteratorTest, RangeLengthInMultilineSpan) { static const char* body_content = "<table style='width:5em'>" "<tbody>" @@ -489,13 +485,13 @@ const EphemeralRange range(Position(text_node, 4), Position(text_node, 7)); - EXPECT_EQ(4, TextIterator::RangeLength(range)); + EXPECT_EQ(LayoutNGEnabled() ? 3 : 4, TextIterator::RangeLength(range)); EXPECT_EQ(3, TextIterator::RangeLength( range, TextIteratorBehavior::NoTrailingSpaceRangeLengthBehavior())); } -TEST_P(ParameterizedTextIteratorTest, RangeLengthBasic) { +TEST_P(TextIteratorTest, RangeLengthBasic) { EXPECT_EQ(0, TestRangeLength("<p>^| (1) abc def</p>")); EXPECT_EQ(0, TestRangeLength("<p>^ |(1) abc def</p>")); EXPECT_EQ(1, TestRangeLength("<p>^ (|1) abc def</p>")); @@ -511,7 +507,7 @@ EXPECT_EQ(11, TestRangeLength("<p>^ (1) abc def|</p>")); } -TEST_P(ParameterizedTextIteratorTest, RangeLengthWithFirstLetter) { +TEST_P(TextIteratorTest, RangeLengthWithFirstLetter) { InsertStyleElement("p::first-letter {font-size:200%;}"); // Expectation should be as same as |RangeLengthBasic| EXPECT_EQ(0, TestRangeLength("<p>^| (1) abc def</p>")); @@ -529,8 +525,7 @@ EXPECT_EQ(11, TestRangeLength("<p>^ (1) abc def|</p>")); } -TEST_P(ParameterizedTextIteratorTest, - RangeLengthWithFirstLetterMultipleLeadingSpaces) { +TEST_P(TextIteratorTest, RangeLengthWithFirstLetterMultipleLeadingSpaces) { InsertStyleElement("p::first-letter {font-size:200%;}"); EXPECT_EQ(0, TestRangeLength("<p>^| foo</p>")); EXPECT_EQ(0, TestRangeLength("<p>^ | foo</p>")); @@ -541,7 +536,7 @@ EXPECT_EQ(3, TestRangeLength("<p>^ foo|</p>")); } -TEST_F(TextIteratorTest, WhitespaceCollapseForReplacedElements) { +TEST_P(TextIteratorTest, WhitespaceCollapseForReplacedElements) { static const char* body_content = "<span>Some text </span> <input type='button' value='Button " "text'/><span>Some more text</span>"; @@ -553,7 +548,7 @@ Iterate<FlatTree>(CollapseTrailingSpaceBehavior())); } -TEST_F(TextIteratorTest, copyTextTo) { +TEST_P(TextIteratorTest, copyTextTo) { const char* body_content = "<a id=host><b id=one>one</b> not appeared <b id=two>two</b></a>"; const char* shadow_content = @@ -623,7 +618,7 @@ << String::Format(message, 2, "three two one zero").Utf8().data(); } -TEST_F(TextIteratorTest, characterAt) { +TEST_P(TextIteratorTest, characterAt) { const char* body_content = "<a id=host><b id=one>one</b> not appeared <b id=two>two</b></a>"; const char* shadow_content = @@ -678,7 +673,7 @@ EXPECT_EQ('o', iter2.CharacterAt(4)) << message2; } -TEST_F(TextIteratorTest, CopyWholeCodePoints) { +TEST_P(TextIteratorTest, CopyWholeCodePoints) { const char* body_content = "𓀀𓀁𓀂 𓅀𓅁."; SetBodyContent(body_content); @@ -703,7 +698,7 @@ } // Regression test for crbug.com/630921 -TEST_F(TextIteratorTest, EndingConditionWithDisplayNone) { +TEST_P(TextIteratorTest, EndingConditionWithDisplayNone) { SetBodyContent( "<div style='display: none'><span>hello</span>world</div>Lorem ipsum " "dolor sit amet."); @@ -714,7 +709,7 @@ } // Trickier regression test for crbug.com/630921 -TEST_F(TextIteratorTest, EndingConditionWithDisplayNoneInShadowTree) { +TEST_P(TextIteratorTest, EndingConditionWithDisplayNoneInShadowTree) { const char* body_content = "<div style='display: none'><span id=host><a></a></span>world</div>Lorem " "ipsum dolor sit amet."; @@ -732,7 +727,7 @@ EXPECT_TRUE(iter.AtEnd()); } -TEST_F(TextIteratorTest, PreserveLeadingSpace) { +TEST_P(TextIteratorTest, PreserveLeadingSpace) { SetBodyContent("<div style='width: 2em;'><b><i>foo</i></b> bar</div>"); Element* div = GetDocument().QuerySelector("div"); Position start(div->firstChild()->firstChild()->firstChild(), 0); @@ -743,7 +738,7 @@ // We used to have a bug where the leading space was duplicated if we didn't // emit alt text, this tests for that bug -TEST_F(TextIteratorTest, PreserveLeadingSpaceWithoutEmittingAltText) { +TEST_P(TextIteratorTest, PreserveLeadingSpaceWithoutEmittingAltText) { SetBodyContent("<div style='width: 2em;'><b><i>foo</i></b> bar</div>"); Element* div = GetDocument().QuerySelector("div"); Position start(div->firstChild()->firstChild()->firstChild(), 0); @@ -751,7 +746,7 @@ EXPECT_EQ("foo bar", PlainText(EphemeralRange(start, end))); } -TEST_F(TextIteratorTest, PreserveOnlyLeadingSpace) { +TEST_P(TextIteratorTest, PreserveOnlyLeadingSpace) { SetBodyContent( "<div style='width: 2em;'><b><i id='foo'>foo </i></b> bar</div>"); Element* div = GetDocument().QuerySelector("div"); @@ -761,7 +756,7 @@ PlainText(EphemeralRange(start, end), EmitsImageAltTextBehavior())); } -TEST_F(TextIteratorTest, StartAtFirstLetter) { +TEST_P(TextIteratorTest, StartAtFirstLetter) { SetBodyContent("<style>div:first-letter {color:red;}</style><div>Axyz</div>"); Element* div = GetDocument().QuerySelector("div"); @@ -792,7 +787,7 @@ EXPECT_EQ("Axyz", String(buffer.Data())); } -TEST_F(TextIteratorTest, StartInMultiCharFirstLetterWithCollapsedSpace) { +TEST_P(TextIteratorTest, StartInMultiCharFirstLetterWithCollapsedSpace) { SetBodyContent( "<style>div:first-letter {color:red;}</style><div> (A) xyz</div>"); @@ -832,7 +827,7 @@ EXPECT_EQ("A) xyz", String(buffer.Data())); } -TEST_F(TextIteratorTest, StartAndEndInMultiCharFirstLetterWithCollapsedSpace) { +TEST_P(TextIteratorTest, StartAndEndInMultiCharFirstLetterWithCollapsedSpace) { SetBodyContent( "<style>div:first-letter {color:red;}</style><div> (A) xyz</div>"); @@ -856,7 +851,7 @@ EXPECT_EQ("A", String(buffer.Data())); } -TEST_F(TextIteratorTest, StartAtRemainingText) { +TEST_P(TextIteratorTest, StartAtRemainingText) { SetBodyContent("<style>div:first-letter {color:red;}</style><div>Axyz</div>"); Element* div = GetDocument().QuerySelector("div"); @@ -879,7 +874,7 @@ EXPECT_EQ("xyz", String(buffer.Data())); } -TEST_F(TextIteratorTest, StartAtFirstLetterInPre) { +TEST_P(TextIteratorTest, StartAtFirstLetterInPre) { SetBodyContent("<style>pre:first-letter {color:red;}</style><pre>Axyz</pre>"); Element* pre = GetDocument().QuerySelector("pre"); @@ -910,7 +905,7 @@ EXPECT_EQ("Axyz", String(buffer.Data())); } -TEST_F(TextIteratorTest, StartInMultiCharFirstLetterInPre) { +TEST_P(TextIteratorTest, StartInMultiCharFirstLetterInPre) { SetBodyContent( "<style>pre:first-letter {color:red;}</style><pre>(A)xyz</pre>"); @@ -942,7 +937,7 @@ EXPECT_EQ("A)xyz", String(buffer.Data())); } -TEST_F(TextIteratorTest, StartAndEndInMultiCharFirstLetterInPre) { +TEST_P(TextIteratorTest, StartAndEndInMultiCharFirstLetterInPre) { SetBodyContent( "<style>pre:first-letter {color:red;}</style><pre>(A)xyz</pre>"); @@ -966,7 +961,7 @@ EXPECT_EQ("A", String(buffer.Data())); } -TEST_F(TextIteratorTest, StartAtRemainingTextInPre) { +TEST_P(TextIteratorTest, StartAtRemainingTextInPre) { SetBodyContent("<style>pre:first-letter {color:red;}</style><pre>Axyz</pre>"); Element* pre = GetDocument().QuerySelector("pre"); @@ -989,7 +984,7 @@ EXPECT_EQ("xyz", String(buffer.Data())); } -TEST_F(TextIteratorTest, VisitsDisplayContentsChildren) { +TEST_P(TextIteratorTest, VisitsDisplayContentsChildren) { SetBodyContent( "<p>Hello, \ntext</p><p style='display: contents'>iterator.</p>"); @@ -997,27 +992,27 @@ EXPECT_EQ("[Hello, ][text][iterator.]", Iterate<FlatTree>()); } -TEST_F(TextIteratorTest, BasicIterationEmptyContent) { +TEST_P(TextIteratorTest, BasicIterationEmptyContent) { SetBodyContent(""); EXPECT_EQ("", Iterate<DOMTree>()); } -TEST_F(TextIteratorTest, BasicIterationSingleCharacter) { +TEST_P(TextIteratorTest, BasicIterationSingleCharacter) { SetBodyContent("a"); EXPECT_EQ("[a]", Iterate<DOMTree>()); } -TEST_F(TextIteratorTest, BasicIterationSingleDiv) { +TEST_P(TextIteratorTest, BasicIterationSingleDiv) { SetBodyContent("<div>a</div>"); EXPECT_EQ("[a]", Iterate<DOMTree>()); } -TEST_F(TextIteratorTest, BasicIterationMultipleDivs) { +TEST_P(TextIteratorTest, BasicIterationMultipleDivs) { SetBodyContent("<div>a</div><div>b</div>"); EXPECT_EQ("[a][\n][b]", Iterate<DOMTree>()); } -TEST_F(TextIteratorTest, BasicIterationMultipleDivsWithStyle) { +TEST_P(TextIteratorTest, BasicIterationMultipleDivsWithStyle) { SetBodyContent( "<div style='line-height: 18px; min-height: 436px; '>" "debugging this note" @@ -1025,12 +1020,12 @@ EXPECT_EQ("[debugging this note]", Iterate<DOMTree>()); } -TEST_F(TextIteratorTest, BasicIterationMultipleDivsWithChildren) { +TEST_P(TextIteratorTest, BasicIterationMultipleDivsWithChildren) { SetBodyContent("<div>Hello<div><br><span></span></div></div>"); EXPECT_EQ("[Hello][\n][\n]", Iterate<DOMTree>()); } -TEST_F(TextIteratorTest, BasicIterationOnChildrenWithStyle) { +TEST_P(TextIteratorTest, BasicIterationOnChildrenWithStyle) { SetBodyContent( "<div style='left:22px'>" "</div>" @@ -1057,7 +1052,7 @@ EXPECT_EQ("[hey]", Iterate<DOMTree>()); } -TEST_F(TextIteratorTest, BasicIterationInput) { +TEST_P(TextIteratorTest, BasicIterationInput) { SetBodyContent("<input id='a' value='b'>"); auto* input_element = ToTextControl(GetDocument().getElementById("a")); const ShadowRoot* shadow_root = input_element->UserAgentShadowRoot(); @@ -1066,7 +1061,7 @@ EXPECT_EQ("[b]", IteratePartial<DOMTree>(start, end)); } -TEST_F(TextIteratorTest, BasicIterationInputiWithBr) { +TEST_P(TextIteratorTest, BasicIterationInputiWithBr) { SetBodyContent("<input id='a' value='b'>"); auto* input_element = ToTextControl(GetDocument().getElementById("a")); Element* inner_editor = input_element->InnerEditorElement(); @@ -1079,30 +1074,30 @@ EXPECT_EQ("[b]", IteratePartial<DOMTree>(start, end)); } -TEST_P(ParameterizedTextIteratorTest, FloatLeft) { +TEST_P(TextIteratorTest, FloatLeft) { SetBodyContent("abc<span style='float:left'>DEF</span>ghi"); EXPECT_EQ("[abc][DEF][ghi]", Iterate<DOMTree>()) << "float doesn't affect text iteration"; } -TEST_P(ParameterizedTextIteratorTest, FloatRight) { +TEST_P(TextIteratorTest, FloatRight) { SetBodyContent("abc<span style='float:right'>DEF</span>ghi"); EXPECT_EQ("[abc][DEF][ghi]", Iterate<DOMTree>()) << "float doesn't affect text iteration"; } -TEST_P(ParameterizedTextIteratorTest, InlineBlock) { +TEST_P(TextIteratorTest, InlineBlock) { SetBodyContent("abc<span style='display:inline-block'>DEF<br>GHI</span>jkl"); EXPECT_EQ("[abc][DEF][\n][GHI][jkl]", Iterate<DOMTree>()) << "inline-block doesn't insert newline around itself."; } -TEST_P(ParameterizedTextIteratorTest, NoZWSForSpaceAfterNoWrapSpace) { +TEST_P(TextIteratorTest, NoZWSForSpaceAfterNoWrapSpace) { SetBodyContent("<span style='white-space: nowrap'>foo </span> bar"); EXPECT_EQ("[foo ][bar]", Iterate<DOMTree>()); } -TEST_P(ParameterizedTextIteratorTest, PositionInShadowTree) { +TEST_P(TextIteratorTest, PositionInShadowTree) { // Flat Tree: <div id=host>A<slot name=c><img slot=c alt=C></slot></div> SetBodyContent("<div id=host><a></a><b></b><img slot=c alt=C></div>"); Element& host = *GetDocument().getElementById("host"); @@ -1134,20 +1129,20 @@ ASSERT_TRUE(it.AtEnd()); } -TEST_P(ParameterizedTextIteratorTest, HiddenFirstLetter) { +TEST_P(TextIteratorTest, HiddenFirstLetter) { InsertStyleElement("body::first-letter{visibility:hidden}"); SetBodyContent("foo"); EXPECT_EQ("[oo]", Iterate<DOMTree>()); } -TEST_P(ParameterizedTextIteratorTest, HiddenFirstLetterInPre) { +TEST_P(TextIteratorTest, HiddenFirstLetterInPre) { InsertStyleElement( "body::first-letter{visibility:hidden} body{white-space:pre}"); SetBodyContent("foo"); EXPECT_EQ("[oo]", Iterate<DOMTree>()); } -TEST_P(ParameterizedTextIteratorTest, TextOffsetMappingAndFlatTree) { +TEST_P(TextIteratorTest, TextOffsetMappingAndFlatTree) { // Tests that TextOffsetMapping should skip text control even though it runs // on flat tree. SetBodyContent("foo <input value='bla bla. bla bla.'> bar");
diff --git a/third_party/blink/renderer/core/editing/layout_selection_test.cc b/third_party/blink/renderer/core/editing/layout_selection_test.cc index 41d31c86..623e9e1 100644 --- a/third_party/blink/renderer/core/editing/layout_selection_test.cc +++ b/third_party/blink/renderer/core/editing/layout_selection_test.cc
@@ -30,7 +30,7 @@ return nullptr; } -class LayoutSelectionTest : public EditingTestBase { +class LayoutSelectionTestBase : public EditingTestBase { protected: static void PrintText(std::ostream& ostream, const Text& text) { ostream << "'" << text.data().Utf8().data() << "'"; @@ -42,12 +42,16 @@ SelectionState state) { const auto fragments = NGPaintFragment::InlineFragmentsFor(&layout_text); if (fragments.IsInLayoutNGInlineFormattingContext()) { + const unsigned text_start = + ToNGPhysicalTextFragment(fragments.begin()->PhysicalFragment()) + .StartOffset(); for (const NGPaintFragment* fragment : fragments) { const LayoutSelectionStatus status = selection.ComputeLayoutSelectionStatus(*fragment); if (state == SelectionState::kNone && status.start == status.end) continue; - ostream << "(" << status.start << "," << status.end << ")"; + ostream << "(" << status.start - text_start << "," + << status.end - text_start << ")"; } return; } @@ -139,7 +143,18 @@ } }; -TEST_F(LayoutSelectionTest, TraverseLayoutObject) { +class LayoutSelectionTest : public ::testing::WithParamInterface<bool>, + private ScopedLayoutNGForTest, + public LayoutSelectionTestBase { + protected: + LayoutSelectionTest() : ScopedLayoutNGForTest(GetParam()) {} + + bool LayoutNGEnabled() const { return GetParam(); } +}; + +INSTANTIATE_TEST_CASE_P(All, LayoutSelectionTest, ::testing::Bool()); + +TEST_P(LayoutSelectionTest, TraverseLayoutObject) { SetBodyContent("foo<br>bar"); Selection().SetSelectionAndEndTyping( SelectionInDOMTree::Builder() @@ -154,7 +169,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, TraverseLayoutObjectTruncateVisibilityHidden) { +TEST_P(LayoutSelectionTest, TraverseLayoutObjectTruncateVisibilityHidden) { SetBodyContent( "<span style='visibility:hidden;'>before</span>" "foo" @@ -174,24 +189,35 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, TraverseLayoutObjectBRs) { +TEST_P(LayoutSelectionTest, TraverseLayoutObjectBRs) { SetBodyContent("<br><br>foo<br><br>"); Selection().SetSelectionAndEndTyping( SelectionInDOMTree::Builder() .SelectAllChildren(*GetDocument().body()) .Build()); Selection().CommitAppearanceIfNeeded(); - EXPECT_EQ( - "BODY, Contain, NotInvalidate \n" - " BR, Start(0,1), ShouldInvalidate \n" - " BR, Inside(0,1), ShouldInvalidate \n" - " 'foo', Inside(0,3), ShouldInvalidate \n" - " BR, Inside(0,1), ShouldInvalidate \n" - " BR, End(0,0), ShouldInvalidate ", - DumpSelectionInfo()); + if (LayoutNGEnabled()) { + EXPECT_EQ( + "BODY, Contain, NotInvalidate \n" + " BR, Start(0,1), ShouldInvalidate \n" + " BR, Inside(0,1), ShouldInvalidate \n" + " 'foo', Inside(0,3), ShouldInvalidate \n" + " BR, Inside(0,1), ShouldInvalidate \n" + " BR, End(0,1), ShouldInvalidate ", + DumpSelectionInfo()); + } else { + EXPECT_EQ( + "BODY, Contain, NotInvalidate \n" + " BR, Start(0,1), ShouldInvalidate \n" + " BR, Inside(0,1), ShouldInvalidate \n" + " 'foo', Inside(0,3), ShouldInvalidate \n" + " BR, Inside(0,1), ShouldInvalidate \n" + " BR, End(0,0), ShouldInvalidate ", + DumpSelectionInfo()); + } } -TEST_F(LayoutSelectionTest, TraverseLayoutObjectListStyleImage) { +TEST_P(LayoutSelectionTest, TraverseLayoutObjectListStyleImage) { SetBodyContent( "<style>ul {list-style-image:url(data:" "image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=)}" @@ -213,7 +239,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, TraverseLayoutObjectCrossingShadowBoundary) { +TEST_P(LayoutSelectionTest, TraverseLayoutObjectCrossingShadowBoundary) { Selection().SetSelectionAndEndTyping(SetSelectionTextToBody( "^foo" "<div>" @@ -240,7 +266,7 @@ } // crbug.com/752715 -TEST_F(LayoutSelectionTest, +TEST_P(LayoutSelectionTest, InvalidationShouldNotChangeRefferedLayoutObjectState) { SetBodyContent( "<div id='d1'>div1</div><div id='d2'>foo<span>bar</span>baz</div>"); @@ -282,20 +308,27 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, TraverseLayoutObjectLineWrap) { +TEST_P(LayoutSelectionTest, TraverseLayoutObjectLineWrap) { SetBodyContent("bar\n"); Selection().SetSelectionAndEndTyping( SelectionInDOMTree::Builder() .SelectAllChildren(*GetDocument().body()) .Build()); Selection().CommitAppearanceIfNeeded(); - EXPECT_EQ( - "BODY, Contain, NotInvalidate \n" - " 'bar\n', StartAndEnd(0,4), ShouldInvalidate ", - DumpSelectionInfo()); + if (LayoutNGEnabled()) { + EXPECT_EQ( + "BODY, Contain, NotInvalidate \n" + " 'bar\n', StartAndEnd(0,3), ShouldInvalidate ", + DumpSelectionInfo()); + } else { + EXPECT_EQ( + "BODY, Contain, NotInvalidate \n" + " 'bar\n', StartAndEnd(0,4), ShouldInvalidate ", + DumpSelectionInfo()); + } } -TEST_F(LayoutSelectionTest, FirstLetter) { +TEST_P(LayoutSelectionTest, FirstLetter) { SetBodyContent( "<style>::first-letter { color: red; }</style>" "<span>foo</span>"); @@ -313,21 +346,31 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, FirstLetterMultiple) { +TEST_P(LayoutSelectionTest, FirstLetterMultiple) { Selection().SetSelectionAndEndTyping( SetSelectionTextToBody("<style>::first-letter { color: red; }</style>" "<span> [^f]o|o</span>")); Selection().CommitAppearanceIfNeeded(); - EXPECT_EQ( - "BODY, Contain, NotInvalidate \n" - " <style> \n" - " SPAN, Contain, NotInvalidate \n" - " ' [f]oo', StartAndEnd(0,1), ShouldInvalidate \n" - " :first-letter, None(2,4), ShouldInvalidate ", - DumpSelectionInfo()); + if (LayoutNGEnabled()) { + EXPECT_EQ( + "BODY, Contain, NotInvalidate \n" + " <style> \n" + " SPAN, Contain, NotInvalidate \n" + " ' [f]oo', StartAndEnd(0,1), ShouldInvalidate \n" + " :first-letter, None(1,3), ShouldInvalidate ", + DumpSelectionInfo()); + } else { + EXPECT_EQ( + "BODY, Contain, NotInvalidate \n" + " <style> \n" + " SPAN, Contain, NotInvalidate \n" + " ' [f]oo', StartAndEnd(0,1), ShouldInvalidate \n" + " :first-letter, None(2,4), ShouldInvalidate ", + DumpSelectionInfo()); + } } -TEST_F(LayoutSelectionTest, FirstLetterClearSeletion) { +TEST_P(LayoutSelectionTest, FirstLetterClearSeletion) { InsertStyleElement("div::first-letter { color: red; }"); Selection().SetSelectionAndEndTyping( SetSelectionTextToBody("fo^o<div>bar</div>b|az")); @@ -353,7 +396,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, FirstLetterUpdateSeletion) { +TEST_P(LayoutSelectionTest, FirstLetterUpdateSeletion) { SetBodyContent( "<style>div::first-letter { color: red; }</style>" "foo<div>bar</div>baz"); @@ -406,7 +449,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, CommitAppearanceIfNeededNotCrash) { +TEST_P(LayoutSelectionTest, CommitAppearanceIfNeededNotCrash) { Selection().SetSelectionAndEndTyping(SetSelectionTextToBody( "<div>" "<template data-mode=open>foo</template>" @@ -416,7 +459,7 @@ Selection().CommitAppearanceIfNeeded(); } -TEST_F(LayoutSelectionTest, SelectImage) { +TEST_P(LayoutSelectionTest, SelectImage) { const SelectionInDOMTree& selection = SetSelectionTextToBody("^<img style=\"width:100px; height:100px\"/>|"); Selection().SetSelectionAndEndTyping(selection); @@ -427,7 +470,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, MoveOnSameNode_Start) { +TEST_P(LayoutSelectionTest, MoveOnSameNode_Start) { const SelectionInDOMTree& selection = SetSelectionTextToBody("f^oo<span>b|ar</span>"); Selection().SetSelectionAndEndTyping(selection); @@ -464,7 +507,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, MoveOnSameNode_End) { +TEST_P(LayoutSelectionTest, MoveOnSameNode_End) { const SelectionInDOMTree& selection = SetSelectionTextToBody("f^oo<span>b|ar</span>"); Selection().SetSelectionAndEndTyping(selection); @@ -501,7 +544,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, MoveOnSameNode_StartAndEnd) { +TEST_P(LayoutSelectionTest, MoveOnSameNode_StartAndEnd) { const SelectionInDOMTree& selection = SetSelectionTextToBody("f^oob|ar"); Selection().SetSelectionAndEndTyping(selection); Selection().CommitAppearanceIfNeeded(); @@ -531,7 +574,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, MoveOnSameNode_StartAndEnd_Collapse) { +TEST_P(LayoutSelectionTest, MoveOnSameNode_StartAndEnd_Collapse) { const SelectionInDOMTree& selection = SetSelectionTextToBody("f^oob|ar"); Selection().SetSelectionAndEndTyping(selection); Selection().CommitAppearanceIfNeeded(); @@ -560,7 +603,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, ContentEditableButton) { +TEST_P(LayoutSelectionTest, ContentEditableButton) { SetBodyContent("<input type=button value=foo contenteditable>"); Selection().SetSelectionAndEndTyping( SelectionInDOMTree::Builder() @@ -575,7 +618,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, ClearSelection) { +TEST_P(LayoutSelectionTest, ClearSelection) { Selection().SetSelectionAndEndTyping( SetSelectionTextToBody("<div>f^o|o</div>")); Selection().CommitAppearanceIfNeeded(); @@ -601,7 +644,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, SVG) { +TEST_P(LayoutSelectionTest, SVG) { const SelectionInDOMTree& selection = SetSelectionTextToBody("<svg><text x=10 y=10>fo^o|bar</text></svg>"); Selection().SetSelectionAndEndTyping(selection); @@ -637,7 +680,7 @@ } // crbug.com/781705 -TEST_F(LayoutSelectionTest, SVGAncestor) { +TEST_P(LayoutSelectionTest, SVGAncestor) { const SelectionInDOMTree& selection = SetSelectionTextToBody( "<svg><text x=10 y=10><tspan>fo^o|bar</tspan></text></svg>"); Selection().SetSelectionAndEndTyping(selection); @@ -675,7 +718,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, Embed) { +TEST_P(LayoutSelectionTest, Embed) { Selection().SetSelectionAndEndTyping( SetSelectionTextToBody("^<embed type=foobar></embed>|")); Selection().CommitAppearanceIfNeeded(); @@ -688,7 +731,7 @@ } // http:/crbug.com/843144 -TEST_F(LayoutSelectionTest, Ruby) { +TEST_P(LayoutSelectionTest, Ruby) { Selection().SetSelectionAndEndTyping( SetSelectionTextToBody("^<ruby>foo<rt>bar</rt></ruby>|")); Selection().CommitAppearanceIfNeeded(); @@ -720,7 +763,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, ClearByRemoveNode) { +TEST_P(LayoutSelectionTest, ClearByRemoveNode) { Selection().SetSelectionAndEndTyping( SetSelectionTextToBody("^foo<span>bar</span>baz|")); Selection().CommitAppearanceIfNeeded(); @@ -750,7 +793,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, ClearByRemoveLayoutObject) { +TEST_P(LayoutSelectionTest, ClearByRemoveLayoutObject) { Selection().SetSelectionAndEndTyping( SetSelectionTextToBody("^foo<span>bar</span><span>baz</span>|")); Selection().CommitAppearanceIfNeeded(); @@ -785,7 +828,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, ClearBySlotChange) { +TEST_P(LayoutSelectionTest, ClearBySlotChange) { Selection().SetSelectionAndEndTyping( SetSelectionTextToBody("<div>" "<template data-mode=open>" @@ -833,7 +876,7 @@ DumpSelectionInfo()); } -TEST_F(LayoutSelectionTest, MoveNode) { +TEST_P(LayoutSelectionTest, MoveNode) { Selection().SetSelectionAndEndTyping(SetSelectionTextToBody( "<div id='div1'></div><div id='div2'>^foo<b>ba|r</b></div>")); Selection().CommitAppearanceIfNeeded(); @@ -869,7 +912,7 @@ } // http://crbug.com/870734 -TEST_F(LayoutSelectionTest, InvalidateSlot) { +TEST_P(LayoutSelectionTest, InvalidateSlot) { Selection().SetSelectionAndEndTyping( SetSelectionTextToBody("^<div>" "<template data-mode=open>" @@ -924,7 +967,7 @@ } class NGLayoutSelectionTest - : public LayoutSelectionTest, + : public LayoutSelectionTestBase, private ScopedLayoutNGForTest, private ScopedPaintUnderInvalidationCheckingForTest { public: @@ -979,7 +1022,7 @@ "BODY, Contain, NotInvalidate \n" " 'foo', None, NotInvalidate \n" " SPAN, Contain, NotInvalidate \n" - " 'bar', StartAndEnd(4,5), ShouldInvalidate ", + " 'bar', StartAndEnd(1,2), ShouldInvalidate ", DumpSelectionInfo()); } @@ -989,7 +1032,7 @@ EXPECT_EQ( "BODY, Contain, NotInvalidate \n" " <style> \n" - " 'foo', StartAndEnd(1,2), ShouldInvalidate \n" + " 'foo', StartAndEnd(0,1), ShouldInvalidate \n" " :first-letter, None(0,1), ShouldInvalidate ", DumpSelectionInfo()); }
diff --git a/third_party/blink/renderer/core/exported/web_meaningful_layouts_test.cc b/third_party/blink/renderer/core/exported/web_meaningful_layouts_test.cc index 4185130..cca943f 100644 --- a/third_party/blink/renderer/core/exported/web_meaningful_layouts_test.cc +++ b/third_party/blink/renderer/core/exported/web_meaningful_layouts_test.cc
@@ -210,10 +210,11 @@ "<link rel=\"stylesheet\" href=\"style.css\">" "</head><body></body></html>"); - GetDocument().UpdateStyleAndLayoutTreeIgnorePendingStylesheets(); - EXPECT_TRUE(GetDocument().DidLayoutWithPendingStylesheets()); + GetDocument().UpdateStyleAndLayoutTree(); + EXPECT_FALSE(GetDocument().IsRenderingReady()); style_resource.Complete(""); + EXPECT_TRUE(GetDocument().IsRenderingReady()); } // A pending stylesheet in the body is not render-blocking and should not @@ -248,10 +249,13 @@ "<link rel=\"import\" href=\"import.html\">" "</head><body></body></html>"); - GetDocument().UpdateStyleAndLayoutTreeIgnorePendingStylesheets(); - EXPECT_TRUE(GetDocument().DidLayoutWithPendingStylesheets()); + GetDocument().UpdateStyleAndLayoutTree(); + EXPECT_FALSE(GetDocument().IsRenderingReady()); import_resource.Complete(""); + // Pump the HTMLImportTreeRoot::RecalcTimerFired task. + test::RunPendingTasks(); + EXPECT_TRUE(GetDocument().IsRenderingReady()); } // A pending import in the body is render-blocking and will be treated like @@ -267,10 +271,13 @@ "<link rel=\"import\" href=\"import.html\">" "</body></html>"); - GetDocument().UpdateStyleAndLayoutTreeIgnorePendingStylesheets(); - EXPECT_TRUE(GetDocument().DidLayoutWithPendingStylesheets()); + GetDocument().UpdateStyleAndLayoutTree(); + EXPECT_FALSE(GetDocument().IsRenderingReady()); import_resource.Complete(""); + // Pump the HTMLImportTreeRoot::RecalcTimerFired task. + test::RunPendingTasks(); + EXPECT_TRUE(GetDocument().IsRenderingReady()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/fileapi/file_error.cc b/third_party/blink/renderer/core/fileapi/file_error.cc index 8446746b..4fbca677 100644 --- a/third_party/blink/renderer/core/fileapi/file_error.cc +++ b/third_party/blink/renderer/core/fileapi/file_error.cc
@@ -72,33 +72,33 @@ namespace { -DOMExceptionCode ErrorCodeToExceptionCode(ErrorCode code) { +DOMExceptionCode ErrorCodeToExceptionCode(FileErrorCode code) { switch (code) { - case ErrorCode::kOK: + case FileErrorCode::kOK: return DOMExceptionCode::kNoError; - case ErrorCode::kNotFoundErr: + case FileErrorCode::kNotFoundErr: return DOMExceptionCode::kNotFoundError; - case ErrorCode::kSecurityErr: + case FileErrorCode::kSecurityErr: return DOMExceptionCode::kSecurityError; - case ErrorCode::kAbortErr: + case FileErrorCode::kAbortErr: return DOMExceptionCode::kAbortError; - case ErrorCode::kNotReadableErr: + case FileErrorCode::kNotReadableErr: return DOMExceptionCode::kNotReadableError; - case ErrorCode::kEncodingErr: + case FileErrorCode::kEncodingErr: return DOMExceptionCode::kEncodingError; - case ErrorCode::kNoModificationAllowedErr: + case FileErrorCode::kNoModificationAllowedErr: return DOMExceptionCode::kNoModificationAllowedError; - case ErrorCode::kInvalidStateErr: + case FileErrorCode::kInvalidStateErr: return DOMExceptionCode::kInvalidStateError; - case ErrorCode::kSyntaxErr: + case FileErrorCode::kSyntaxErr: return DOMExceptionCode::kSyntaxError; - case ErrorCode::kInvalidModificationErr: + case FileErrorCode::kInvalidModificationErr: return DOMExceptionCode::kInvalidModificationError; - case ErrorCode::kQuotaExceededErr: + case FileErrorCode::kQuotaExceededErr: return DOMExceptionCode::kQuotaExceededError; - case ErrorCode::kTypeMismatchErr: + case FileErrorCode::kTypeMismatchErr: return DOMExceptionCode::kTypeMismatchError; - case ErrorCode::kPathExistsErr: + case FileErrorCode::kPathExistsErr: return DOMExceptionCode::kPathExistsError; default: NOTREACHED(); @@ -106,35 +106,35 @@ } } -const char* ErrorCodeToMessage(ErrorCode code) { +const char* ErrorCodeToMessage(FileErrorCode code) { // Note that some of these do not set message. If message is 0 then the // default message is used. switch (code) { - case ErrorCode::kOK: + case FileErrorCode::kOK: return nullptr; - case ErrorCode::kSecurityErr: + case FileErrorCode::kSecurityErr: return kSecurityErrorMessage; - case ErrorCode::kNotFoundErr: + case FileErrorCode::kNotFoundErr: return kNotFoundErrorMessage; - case ErrorCode::kAbortErr: + case FileErrorCode::kAbortErr: return kAbortErrorMessage; - case ErrorCode::kNotReadableErr: + case FileErrorCode::kNotReadableErr: return kNotReadableErrorMessage; - case ErrorCode::kEncodingErr: + case FileErrorCode::kEncodingErr: return kEncodingErrorMessage; - case ErrorCode::kNoModificationAllowedErr: + case FileErrorCode::kNoModificationAllowedErr: return kNoModificationAllowedErrorMessage; - case ErrorCode::kInvalidStateErr: + case FileErrorCode::kInvalidStateErr: return kInvalidStateErrorMessage; - case ErrorCode::kSyntaxErr: + case FileErrorCode::kSyntaxErr: return kSyntaxErrorMessage; - case ErrorCode::kInvalidModificationErr: + case FileErrorCode::kInvalidModificationErr: return nullptr; - case ErrorCode::kQuotaExceededErr: + case FileErrorCode::kQuotaExceededErr: return kQuotaExceededErrorMessage; - case ErrorCode::kTypeMismatchErr: + case FileErrorCode::kTypeMismatchErr: return nullptr; - case ErrorCode::kPathExistsErr: + case FileErrorCode::kPathExistsErr: return kPathExistsErrorMessage; default: NOTREACHED(); @@ -229,14 +229,14 @@ } // namespace void ThrowDOMException(ExceptionState& exception_state, - ErrorCode code, + FileErrorCode code, String message) { - if (code == ErrorCode::kOK) + if (code == FileErrorCode::kOK) return; // SecurityError is special-cased, as we want to route those exceptions // through ExceptionState::ThrowSecurityError. - if (code == ErrorCode::kSecurityErr) { + if (code == FileErrorCode::kSecurityErr) { exception_state.ThrowSecurityError(kSecurityErrorMessage); return; } @@ -268,8 +268,8 @@ exception_state.ThrowDOMException(FileErrorToExceptionCode(error), message); } -DOMException* CreateDOMException(ErrorCode code) { - DCHECK_NE(code, ErrorCode::kOK); +DOMException* CreateDOMException(FileErrorCode code) { + DCHECK_NE(code, FileErrorCode::kOK); return DOMException::Create(ErrorCodeToExceptionCode(code), ErrorCodeToMessage(code)); }
diff --git a/third_party/blink/renderer/core/fileapi/file_error.h b/third_party/blink/renderer/core/fileapi/file_error.h index e880fe9..ac22e5e 100644 --- a/third_party/blink/renderer/core/fileapi/file_error.h +++ b/third_party/blink/renderer/core/fileapi/file_error.h
@@ -40,9 +40,7 @@ class DOMException; class ExceptionState; -namespace file_error { - -enum class ErrorCode { +enum class FileErrorCode { kOK = 0, kNotFoundErr = 1, kSecurityErr = 2, @@ -58,6 +56,8 @@ kPathExistsErr = 12, }; +namespace file_error { + CORE_EXPORT extern const char kAbortErrorMessage[]; CORE_EXPORT extern const char kEncodingErrorMessage[]; CORE_EXPORT extern const char kInvalidStateErrorMessage[]; @@ -71,12 +71,12 @@ CORE_EXPORT extern const char kTypeMismatchErrorMessage[]; CORE_EXPORT void ThrowDOMException(ExceptionState&, - ErrorCode, + FileErrorCode, String message = String()); CORE_EXPORT void ThrowDOMException(ExceptionState& exception_state, base::File::Error error, String message = String()); -CORE_EXPORT DOMException* CreateDOMException(ErrorCode); +CORE_EXPORT DOMException* CreateDOMException(FileErrorCode); CORE_EXPORT DOMException* CreateDOMException(base::File::Error); } // namespace file_error
diff --git a/third_party/blink/renderer/core/fileapi/file_reader.cc b/third_party/blink/renderer/core/fileapi/file_reader.cc index 223fdc9..d0eae59 100644 --- a/third_party/blink/renderer/core/fileapi/file_reader.cc +++ b/third_party/blink/renderer/core/fileapi/file_reader.cc
@@ -338,7 +338,7 @@ base::AutoReset<bool> firing_events(&still_firing_events_, true); // Setting error implicitly makes |result| return null. - error_ = file_error::CreateDOMException(file_error::ErrorCode::kAbortErr); + error_ = file_error::CreateDOMException(FileErrorCode::kAbortErr); // Unregister the reader. ThrottlingController::FinishReaderType final_step = @@ -432,7 +432,7 @@ ThrottlingController::FinishReader(GetExecutionContext(), this, final_step); } -void FileReader::DidFail(file_error::ErrorCode error_code) { +void FileReader::DidFail(FileErrorCode error_code) { if (loading_state_ == kLoadingStateAborted) return;
diff --git a/third_party/blink/renderer/core/fileapi/file_reader.h b/third_party/blink/renderer/core/fileapi/file_reader.h index cc044c3..42df8cca 100644 --- a/third_party/blink/renderer/core/fileapi/file_reader.h +++ b/third_party/blink/renderer/core/fileapi/file_reader.h
@@ -43,13 +43,10 @@ namespace blink { -namespace file_error { -enum class ErrorCode; -} - class Blob; class ExceptionState; class ExecutionContext; +enum class FileErrorCode; class StringOrArrayBuffer; class CORE_EXPORT FileReader final : public EventTargetWithInlineData, @@ -93,7 +90,7 @@ void DidStartLoading() override; void DidReceiveData() override; void DidFinishLoading() override; - void DidFail(file_error::ErrorCode) override; + void DidFail(FileErrorCode) override; DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart, kLoadstart); DEFINE_ATTRIBUTE_EVENT_LISTENER(progress, kProgress);
diff --git a/third_party/blink/renderer/core/fileapi/file_reader_loader.cc b/third_party/blink/renderer/core/fileapi/file_reader_loader.cc index c2321ac7..5a1cc40 100644 --- a/third_party/blink/renderer/core/fileapi/file_reader_loader.cc +++ b/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
@@ -100,8 +100,7 @@ mojo::ScopedDataPipeProducerHandle producer_handle; MojoResult rv = CreateDataPipe(&options, &producer_handle, &consumer_handle_); if (rv != MOJO_RESULT_OK) { - Failed(file_error::ErrorCode::kNotReadableErr, - FailureType::kMojoPipeCreation); + Failed(FileErrorCode::kNotReadableErr, FailureType::kMojoPipeCreation); return; } @@ -116,7 +115,7 @@ if (received_on_complete_) return; if (!received_all_data_) { - Failed(file_error::ErrorCode::kNotReadableErr, + Failed(FileErrorCode::kNotReadableErr, FailureType::kSyncDataNotAllLoaded); return; } @@ -124,14 +123,14 @@ // Wait for OnComplete binding_.WaitForIncomingMethodCall(); if (!received_on_complete_) { - Failed(file_error::ErrorCode::kNotReadableErr, + Failed(FileErrorCode::kNotReadableErr, FailureType::kSyncOnCompleteNotReceived); } } } void FileReaderLoader::Cancel() { - error_code_ = file_error::ErrorCode::kAbortErr; + error_code_ = FileErrorCode::kAbortErr; Cleanup(); } @@ -141,7 +140,7 @@ return array_buffer_result_; // If the loading is not started or an error occurs, return an empty result. - if (!raw_data_ || error_code_ != file_error::ErrorCode::kOK) + if (!raw_data_ || error_code_ != FileErrorCode::kOK) return nullptr; DOMArrayBuffer* result = DOMArrayBuffer::Create(raw_data_->ToArrayBuffer()); @@ -158,7 +157,7 @@ DCHECK_NE(read_type_, kReadAsArrayBuffer); DCHECK_NE(read_type_, kReadByClient); - if (!raw_data_ || (error_code_ != file_error::ErrorCode::kOK) || + if (!raw_data_ || (error_code_ != FileErrorCode::kOK) || is_raw_data_converted_) { return string_result_; } @@ -201,7 +200,7 @@ consumer_handle_.reset(); // If we get any error, we do not need to keep a buffer around. - if (error_code_ != file_error::ErrorCode::kOK) { + if (error_code_ != FileErrorCode::kOK) { raw_data_.reset(); string_result_ = ""; is_raw_data_converted_ = true; @@ -211,13 +210,12 @@ } } -void FileReaderLoader::Failed(file_error::ErrorCode error_code, - FailureType type) { +void FileReaderLoader::Failed(FileErrorCode error_code, FailureType type) { DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, failure_histogram, ("Storage.Blob.FileReaderLoader.FailureType", static_cast<int>(FailureType::kCount))); // If an error was already reported, don't report this error again. - if (error_code_ != file_error::ErrorCode::kOK) + if (error_code_ != FileErrorCode::kOK) return; error_code_ = error_code; failure_histogram.Count(static_cast<int>(type)); @@ -236,14 +234,13 @@ // so to call ArrayBuffer's create function. // FIXME: Support reading more than the current size limit of ArrayBuffer. if (total_bytes > std::numeric_limits<unsigned>::max()) { - Failed(file_error::ErrorCode::kNotReadableErr, - FailureType::kTotalBytesTooLarge); + Failed(FileErrorCode::kNotReadableErr, FailureType::kTotalBytesTooLarge); return; } raw_data_ = std::make_unique<ArrayBufferBuilder>(total_bytes); if (!raw_data_->IsValid()) { - Failed(file_error::ErrorCode::kNotReadableErr, + Failed(FileErrorCode::kNotReadableErr, FailureType::kArrayBufferBuilderCreation); return; } @@ -258,7 +255,7 @@ DCHECK(data); // Bail out if we already encountered an error. - if (error_code_ != file_error::ErrorCode::kOK) + if (error_code_ != FileErrorCode::kOK) return; if (read_type_ == kReadByClient) { @@ -273,7 +270,7 @@ if (!bytes_appended) { raw_data_.reset(); bytes_loaded_ = 0; - Failed(file_error::ErrorCode::kNotReadableErr, + Failed(FileErrorCode::kNotReadableErr, FailureType::kArrayBufferBuilderAppend); return; } @@ -329,15 +326,13 @@ if (status != net::OK) { net_error_ = status; file_reader_loader_read_errors_histogram.Sample(std::max(0, -net_error_)); - Failed(status == net::ERR_FILE_NOT_FOUND - ? file_error::ErrorCode::kNotFoundErr - : file_error::ErrorCode::kNotReadableErr, + Failed(status == net::ERR_FILE_NOT_FOUND ? FileErrorCode::kNotFoundErr + : FileErrorCode::kNotReadableErr, FailureType::kBackendReadError); return; } if (data_length != total_bytes_) { - Failed(file_error::ErrorCode::kNotReadableErr, - FailureType::kReadSizesIncorrect); + Failed(FileErrorCode::kNotReadableErr, FailureType::kReadSizesIncorrect); return; } @@ -349,7 +344,7 @@ void FileReaderLoader::OnDataPipeReadable(MojoResult result) { if (result != MOJO_RESULT_OK) { if (!received_all_data_) { - Failed(file_error::ErrorCode::kNotReadableErr, + Failed(FileErrorCode::kNotReadableErr, FailureType::kDataPipeNotReadableWithBytesLeft); } return; @@ -371,13 +366,13 @@ if (result == MOJO_RESULT_FAILED_PRECONDITION) { // Pipe closed. if (!received_all_data_) { - Failed(file_error::ErrorCode::kNotReadableErr, + Failed(FileErrorCode::kNotReadableErr, FailureType::kMojoPipeClosedEarly); } return; } if (result != MOJO_RESULT_OK) { - Failed(file_error::ErrorCode::kNotReadableErr, + Failed(FileErrorCode::kNotReadableErr, FailureType::kMojoPipeUnexpectedReadError); return; }
diff --git a/third_party/blink/renderer/core/fileapi/file_reader_loader.h b/third_party/blink/renderer/core/fileapi/file_reader_loader.h index b445933b..9f238c87 100644 --- a/third_party/blink/renderer/core/fileapi/file_reader_loader.h +++ b/third_party/blink/renderer/core/fileapi/file_reader_loader.h
@@ -97,7 +97,7 @@ // After OnCalculatedSize() is called: Returns the size of the resource. base::Optional<uint64_t> TotalBytes() const { return total_bytes_; } - file_error::ErrorCode GetErrorCode() const { return error_code_; } + FileErrorCode GetErrorCode() const { return error_code_; } int32_t GetNetError() const { return net_error_; } @@ -128,7 +128,7 @@ }; void Cleanup(); - void Failed(file_error::ErrorCode, FailureType type); + void Failed(FileErrorCode, FailureType type); void OnStartLoading(uint64_t total_bytes); void OnReceivedData(const char* data, unsigned data_length); @@ -172,7 +172,7 @@ int64_t memory_usage_reported_to_v8_ = 0; int32_t net_error_ = 0; // net::OK - file_error::ErrorCode error_code_ = file_error::ErrorCode::kOK; + FileErrorCode error_code_ = FileErrorCode::kOK; mojo::ScopedDataPipeConsumerHandle consumer_handle_; mojo::SimpleWatcher handle_watcher_;
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 bc5728a2..747a254 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
@@ -36,9 +36,7 @@ namespace blink { -namespace file_error { -enum class ErrorCode; -} +enum class FileErrorCode; class CORE_EXPORT FileReaderLoaderClient { public: @@ -54,7 +52,7 @@ NOTREACHED(); } virtual void DidFinishLoading() = 0; - virtual void DidFail(file_error::ErrorCode) = 0; + virtual void DidFail(FileErrorCode) = 0; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/fileapi/file_reader_sync.cc b/third_party/blink/renderer/core/fileapi/file_reader_sync.cc index 8d515827e..4357025 100644 --- a/third_party/blink/renderer/core/fileapi/file_reader_sync.cc +++ b/third_party/blink/renderer/core/fileapi/file_reader_sync.cc
@@ -116,7 +116,7 @@ const Blob& blob, ExceptionState& exception_state) { loader.Start(blob.GetBlobDataHandle()); - if (loader.GetErrorCode() != file_error::ErrorCode::kOK) + if (loader.GetErrorCode() != FileErrorCode::kOK) file_error::ThrowDOMException(exception_state, loader.GetErrorCode()); }
diff --git a/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc b/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc index ebda232..632f550 100644 --- a/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc +++ b/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc
@@ -422,13 +422,11 @@ // Import loader isn't finish, shoudn't paint. EXPECT_FALSE(GetDocument().IsRenderingReady()); - // If ignoringPendingStylesheets==true, element should get non-empty rect. + // Pending imports should not block layout Element* element = GetDocument().getElementById("test"); DOMRect* rect = element->getBoundingClientRect(); EXPECT_TRUE(rect->width() > 0.f); EXPECT_TRUE(rect->height() > 0.f); - - // After reset ignoringPendingStylesheets, we should block rendering again. EXPECT_FALSE(GetDocument().IsRenderingReady()); import_resource.Write("div { color: red; }");
diff --git a/third_party/blink/renderer/core/frame/frame.cc b/third_party/blink/renderer/core/frame/frame.cc index bcad5c7..3739269 100644 --- a/third_party/blink/renderer/core/frame/frame.cc +++ b/third_party/blink/renderer/core/frame/frame.cc
@@ -79,6 +79,10 @@ lifecycle_.AdvanceTo(FrameLifecycle::kDetaching); DetachImpl(type); + + if (GetPage()) + GetPage()->GetFocusController().FrameDetached(this); + // Due to re-entrancy, |this| could have completed detaching already. // TODO(dcheng): This DCHECK is not always true. See https://crbug.com/838348. DCHECK(IsDetached() == !client_);
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index abaed98..9ab834fd 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -30,7 +30,9 @@ #include "third_party/blink/renderer/core/frame/local_frame.h" +#include <limits> #include <memory> +#include <utility> #include "services/network/public/cpp/features.h" #include "services/service_manager/public/cpp/connector.h" @@ -426,9 +428,6 @@ DomWindow()->FrameDestroyed(); - if (GetPage() && GetPage()->GetFocusController().FocusedFrame() == this) - GetPage()->GetFocusController().SetFocusedFrame(nullptr); - probe::frameDetachedFromParent(this); supplements_.clear();
diff --git a/third_party/blink/renderer/core/html/forms/file_chooser.cc b/third_party/blink/renderer/core/html/forms/file_chooser.cc index f40ab7aa..5def216 100644 --- a/third_party/blink/renderer/core/html/forms/file_chooser.cc +++ b/third_party/blink/renderer/core/html/forms/file_chooser.cc
@@ -103,8 +103,11 @@ } void FileChooser::DidChooseFiles(mojom::blink::FileChooserResultPtr result) { - DCHECK(result); - FileChooserFileInfoList files = std::move(result->files); + // TODO(tkent): If |result| is nullptr, we should not clear the + // already-selected files in <input type=file> like other browsers. + FileChooserFileInfoList files; + if (result) + files = std::move(result->files); // FIXME: This is inelegant. We should not be looking at params_ here. if (params_->selected_files.size() == files.size()) { bool was_changed = false; @@ -129,8 +132,10 @@ } } - if (client_) - client_->FilesChosen(std::move(files), result->base_directory); + if (client_) { + client_->FilesChosen(std::move(files), + result ? result->base_directory : base::FilePath()); + } DidCloseChooser(); }
diff --git a/third_party/blink/renderer/core/html/forms/form_data.cc b/third_party/blink/renderer/core/html/forms/form_data.cc index 3ac5fe468..6fbc506 100644 --- a/third_party/blink/renderer/core/html/forms/form_data.cc +++ b/third_party/blink/renderer/core/html/forms/form_data.cc
@@ -91,8 +91,11 @@ FormData* FormData::Create(HTMLFormElement* form, ExceptionState& exception_state) { - DCHECK(form); auto* form_data = new FormData(); + // TODO(tkent): Null check should be unnecessary. We should remove + // LegacyInterfaceTypeChecking from form_data.idl. crbug.com/561338 + if (!form) + return form_data; if (!form->ConstructEntryList(nullptr, *form_data)) { DCHECK(RuntimeEnabledFeatures::FormDataEventEnabled()); exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc index d1e8a89b..44891e8c9 100644 --- a/third_party/blink/renderer/core/html/html_element.cc +++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -1413,8 +1413,9 @@ ElementInternals* HTMLElement::attachInternals( ExceptionState& exception_state) { + CustomElementRegistry* registry = CustomElement::Registry(*this); auto* definition = - CustomElement::Registry(*this)->DefinitionForName(localName()); + registry ? registry->DefinitionForName(localName()) : nullptr; if (!definition) { exception_state.ThrowDOMException( DOMExceptionCode::kInvalidStateError,
diff --git a/third_party/blink/renderer/core/html/html_frame_set_element.cc b/third_party/blink/renderer/core/html/html_frame_set_element.cc index 42150f9a..2950a08f 100644 --- a/third_party/blink/renderer/core/html/html_frame_set_element.cc +++ b/third_party/blink/renderer/core/html/html_frame_set_element.cc
@@ -213,8 +213,7 @@ bool HTMLFrameSetElement::LayoutObjectIsNeeded( const ComputedStyle& style) const { // For compatibility, frames layoutObject even when display: none is set. - // However, we delay creating a layoutObject until stylesheets have loaded. - return style.IsStyleAvailable(); + return true; } LayoutObject* HTMLFrameSetElement::CreateLayoutObject(
diff --git a/third_party/blink/renderer/core/html/html_slot_element.cc b/third_party/blink/renderer/core/html/html_slot_element.cc index 62693d5..7a9df98 100644 --- a/third_party/blink/renderer/core/html/html_slot_element.cc +++ b/third_party/blink/renderer/core/html/html_slot_element.cc
@@ -204,12 +204,14 @@ flat_tree_node_data.SetAssignedSlot(this); flat_tree_node_data.SetPreviousInAssignedNodes(previous); if (previous) { - previous->GetFlatTreeNodeData().SetNextInAssignedNodes(current); + DCHECK(previous->GetFlatTreeNodeData()); + previous->GetFlatTreeNodeData()->SetNextInAssignedNodes(current); } previous = current; } if (previous) { - previous->GetFlatTreeNodeData().SetNextInAssignedNodes(nullptr); + DCHECK(previous->GetFlatTreeNodeData()); + previous->GetFlatTreeNodeData()->SetNextInAssignedNodes(nullptr); } } @@ -237,20 +239,6 @@ DispatchScopedEvent(*event); } -Node* HTMLSlotElement::AssignedNodeNextTo(const Node& node) const { - DCHECK(SupportsAssignment()); - ContainingShadowRoot()->GetSlotAssignment().RecalcAssignment(); - DCHECK(assigned_nodes_.Contains(node)); - return node.GetFlatTreeNodeData().NextInAssignedNodes(); -} - -Node* HTMLSlotElement::AssignedNodePreviousTo(const Node& node) const { - DCHECK(SupportsAssignment()); - ContainingShadowRoot()->GetSlotAssignment().RecalcAssignment(); - DCHECK(assigned_nodes_.Contains(node)); - return node.GetFlatTreeNodeData().PreviousInAssignedNodes(); -} - AtomicString HTMLSlotElement::GetName() const { return NormalizeSlotName(FastGetAttribute(kNameAttr)); }
diff --git a/third_party/blink/renderer/core/html/html_slot_element.h b/third_party/blink/renderer/core/html/html_slot_element.h index 941c0e1..4e127e1 100644 --- a/third_party/blink/renderer/core/html/html_slot_element.h +++ b/third_party/blink/renderer/core/html/html_slot_element.h
@@ -64,9 +64,6 @@ return nodes.IsEmpty() ? nullptr : nodes.back().Get(); } - Node* AssignedNodeNextTo(const Node&) const; - Node* AssignedNodePreviousTo(const Node&) const; - void AppendAssignedNode(Node&); const HeapVector<Member<Node>> FlattenedAssignedNodes();
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc index a28078f..f89011e 100644 --- a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc +++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc
@@ -291,7 +291,7 @@ ScheduleAsyncImageBitmapDecoding(array_buffer); } -void ImageBitmapFactories::ImageBitmapLoader::DidFail(file_error::ErrorCode) { +void ImageBitmapFactories::ImageBitmapLoader::DidFail(FileErrorCode) { RejectPromise(kUndecodableImageBitmapRejectionReason); }
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h index 6b20fc6..b59e50a 100644 --- a/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h +++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h
@@ -145,7 +145,7 @@ void DidStartLoading() override {} void DidReceiveData() override {} void DidFinishLoading() override; - void DidFail(file_error::ErrorCode) override; + void DidFail(FileErrorCode) override; std::unique_ptr<FileReaderLoader> loader_; Member<ImageBitmapFactories> factory_;
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc index ebf6d32..1e67a3c 100644 --- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -186,7 +186,7 @@ void DidFinishLoading() override { Done(raw_data_); } - void DidFail(file_error::ErrorCode) override { Done(nullptr); } + void DidFail(FileErrorCode) override { Done(nullptr); } private: void Done(scoped_refptr<SharedBuffer> output) {
diff --git a/third_party/blink/renderer/core/layout/floating_objects.cc b/third_party/blink/renderer/core/layout/floating_objects.cc index 8f76ce18..f5cf1c6 100644 --- a/third_party/blink/renderer/core/layout/floating_objects.cc +++ b/third_party/blink/renderer/core/layout/floating_objects.cc
@@ -57,7 +57,8 @@ is_lowest_non_overhanging_float_in_child_(false) #if DCHECK_IS_ON() , - is_in_placed_tree_(false) + is_in_placed_tree_(false), + has_geometry_(false) #endif { } @@ -79,7 +80,8 @@ is_lowest_non_overhanging_float_in_child) #if DCHECK_IS_ON() , - is_in_placed_tree_(false) + is_in_placed_tree_(false), + has_geometry_(false) #endif { } @@ -122,6 +124,9 @@ new FloatingObject(GetLayoutObject(), GetType(), frame_rect_, should_paint_, is_descendant_, false)); clone_object->is_placed_ = is_placed_; +#if DCHECK_IS_ON() + clone_object->has_geometry_ = has_geometry_; +#endif return clone_object; } @@ -511,6 +516,7 @@ } void FloatingObjects::AddPlacedObject(FloatingObject& floating_object) { + DCHECK(!layout_object_->IsLayoutNGMixin()); DCHECK(!floating_object.IsInPlacedTree()); floating_object.SetIsPlaced(true); @@ -524,6 +530,7 @@ } void FloatingObjects::RemovePlacedObject(FloatingObject& floating_object) { + DCHECK(!layout_object_->IsLayoutNGMixin()); DCHECK(floating_object.IsPlaced()); DCHECK(floating_object.IsInPlacedTree());
diff --git a/third_party/blink/renderer/core/layout/floating_objects.h b/third_party/blink/renderer/core/layout/floating_objects.h index 12fcbf51..7820696 100644 --- a/third_party/blink/renderer/core/layout/floating_objects.h +++ b/third_party/blink/renderer/core/layout/floating_objects.h
@@ -66,22 +66,39 @@ LayoutBox* GetLayoutObject() const { return layout_object_; } bool IsPlaced() const { return is_placed_; } - void SetIsPlaced(bool placed = true) { is_placed_ = placed; } + void SetIsPlaced(bool placed = true) { + is_placed_ = placed; +#if DCHECK_IS_ON() + has_geometry_ = placed; +#endif + } + +#if DCHECK_IS_ON() + void SetHasGeometry() { has_geometry_ = true; } +#endif + + bool HasGeometry() const { +#if DCHECK_IS_ON() + return has_geometry_; +#else + return true; +#endif + } LayoutUnit X() const { - DCHECK(IsPlaced()); + DCHECK(HasGeometry()); return frame_rect_.X(); } LayoutUnit MaxX() const { - DCHECK(IsPlaced()); + DCHECK(HasGeometry()); return frame_rect_.MaxX(); } LayoutUnit Y() const { - DCHECK(IsPlaced()); + DCHECK(HasGeometry()); return frame_rect_.Y(); } LayoutUnit MaxY() const { - DCHECK(IsPlaced()); + DCHECK(HasGeometry()); return frame_rect_.MaxY(); } LayoutUnit Width() const { return frame_rect_.Width(); } @@ -105,7 +122,7 @@ } const LayoutRect& FrameRect() const { - DCHECK(IsPlaced()); + DCHECK(HasGeometry()); return frame_rect_; } @@ -149,6 +166,14 @@ unsigned is_placed_ : 1; unsigned is_lowest_non_overhanging_float_in_child_ : 1; unsigned is_in_placed_tree_ : 1; + +#if DCHECK_IS_ON() + // If set, it's safe to read out position data for this float. For LayoutNG + // this will always be true, while for legacy layout, it depends on whether + // the float IsPlaced() or not. + unsigned has_geometry_ : 1; +#endif + DISALLOW_COPY_AND_ASSIGN(FloatingObject); };
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow_line.cc b/third_party/blink/renderer/core/layout/layout_block_flow_line.cc index 0b91f1b..5b7c9a5 100644 --- a/third_party/blink/renderer/core/layout/layout_block_flow_line.cc +++ b/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
@@ -1606,9 +1606,6 @@ LayoutUnit inline_min; const ComputedStyle& style_to_use = StyleRef(); - LayoutBlock* containing_block = ContainingBlock(); - LayoutUnit cw = - containing_block ? containing_block->ContentLogicalWidth() : LayoutUnit(); // If we are at the start of a line, we want to ignore all white-space. // Also strip spaces if we previously had text that ended in a trailing space. @@ -1633,7 +1630,9 @@ // Signals the text indent was more negative than the min preferred width bool has_remaining_negative_text_indent = false; - LayoutUnit text_indent = MinimumValueForLength(style_to_use.TextIndent(), cw); + // Always resolve percentages to 0 when calculating preferred logical widths. + LayoutUnit text_indent = + MinimumValueForLength(style_to_use.TextIndent(), LayoutUnit()); LayoutObject* prev_float = nullptr; bool is_prev_child_inline_flow = false; bool should_break_line_after_text = false;
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc index ccd3383..b7bb899 100644 --- a/third_party/blink/renderer/core/layout/layout_text.cc +++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -1564,16 +1564,26 @@ String text = text_box->GetText(); return text.length() ? text.CharacterStartingAt(0) : 0; } - // TODO(kojii): Support LayoutNG once we have NGInlineItem pointers. + if (const NGPaintFragment* paint_fragment = FirstInlineFragment()) { + const StringView text = + ToNGPhysicalTextFragment(paint_fragment->PhysicalFragment()).Text(); + return text.length() ? text.CodepointAt(0) : 0; + } return 0; } UChar32 LayoutText::LastCharacterAfterWhitespaceCollapsing() const { if (InlineTextBox* text_box = LastTextBox()) { String text = text_box->GetText(); - return text.length() ? text.CharacterStartingAt(text.length() - 1) : 0; + return text.length() ? StringView(text).CodepointAt(text.length() - 1) : 0; } - // TODO(kojii): Support LayoutNG once we have NGInlineItem pointers. + if (const NGPaintFragment* paint_fragment = FirstInlineFragment()) { + const StringView text = + ToNGPhysicalTextFragment( + paint_fragment->LastForSameLayoutObject()->PhysicalFragment()) + .Text(); + return text.length() ? text.CodepointAt(text.length() - 1) : 0; + } return 0; }
diff --git a/third_party/blink/renderer/core/layout/layout_text_test.cc b/third_party/blink/renderer/core/layout/layout_text_test.cc index 48b0608..0296a5e 100644 --- a/third_party/blink/renderer/core/layout/layout_text_test.cc +++ b/third_party/blink/renderer/core/layout/layout_text_test.cc
@@ -233,9 +233,7 @@ } } -// TODO(kojii): Include LayoutNG tests by switching to -// ParameterizedLayoutTextTest when these functions support LayoutNG. -TEST_F(LayoutTextTest, CharacterAfterWhitespaceCollapsing) { +TEST_P(ParameterizedLayoutTextTest, CharacterAfterWhitespaceCollapsing) { SetBodyInnerHTML("a<span id=target> b </span>"); LayoutText* layout_text = GetLayoutTextById("target"); EXPECT_EQ(' ', layout_text->FirstCharacterAfterWhitespaceCollapsing()); @@ -272,6 +270,11 @@ DCHECK(!layout_text->HasTextBoxes()); EXPECT_EQ(0, layout_text->FirstCharacterAfterWhitespaceCollapsing()); EXPECT_EQ(0, layout_text->LastCharacterAfterWhitespaceCollapsing()); + + SetBodyInnerHTML("<b id=target>🍌_🍍</b>"); + layout_text = GetLayoutTextById("target"); + EXPECT_EQ(0x1F34C, layout_text->FirstCharacterAfterWhitespaceCollapsing()); + EXPECT_EQ(0x1F34D, layout_text->LastCharacterAfterWhitespaceCollapsing()); } TEST_P(ParameterizedLayoutTextTest, CaretMinMaxOffset) {
diff --git a/third_party/blink/renderer/core/layout/layout_theme_mac.mm b/third_party/blink/renderer/core/layout/layout_theme_mac.mm index 7507d2fc..d35622c 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_mac.mm +++ b/third_party/blink/renderer/core/layout/layout_theme_mac.mm
@@ -24,6 +24,9 @@ #import <Carbon/Carbon.h> #import <Cocoa/Cocoa.h> #import <math.h> + +#import "third_party/blink/public/platform/mac/web_sandbox_support.h" +#import "third_party/blink/public/platform/platform.h" #import "third_party/blink/renderer/core/css_value_keywords.h" #import "third_party/blink/renderer/core/fileapi/file_list.h" #import "third_party/blink/renderer/core/html_names.h" @@ -128,8 +131,13 @@ return false; } -NSColor* ColorInColorSpace(NSColor* color) { - return [color colorUsingColorSpace:[NSColorSpace sRGBColorSpace]]; +Color GetSystemColor(MacSystemColorID color_id) { + // In tests, a WebSandboxSupport may not be set up. Just return a dummy + // color, in this case, black. + auto* sandbox_support = Platform::Current()->GetSandboxSupport(); + if (!sandbox_support) + return Color(); + return sandbox_support->GetSystemColor(color_id); } } // namespace @@ -153,17 +161,11 @@ } Color LayoutThemeMac::PlatformActiveSelectionBackgroundColor() const { - NSColor* color = ColorInColorSpace([NSColor selectedTextBackgroundColor]); - return Color(static_cast<int>(255.0 * [color redComponent]), - static_cast<int>(255.0 * [color greenComponent]), - static_cast<int>(255.0 * [color blueComponent])); + return GetSystemColor(MacSystemColorID::kSelectedTextBackground); } Color LayoutThemeMac::PlatformInactiveSelectionBackgroundColor() const { - NSColor* color = ColorInColorSpace([NSColor secondarySelectedControlColor]); - return Color(static_cast<int>(255.0 * [color redComponent]), - static_cast<int>(255.0 * [color greenComponent]), - static_cast<int>(255.0 * [color blueComponent])); + return GetSystemColor(MacSystemColorID::kSecondarySelectedControl); } Color LayoutThemeMac::PlatformActiveSelectionForegroundColor() const { @@ -171,10 +173,7 @@ } Color LayoutThemeMac::PlatformActiveListBoxSelectionBackgroundColor() const { - NSColor* color = ColorInColorSpace([NSColor alternateSelectedControlColor]); - return Color(static_cast<int>(255.0 * [color redComponent]), - static_cast<int>(255.0 * [color greenComponent]), - static_cast<int>(255.0 * [color blueComponent])); + return GetSystemColor(MacSystemColorID::kAlternateSelectedControl); } Color LayoutThemeMac::PlatformActiveListBoxSelectionForegroundColor() const { @@ -263,84 +262,6 @@ font_family = font_family_names::kSystemUi; } -static RGBA32 ConvertNSColorToColor(NSColor* color) { - NSColor* color_in_color_space = ColorInColorSpace(color); - if (color_in_color_space) { - static const double kScaleFactor = nextafter(256.0, 0.0); - return MakeRGBA( - static_cast<int>(kScaleFactor * [color_in_color_space redComponent]), - static_cast<int>(kScaleFactor * [color_in_color_space greenComponent]), - static_cast<int>(kScaleFactor * [color_in_color_space blueComponent]), - static_cast<int>(kScaleFactor * [color_in_color_space alphaComponent])); - } - - // This conversion above can fail if the NSColor in question is an - // NSPatternColor (as many system colors are). These colors are actually a - // repeating pattern not just a solid color. To work around this we simply - // draw a 1x1 image of the color and use that pixel's color. It might be - // better to use an average of the colors in the pattern instead. - NSBitmapImageRep* offscreen_rep = - [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil - pixelsWide:1 - pixelsHigh:1 - bitsPerSample:8 - samplesPerPixel:4 - hasAlpha:YES - isPlanar:NO - colorSpaceName:NSDeviceRGBColorSpace - bytesPerRow:4 - bitsPerPixel:32]; - - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext - setCurrentContext:[NSGraphicsContext - graphicsContextWithBitmapImageRep:offscreen_rep]]; - NSEraseRect(NSMakeRect(0, 0, 1, 1)); - [color drawSwatchInRect:NSMakeRect(0, 0, 1, 1)]; - [NSGraphicsContext restoreGraphicsState]; - - NSUInteger pixel[4]; - [offscreen_rep getPixel:pixel atX:0 y:0]; - [offscreen_rep release]; - // This recursive call will not recurse again, because the color space - // the second time around is NSDeviceRGBColorSpace. - return ConvertNSColorToColor([NSColor colorWithDeviceRed:pixel[0] / 255. - green:pixel[1] / 255. - blue:pixel[2] / 255. - alpha:1.]); -} - -static RGBA32 MenuBackgroundColor() { - NSBitmapImageRep* offscreen_rep = - [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil - pixelsWide:1 - pixelsHigh:1 - bitsPerSample:8 - samplesPerPixel:4 - hasAlpha:YES - isPlanar:NO - colorSpaceName:NSDeviceRGBColorSpace - bytesPerRow:4 - bitsPerPixel:32]; - - CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext - graphicsContextWithBitmapImageRep:offscreen_rep] graphicsPort]); - CGRect rect = CGRectMake(0, 0, 1, 1); - HIThemeMenuDrawInfo draw_info; - draw_info.version = 0; - draw_info.menuType = kThemeMenuTypePopUp; - HIThemeDrawMenuBackground(&rect, &draw_info, context, - kHIThemeOrientationInverted); - - NSUInteger pixel[4]; - [offscreen_rep getPixel:pixel atX:0 y:0]; - [offscreen_rep release]; - return ConvertNSColorToColor([NSColor colorWithDeviceRed:pixel[0] / 255. - green:pixel[1] / 255. - blue:pixel[2] / 255. - alpha:1.]); -} - void LayoutThemeMac::PlatformColorsDidChange() { system_color_cache_.clear(); LayoutTheme::PlatformColorsDidChange(); @@ -357,50 +278,50 @@ bool needs_fallback = false; switch (css_value_id) { case CSSValueActiveborder: - color = ConvertNSColorToColor([NSColor keyboardFocusIndicatorColor]); + color = GetSystemColor(MacSystemColorID::kKeyboardFocusIndicator); break; case CSSValueActivecaption: - color = ConvertNSColorToColor([NSColor windowFrameTextColor]); + color = GetSystemColor(MacSystemColorID::kWindowFrameText); break; case CSSValueAppworkspace: - color = ConvertNSColorToColor([NSColor headerColor]); + color = GetSystemColor(MacSystemColorID::kHeader); break; case CSSValueBackground: // Use theme independent default needs_fallback = true; break; case CSSValueButtonface: - color = ConvertNSColorToColor([NSColor controlBackgroundColor]); + color = GetSystemColor(MacSystemColorID::kControlBackground); break; case CSSValueButtonhighlight: - color = ConvertNSColorToColor([NSColor controlHighlightColor]); + color = GetSystemColor(MacSystemColorID::kControlHighlight); break; case CSSValueButtonshadow: - color = ConvertNSColorToColor([NSColor controlShadowColor]); + color = GetSystemColor(MacSystemColorID::kControlShadow); break; case CSSValueButtontext: - color = ConvertNSColorToColor([NSColor controlTextColor]); + color = GetSystemColor(MacSystemColorID::kControlText); break; case CSSValueCaptiontext: - color = ConvertNSColorToColor([NSColor textColor]); + color = GetSystemColor(MacSystemColorID::kText); break; case CSSValueGraytext: - color = ConvertNSColorToColor([NSColor disabledControlTextColor]); + color = GetSystemColor(MacSystemColorID::kDisabledControlText); break; case CSSValueHighlight: - color = ConvertNSColorToColor([NSColor selectedTextBackgroundColor]); + color = GetSystemColor(MacSystemColorID::kSelectedTextBackground); break; case CSSValueHighlighttext: - color = ConvertNSColorToColor([NSColor selectedTextColor]); + color = GetSystemColor(MacSystemColorID::kSelectedText); break; case CSSValueInactiveborder: - color = ConvertNSColorToColor([NSColor controlBackgroundColor]); + color = GetSystemColor(MacSystemColorID::kControlBackground); break; case CSSValueInactivecaption: - color = ConvertNSColorToColor([NSColor controlBackgroundColor]); + color = GetSystemColor(MacSystemColorID::kControlBackground); break; case CSSValueInactivecaptiontext: - color = ConvertNSColorToColor([NSColor textColor]); + color = GetSystemColor(MacSystemColorID::kText); break; case CSSValueInfobackground: // There is no corresponding NSColor for this so we use a hard coded @@ -408,25 +329,25 @@ color = 0xFFFBFCC5; break; case CSSValueInfotext: - color = ConvertNSColorToColor([NSColor textColor]); + color = GetSystemColor(MacSystemColorID::kText); break; case CSSValueMenu: - color = MenuBackgroundColor(); + color = GetSystemColor(MacSystemColorID::kMenuBackground); break; case CSSValueMenutext: - color = ConvertNSColorToColor([NSColor selectedMenuItemTextColor]); + color = GetSystemColor(MacSystemColorID::kSelectedMenuItemText); break; case CSSValueScrollbar: - color = ConvertNSColorToColor([NSColor scrollBarColor]); + color = GetSystemColor(MacSystemColorID::kScrollBar); break; case CSSValueText: - color = ConvertNSColorToColor([NSColor textColor]); + color = GetSystemColor(MacSystemColorID::kText); break; case CSSValueThreeddarkshadow: - color = ConvertNSColorToColor([NSColor controlDarkShadowColor]); + color = GetSystemColor(MacSystemColorID::kControlDarkShadow); break; case CSSValueThreedshadow: - color = ConvertNSColorToColor([NSColor shadowColor]); + color = GetSystemColor(MacSystemColorID::kShadow); break; case CSSValueThreedface: // We use this value instead of NSColor's controlColor to avoid website @@ -435,22 +356,22 @@ color = 0xFFC0C0C0; break; case CSSValueThreedhighlight: - color = ConvertNSColorToColor([NSColor highlightColor]); + color = GetSystemColor(MacSystemColorID::kHighlight); break; case CSSValueThreedlightshadow: - color = ConvertNSColorToColor([NSColor controlLightHighlightColor]); + color = GetSystemColor(MacSystemColorID::kControlLightHighlight); break; case CSSValueWebkitFocusRingColor: - color = ConvertNSColorToColor([NSColor keyboardFocusIndicatorColor]); + color = GetSystemColor(MacSystemColorID::kKeyboardFocusIndicator); break; case CSSValueWindow: - color = ConvertNSColorToColor([NSColor windowBackgroundColor]); + color = GetSystemColor(MacSystemColorID::kWindowBackground); break; case CSSValueWindowframe: - color = ConvertNSColorToColor([NSColor windowFrameColor]); + color = GetSystemColor(MacSystemColorID::kWindowFrame); break; case CSSValueWindowtext: - color = ConvertNSColorToColor([NSColor windowFrameTextColor]); + color = GetSystemColor(MacSystemColorID::kWindowFrameText); break; default: needs_fallback = true;
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 36f862a..960648ad 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
@@ -26,25 +26,10 @@ void NGLineInfo::SetLineStyle(const NGInlineNode& node, const NGInlineItemsData& items_data, - const NGConstraintSpace& constraint_space, - bool is_first_line, - bool use_first_line_style, - bool is_after_forced_break) { + bool use_first_line_style) { use_first_line_style_ = use_first_line_style; items_data_ = &items_data; line_style_ = node.GetLayoutBox()->Style(use_first_line_style_); - - if (line_style_->ShouldUseTextIndent(is_first_line, is_after_forced_break)) { - // TODO(kojii): ComputeMinMaxSize does not know parent constraint - // space that we cannot compute percent for text-indent. - const Length& length = line_style_->TextIndent(); - LayoutUnit maximum_value; - if (length.IsPercentOrCalc()) - maximum_value = constraint_space.AvailableSize().inline_size; - text_indent_ = MinimumValueForLength(length, maximum_value); - } else { - text_indent_ = LayoutUnit(); - } } #if DCHECK_IS_ON()
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 12cacfd9..e10711c 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
@@ -15,7 +15,6 @@ namespace blink { -class NGConstraintSpace; class NGInlineItem; class NGInlineNode; @@ -132,10 +131,7 @@ } void SetLineStyle(const NGInlineNode&, const NGInlineItemsData&, - const NGConstraintSpace&, - bool is_first_formatted_line, - bool use_first_line_style, - bool is_after_forced_break); + bool use_first_line_style); // Use ::first-line style if true. // https://drafts.csswg.org/css-pseudo/#selectordef-first-line @@ -159,6 +155,7 @@ NGInlineItemResults* MutableResults() { return &results_; } const NGInlineItemResults& Results() const { return results_; } + void SetTextIndent(LayoutUnit indent) { text_indent_ = indent; } LayoutUnit TextIndent() const { return text_indent_; } NGBfcOffset BfcOffset() const { return bfc_offset_; }
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 d8125eb..a95084f 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
@@ -158,9 +158,20 @@ } line_info_->SetStartOffset(offset_); - line_info_->SetLineStyle(node_, items_data_, constraint_space_, - is_first_formatted_line_, use_first_line_style_, - previous_line_had_forced_break_); + line_info_->SetLineStyle(node_, items_data_, use_first_line_style_); + + DCHECK(!line_info_->TextIndent()); + if (line_info_->LineStyle().ShouldUseTextIndent( + is_first_formatted_line_, previous_line_had_forced_break_)) { + const Length& length = line_info_->LineStyle().TextIndent(); + LayoutUnit maximum_value; + // Ignore percentages (resolve to 0) when calculating min/max intrinsic + // sizes. + if (length.IsPercentOrCalc() && mode_ == NGLineBreakerMode::kContent) + maximum_value = constraint_space_.AvailableSize().inline_size; + line_info_->SetTextIndent(MinimumValueForLength(length, maximum_value)); + } + // Set the initial style of this line from the break token. Example: // <p>...<span>....</span></p> // When the line wraps in <span>, the 2nd line needs to start with the style @@ -316,9 +327,15 @@ DCHECK(item.TextShapeResult()); // If we're trailing, only trailing spaces can be included in this line. - if (state_ == LineBreakState::kTrailing && - CanBreakAfterLast(*item_results_)) { - return HandleTrailingSpaces(item); + if (state_ == LineBreakState::kTrailing) { + if (CanBreakAfterLast(*item_results_)) + return HandleTrailingSpaces(item); + // When a run of preserved spaces are across items, |CanBreakAfterLast| is + // false for between spaces. But we still need to handle them as trailing + // spaces. + const String& text = Text(); + if (offset_ < text.length() && text[offset_] == kSpaceCharacter) + return HandleTrailingSpaces(item); } // Skip leading collapsible spaces.
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 4e028dd..5a5b5cc 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
@@ -211,6 +211,29 @@ EXPECT_EQ("789", ToString(lines[2], node)); } +TEST_F(NGLineBreakerTest, OverflowAfterSpacesAcrossElements) { + LoadAhem(); + NGInlineNode node = CreateInlineNode(R"HTML( + <!DOCTYPE html> + <style> + div { + font: 10px/1 Ahem; + white-space: pre-wrap; + width: 10ch; + word-wrap: break-word; + } + </style> + <div id=container><span>12345 </span> 1234567890123</div> + )HTML"); + + Vector<NGInlineItemResults> lines; + lines = BreakLines(node, LayoutUnit(100)); + EXPECT_EQ(3u, lines.size()); + EXPECT_EQ("12345 ", ToString(lines[0], node)); + EXPECT_EQ("1234567890", ToString(lines[1], node)); + EXPECT_EQ("123", ToString(lines[2], node)); +} + // Tests when the last word in a node wraps, and another node continues. TEST_F(NGLineBreakerTest, WrapLastWord) { LoadAhem();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc index 8b7fc51..20dda17 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -1108,14 +1108,12 @@ ->MutableSet(); ASSERT_EQ(2UL, floating_objects.size()); auto left_floating_object = floating_objects.TakeFirst(); - ASSERT_TRUE(left_floating_object->IsPlaced()); // 80 = float_inline_offset(25) + accumulative offset of empty blocks(35 + 20) EXPECT_THAT(left_floating_object->X(), LayoutUnit(15)); // 10 = left float's margin EXPECT_THAT(left_floating_object->Y(), LayoutUnit()); auto right_floating_object = floating_objects.TakeFirst(); - ASSERT_TRUE(right_floating_object->IsPlaced()); // 150 = float_inline_offset(25) + // right float offset(125) EXPECT_THAT(right_floating_object->X(), LayoutUnit(140));
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc index c6f4292b..fa96bff 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -710,7 +710,6 @@ if (IsFloatFragment(fragment) && containing_block->IsLayoutBlockFlow()) { FloatingObject* floating_object = ToLayoutBlockFlow(containing_block)->InsertFloatingObject(*layout_box); - floating_object->SetIsInPlacedTree(false); floating_object->SetShouldPaint(!layout_box->HasSelfPaintingLayer()); LayoutUnit horizontal_margin_edge_offset = horizontal_offset; if (has_flipped_x_axis) @@ -720,8 +719,15 @@ floating_object->SetX(horizontal_margin_edge_offset); floating_object->SetY(fragment_offset.top + additional_offset.top - layout_box->MarginTop()); - floating_object->SetIsPlaced(true); - floating_object->SetIsInPlacedTree(true); +#if DCHECK_IS_ON() + // Being "placed" is a legacy thing. Make sure the flags remain unset in NG. + DCHECK(!floating_object->IsPlaced()); + DCHECK(!floating_object->IsInPlacedTree()); + + // Set this flag to tell the float machinery that it's safe to read out + // position data. + floating_object->SetHasGeometry(); +#endif } }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h index 8a7258b..71c25d0 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h +++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
@@ -564,7 +564,7 @@ bool MaySkipLayout(const RareData& other) const { return margin_strut == other.margin_strut && - bfc_offset == other.bfc_offset && + bfc_offset.line_offset == other.bfc_offset.line_offset && floats_bfc_block_offset == other.floats_bfc_block_offset && clearance_offset == other.clearance_offset && fragmentainer_block_size == other.fragmentainer_block_size &&
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc index 3bed37ca..5370cb6 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
@@ -38,6 +38,8 @@ message.stack_trace_debugger_id_second)); result.locked_agent_cluster_id = message.locked_agent_cluster_id; result.ports.AppendRange(message.ports.begin(), message.ports.end()); + result.message->GetStreamChannels().AppendRange( + message.stream_channels.begin(), message.stream_channels.end()); result.has_user_gesture = message.has_user_gesture; if (message.user_activation) { result.user_activation = mojom::blink::UserActivationSnapshot::New( @@ -66,6 +68,8 @@ message.sender_stack_trace_id.debugger_id.second; result.locked_agent_cluster_id = message.locked_agent_cluster_id; result.ports.assign(message.ports.begin(), message.ports.end()); + auto& stream_channels = message.message->GetStreamChannels(); + result.stream_channels.assign(stream_channels.begin(), stream_channels.end()); result.has_user_gesture = message.has_user_gesture; if (message.user_activation) { result.user_activation = mojom::UserActivationSnapshot::New(
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.cc index 514714c6..fe3e97c6 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.cc +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.cc
@@ -65,19 +65,24 @@ Read(blink::mojom::blink::TransferableMessage::DataView data, blink::BlinkTransferableMessage* out) { Vector<mojo::ScopedMessagePipeHandle> ports; + Vector<mojo::ScopedMessagePipeHandle> stream_channels; blink::SerializedScriptValue::ArrayBufferContentsArray array_buffer_contents_array; Vector<SkBitmap> sk_bitmaps; if (!data.ReadMessage(static_cast<blink::BlinkCloneableMessage*>(out)) || !data.ReadArrayBufferContentsArray(&array_buffer_contents_array) || !data.ReadImageBitmapContentsArray(&sk_bitmaps) || - !data.ReadPorts(&ports) || !data.ReadUserActivation(&out->user_activation)) { + !data.ReadPorts(&ports) || !data.ReadStreamChannels(&stream_channels) || + !data.ReadUserActivation(&out->user_activation)) { return false; } out->ports.ReserveInitialCapacity(ports.size()); out->ports.AppendRange(std::make_move_iterator(ports.begin()), std::make_move_iterator(ports.end())); + out->message->GetStreamChannels().AppendRange( + std::make_move_iterator(stream_channels.begin()), + std::make_move_iterator(stream_channels.end())); out->has_user_gesture = data.has_user_gesture(); out->message->SetArrayBufferContentsArray(
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h b/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h index 92e8bd8..3194e3f 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h
@@ -34,6 +34,16 @@ return result; } + static Vector<mojo::ScopedMessagePipeHandle> stream_channels( + blink::BlinkTransferableMessage& input) { + Vector<mojo::ScopedMessagePipeHandle> result; + auto& stream_channels = input.message->GetStreamChannels(); + result.ReserveInitialCapacity(stream_channels.size()); + for (const auto& port : stream_channels) + result.push_back(port.ReleaseHandle()); + return result; + } + static const blink::SerializedScriptValue::ArrayBufferContentsArray& array_buffer_contents_array(const blink::BlinkCloneableMessage& input) { return input.message->GetArrayBufferContentsArray();
diff --git a/third_party/blink/renderer/core/page/focus_controller.cc b/third_party/blink/renderer/core/page/focus_controller.cc index e6686ac..d30f345 100644 --- a/third_party/blink/renderer/core/page/focus_controller.cc +++ b/third_party/blink/renderer/core/page/focus_controller.cc
@@ -26,6 +26,8 @@ #include "third_party/blink/renderer/core/page/focus_controller.h" +#include <limits> + #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" #include "third_party/blink/renderer/core/dom/container_node.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -58,8 +60,6 @@ #include "third_party/blink/renderer/core/page/slot_scoped_traversal.h" #include "third_party/blink/renderer/core/page/spatial_navigation.h" -#include <limits> - namespace blink { namespace { @@ -843,10 +843,7 @@ } LocalFrame* FocusController::FocusedFrame() const { - // TODO(alexmos): Strengthen this to DCHECK that whoever called this really - // expected a LocalFrame. Refactor call sites so that the rare cases that - // need to know about focused RemoteFrames use a separate accessor (to be - // added). + // All callsites only care about *local* focused frames. if (focused_frame_ && focused_frame_->IsRemoteFrame()) return nullptr; return ToLocalFrame(focused_frame_.Get()); @@ -856,9 +853,10 @@ if (LocalFrame* frame = FocusedFrame()) return frame; - // FIXME: This is a temporary hack to ensure that we return a LocalFrame, even - // when the mainFrame is remote. FocusController needs to be refactored to - // deal with RemoteFrames cross-process focus transfers. + // TODO(dcheng, alexmos): https://crbug.com/820786: This is a temporary hack + // to ensure that we return a LocalFrame, even when the mainFrame is remote. + // FocusController needs to be refactored to deal with RemoteFrames + // cross-process focus transfers. for (Frame* frame = &page_->MainFrame()->Tree().Top(); frame; frame = frame->Tree().TraverseNext()) { if (frame->IsLocalFrame() && ToLocalFrame(frame)->IsLocalRoot()) @@ -868,6 +866,11 @@ return page_->MainFrame(); } +void FocusController::FrameDetached(Frame* detached_frame) { + if (detached_frame == focused_frame_) + SetFocusedFrame(nullptr); +} + HTMLFrameOwnerElement* FocusController::FocusedFrameOwnerElement( LocalFrame& current_frame) const { Frame* focused_frame = focused_frame_.Get();
diff --git a/third_party/blink/renderer/core/page/focus_controller.h b/third_party/blink/renderer/core/page/focus_controller.h index 840b3d2..ceceb13 100644 --- a/third_party/blink/renderer/core/page/focus_controller.h +++ b/third_party/blink/renderer/core/page/focus_controller.h
@@ -62,6 +62,9 @@ LocalFrame* FocusedFrame() const; Frame* FocusedOrMainFrame() const; + // Clears |focused_frame_| if it's been detached. + void FrameDetached(Frame* detached_frame); + // Finds the focused HTMLFrameOwnerElement, if any, in the provided frame. // An HTMLFrameOwnerElement is considered focused if the frame it owns, or // one of its descendant frames, is currently focused.
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc b/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc index 4c46a29..d8f78588 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc
@@ -66,10 +66,15 @@ if (graphics_layer) { if (!container_layer_state) { container_layer_state = fragment_data.LocalBorderBoxProperties(); - if (const auto* properties = fragment_data.PaintProperties()) { - // CSS clip should be applied within the layer. - if (const auto* css_clip = properties->CssClip()) - container_layer_state->SetClip(css_clip->Parent()); + // Before BlinkGenPropertyTrees, CSS clip could not be composited so + // we should avoid setting it on the layer itself. + if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() && + !RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { + if (const auto* properties = fragment_data.PaintProperties()) { + if (const auto* css_clip = properties->CssClip()) { + container_layer_state->SetClip(css_clip->Parent()); + } + } } } graphics_layer->SetLayerState(
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc index eb9131b..81a6fad3 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -39,7 +39,7 @@ public ImageResourceObserver { void* pointers[6]; NGPhysicalOffset offsets[2]; - LayoutRect rects[2]; + LayoutRect rects[1]; unsigned flags; }; @@ -302,6 +302,12 @@ return paint_fragment; } +NGPaintFragment::RareData& NGPaintFragment::EnsureRareData() { + if (!rare_data_) + rare_data_ = std::make_unique<RareData>(); + return *rare_data_; +} + void NGPaintFragment::UpdateFromCachedLayoutResult( scoped_refptr<const NGPhysicalFragment> fragment, NGPhysicalOffset offset) { @@ -329,16 +335,22 @@ NGPaintFragment* NGPaintFragment::Last(const NGBreakToken& break_token) { for (NGPaintFragment* fragment = this; fragment; - fragment = fragment->next_fragmented_.get()) { + fragment = fragment->Next()) { if (fragment->PhysicalFragment().BreakToken() == &break_token) return fragment; } return nullptr; } +NGPaintFragment* NGPaintFragment::Next() { + if (!rare_data_) + return nullptr; + return rare_data_->next_fragmented_.get(); +} + NGPaintFragment* NGPaintFragment::Last() { for (NGPaintFragment* fragment = this;;) { - NGPaintFragment* next = fragment->next_fragmented_.get(); + NGPaintFragment* next = fragment->Next(); if (!next) return fragment; fragment = next; @@ -360,7 +372,8 @@ if (!*fragment) return fragment; - scoped_refptr<NGPaintFragment>* next = &(*fragment)->next_fragmented_; + scoped_refptr<NGPaintFragment>* next = + &(*fragment)->EnsureRareData().next_fragmented_; if ((*fragment)->PhysicalFragment().BreakToken() == break_token) return next; fragment = next; @@ -369,7 +382,9 @@ } void NGPaintFragment::SetNext(scoped_refptr<NGPaintFragment> fragment) { - next_fragmented_ = std::move(fragment); + if (!rare_data_ && !fragment) + return; + EnsureRareData().next_fragmented_ = std::move(fragment); } bool NGPaintFragment::IsDescendantOfNotSelf( @@ -397,6 +412,18 @@ ToNGPhysicalBoxFragment(*physical_fragment_).ShouldClipOverflow(); } +LayoutRect NGPaintFragment::SelectionVisualRect() const { + if (!rare_data_) + return LayoutRect(); + return rare_data_->selection_visual_rect_; +} + +void NGPaintFragment::SetSelectionVisualRect(const LayoutRect& rect) { + if (!rare_data_ && rect.IsEmpty()) + return; + EnsureRareData().selection_visual_rect_ = rect; +} + LayoutRect NGPaintFragment::SelfInkOverflow() const { return physical_fragment_->InkOverflow().ToLayoutRect(); }
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h index b9ac581d..7d331af 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h +++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
@@ -58,7 +58,7 @@ NGPhysicalOffset offset); // Next/last fragment for when this is fragmented. - NGPaintFragment* Next() { return next_fragmented_.get(); } + NGPaintFragment* Next(); void SetNext(scoped_refptr<NGPaintFragment>); NGPaintFragment* Last(); NGPaintFragment* Last(const NGBreakToken&); @@ -170,10 +170,8 @@ LayoutRect VisualRect() const override { return visual_rect_; } void SetVisualRect(const LayoutRect& rect) { visual_rect_ = rect; } - LayoutRect SelectionVisualRect() const { return selection_visual_rect_; } - void SetSelectionVisualRect(const LayoutRect& rect) { - selection_visual_rect_ = rect; - } + LayoutRect SelectionVisualRect() const; + void SetSelectionVisualRect(const LayoutRect& rect); // CSS ink overflow https://www.w3.org/TR/css-overflow-3/#ink // Encloses all pixels painted by self + children. @@ -334,8 +332,18 @@ scoped_refptr<NGPaintFragment> first_child_; scoped_refptr<NGPaintFragment> next_sibling_; - // The next fragment for when this is fragmented. - scoped_refptr<NGPaintFragment> next_fragmented_; + struct RareData { + USING_FAST_MALLOC(RareData); + + public: + // The next fragment for when this is fragmented. + scoped_refptr<NGPaintFragment> next_fragmented_; + + // Used for invalidating selected fragment. + LayoutRect selection_visual_rect_; + }; + RareData& EnsureRareData(); + std::unique_ptr<RareData> rare_data_; NGPaintFragment* next_for_same_layout_object_ = nullptr; NGPhysicalOffset inline_offset_to_container_box_; @@ -351,7 +359,6 @@ // LayoutRect visual_rect_; - LayoutRect selection_visual_rect_; }; extern template class CORE_EXTERN_TEMPLATE_EXPORT
diff --git a/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc b/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc index e0f5749..db4e0af5 100644 --- a/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc +++ b/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
@@ -833,21 +833,10 @@ // Scroll target into view. GetDocument().domWindow()->scrollTo(0, 4000); UpdateAllLifecyclePhasesForTest(); - if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { - // TODO(crbug.com/792577): SPv2's cull rect for view scrolling contents is - // too small, causing this result. - EXPECT_THAT( - GetRasterInvalidationTracking()->Invalidations(), - UnorderedElementsAre(RasterInvalidationInfo{ - target->EnclosingLayer(), target->EnclosingLayer()->DebugName(), - IntRect(0, 4000, 100, 100), - PaintInvalidationReason::kChunkAppeared})); - } else { - EXPECT_THAT(GetRasterInvalidationTracking()->Invalidations(), - UnorderedElementsAre(RasterInvalidationInfo{ - target, target->DebugName(), IntRect(0, 4000, 100, 100), - PaintInvalidationReason::kForTesting})); - } + EXPECT_THAT(GetRasterInvalidationTracking()->Invalidations(), + UnorderedElementsAre(RasterInvalidationInfo{ + target, target->DebugName(), IntRect(0, 4000, 100, 100), + PaintInvalidationReason::kForTesting})); EXPECT_EQ(PaintInvalidationReason::kNone, target->FullPaintInvalidationReason()); EXPECT_FALSE(target->ShouldDelayFullPaintInvalidation());
diff --git a/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc b/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc index 9e1941e..40084431 100644 --- a/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc +++ b/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc
@@ -148,26 +148,29 @@ <div id='div4' style='top: 9000px; left: 9000px'></div> )HTML"); - auto& div1 = *GetLayoutObjectByElementId("div1"); + const auto& div1 = *GetLayoutObjectByElementId("div1"); + const auto& div2 = *GetLayoutObjectByElementId("div2"); + const auto& div3 = *GetLayoutObjectByElementId("div3"); + const auto& div4 = *GetLayoutObjectByElementId("div4"); - // TODO(crbug.com/792577): Cull rect for frame scrolling contents is too - // small? - EXPECT_THAT(RootPaintController().GetDisplayItemList(), - ElementsAre(IsSameId(&GetLayoutView(), kScrollHitTestType), - IsSameId(&ViewScrollingBackgroundClient(), - kDocumentBackgroundType), - IsSameId(&div1, kBackgroundType))); + EXPECT_THAT( + RootPaintController().GetDisplayItemList(), + ElementsAre( + IsSameId(&GetLayoutView(), kScrollHitTestType), + IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType), + IsSameId(&div1, kBackgroundType), IsSameId(&div2, kBackgroundType))); GetDocument().View()->LayoutViewport()->SetScrollOffset( ScrollOffset(5000, 5000), kProgrammaticScroll); UpdateAllLifecyclePhasesForTest(); - // TODO(crbug.com/792577): Cull rect for frame scrolling contents is too - // small? - EXPECT_THAT(RootPaintController().GetDisplayItemList(), - ElementsAre(IsSameId(&GetLayoutView(), kScrollHitTestType), - IsSameId(&ViewScrollingBackgroundClient(), - kDocumentBackgroundType))); + EXPECT_THAT( + RootPaintController().GetDisplayItemList(), + ElementsAre( + IsSameId(&GetLayoutView(), kScrollHitTestType), + IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType), + IsSameId(&div2, kBackgroundType), IsSameId(&div3, kBackgroundType), + IsSameId(&div4, kBackgroundType))); } TEST_P(PaintControllerPaintTestForSPv2, BlockScrollingNonLayeredContents) {
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter.cc b/third_party/blink/renderer/core/paint/paint_layer_painter.cc index ae5e1f261..cc11fe69 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_painter.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
@@ -204,20 +204,12 @@ ShouldRespectOverflowClipType respect_overflow_clip) { bool needs_repaint = false; - // We should set shouldResetEmptyPaintPhaseFlags if some previously unpainted - // objects may begin to be painted, causing a previously empty paint phase to - // become non-empty. - // Repaint subsequence if the layer is marked for needing repaint. - // We don't set needsResetEmptyPaintPhase here, but clear the empty paint - // phase flags in PaintLayer::setNeedsPaintPhaseXXX(), to ensure that we won't - // clear previousPaintPhaseXXXEmpty flags when unrelated things changed which - // won't cause the paint phases to become non-empty. if (paint_layer.NeedsRepaint()) needs_repaint = true; - // Repaint if previously the layer might be clipped by paintDirtyRect and - // paintDirtyRect changes. + // Repaint if previously the layer may be clipped by cull rect, and cull rect + // changes. if ((paint_layer.PreviousPaintResult() == kMayBeClippedByCullRect || // When PaintUnderInvalidationChecking is enabled, always repaint the // subsequence when the paint rect changes because we will strictly match @@ -298,11 +290,28 @@ // - The current layer's transform state escapes the root layers contents // transform, e.g. a fixed-position layer; // - Scroll offsets. - // TODO(wangxianzhu): Use CullRect::ApplyTransform() which will support - // SPv2 interest rect expansion for composited scrolling. - auto rect = painting_info.cull_rect.Rect(); - first_root_fragment.MapRectToFragment(first_fragment, rect); - painting_info.cull_rect = CullRect(rect); + if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { + auto& cull_rect = painting_info.cull_rect; + // CullRect::ApplyTransforms() requires the cull rect in the source + // transform space. Convert cull_rect from the root layer's local space. + cull_rect.MoveBy(RoundedIntPoint(first_root_fragment.PaintOffset())); + base::Optional<CullRect> old_cull_rect; + if (!paint_layer_.NeedsRepaint()) { + old_cull_rect = paint_layer_.PreviousCullRect(); + // Convert old_cull_rect into the layer's transform space. + old_cull_rect->MoveBy(RoundedIntPoint(first_fragment.PaintOffset())); + } + cull_rect.ApplyTransforms( + first_root_fragment.LocalBorderBoxProperties().Transform(), + first_fragment.LocalBorderBoxProperties().Transform(), old_cull_rect); + // Convert cull_rect from the layer's transform space to the layer's local + // space. + cull_rect.MoveBy(-RoundedIntPoint(first_fragment.PaintOffset())); + } else { + auto rect = painting_info.cull_rect.Rect(); + first_root_fragment.MapRectToFragment(first_fragment, rect); + painting_info.cull_rect = CullRect(rect); + } } // Make the current layer the new root layer.
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter.h b/third_party/blink/renderer/core/paint/paint_layer_painter.h index 4c39e00..0b667ea 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_painter.h +++ b/third_party/blink/renderer/core/paint/paint_layer_painter.h
@@ -60,6 +60,7 @@ private: friend class PaintLayerPainterTest; + friend class PaintLayerPainterTestSPv2; PaintResult PaintChildren(unsigned children_to_visit, GraphicsContext&,
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc b/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc index ed306c2..c217d017 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc
@@ -212,8 +212,8 @@ DisplayItemClient& content3 = *GetDisplayItemClientFromElementId("content3"); GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(); - IntRect interest_rect(0, 0, 400, 300); - Paint(&interest_rect); + IntRect cull_rect(0, 0, 400, 300); + Paint(&cull_rect); const auto& background_display_item_client = ViewScrollingBackgroundClient(); @@ -232,8 +232,8 @@ IsSameId(&content3, kBackgroundType))); GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(); - IntRect new_interest_rect(0, 100, 300, 1000); - EXPECT_TRUE(PaintWithoutCommit(&new_interest_rect)); + IntRect new_cull_rect(0, 100, 300, 1000); + EXPECT_TRUE(PaintWithoutCommit(&new_cull_rect)); // Container1 becomes partly in the interest rect, but uses cached subsequence // because it was fully painted before; @@ -269,14 +269,14 @@ // |target| will be fully painted. GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(); - IntRect interest_rect(0, 0, 400, 300); - Paint(&interest_rect); + IntRect cull_rect(0, 0, 400, 300); + Paint(&cull_rect); // |target| will be partially painted. Should not trigger under-invalidation // checking DCHECKs. GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(); - IntRect new_interest_rect(0, 100, 300, 1000); - Paint(&new_interest_rect); + IntRect new_cull_rect(0, 100, 300, 1000); + Paint(&new_cull_rect); } TEST_P(PaintLayerPainterTest, @@ -295,8 +295,8 @@ )HTML"); GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(); // PaintResult of all subsequences will be MayBeClippedByCullRect. - IntRect interest_rect(0, 0, 50, 300); - Paint(&interest_rect); + IntRect cull_rect(0, 0, 50, 300); + Paint(&cull_rect); DisplayItemClient& container1 = *GetDisplayItemClientFromElementId("container1"); @@ -319,7 +319,7 @@ "position: absolute; width: 100px; height: 100px; " "background-color: green"); GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(); - EXPECT_TRUE(PaintWithoutCommit(&interest_rect)); + EXPECT_TRUE(PaintWithoutCommit(&cull_rect)); EXPECT_EQ(4, NumCachedNewItems()); CommitAndFinishCycle();
diff --git a/third_party/blink/renderer/core/paint/view_painter_test.cc b/third_party/blink/renderer/core/paint/view_painter_test.cc index 057ea4e9..6f4a2b5 100644 --- a/third_party/blink/renderer/core/paint/view_painter_test.cc +++ b/third_party/blink/renderer/core/paint/view_painter_test.cc
@@ -23,11 +23,6 @@ void ViewPainterTest::RunFixedBackgroundTest( bool prefer_compositing_to_lcd_text) { - // TODO(crbug.com/792577): Cull rect for frame scrolling contents is too - // small. - if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) - return; - if (prefer_compositing_to_lcd_text) { Settings* settings = GetDocument().GetFrame()->GetSettings(); settings->SetPreferCompositingToLCDTextEnabled(true); @@ -52,40 +47,71 @@ layout_viewport->SetScrollOffset(scroll_offset, kUserScroll); frame_view->UpdateAllLifecyclePhases(); - CompositedLayerMapping* clm = - GetLayoutView().Layer()->GetCompositedLayerMapping(); - - // If we prefer compositing to LCD text, the fixed background should go in a - // different layer from the scrolling content; otherwise, it should go in the - // same layer (i.e., the scrolling contents layer). - GraphicsLayer* layer_for_background; - if (prefer_compositing_to_lcd_text) { - layer_for_background = clm->MainGraphicsLayer(); + const DisplayItem* background_display_item = nullptr; + if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { + const auto& display_items = RootPaintController().GetDisplayItemList(); + if (prefer_compositing_to_lcd_text) { + EXPECT_THAT( + display_items, + ElementsAre(IsSameId(&GetLayoutView(), kDocumentBackgroundType), + IsSameId(&GetLayoutView(), DisplayItem::kScrollHitTest), + IsSameId(GetDocument().body()->GetLayoutObject(), + kBackgroundType))); + background_display_item = &display_items[0]; + } else { + EXPECT_THAT( + display_items, + ElementsAre(IsSameId(&GetLayoutView(), DisplayItem::kScrollHitTest), + IsSameId(&ViewScrollingBackgroundClient(), + kDocumentBackgroundType), + IsSameId(GetDocument().body()->GetLayoutObject(), + kBackgroundType))); + background_display_item = &display_items[1]; + } } else { - layer_for_background = clm->ScrollingContentsLayer(); + // If we prefer compositing to LCD text, the fixed background should go in a + // different layer from the scrolling content; otherwise, it should go in + // the same layer (i.e., the scrolling contents layer). + if (prefer_compositing_to_lcd_text) { + const auto& display_items = GetLayoutView() + .Layer() + ->GraphicsLayerBacking(&GetLayoutView()) + ->GetPaintController() + .GetDisplayItemList(); + EXPECT_THAT( + display_items, + ElementsAre(IsSameId(&GetLayoutView(), kDocumentBackgroundType))); + background_display_item = &display_items[0]; + } else { + const auto& display_items = RootPaintController().GetDisplayItemList(); + EXPECT_THAT(display_items, + ElementsAre(IsSameId(&ViewScrollingBackgroundClient(), + kDocumentBackgroundType), + IsSameId(GetDocument().body()->GetLayoutObject(), + kBackgroundType))); + background_display_item = &display_items[0]; + } } - const DisplayItemList& display_items = - layer_for_background->GetPaintController().GetDisplayItemList(); - const DisplayItem& background = display_items[0]; - EXPECT_EQ(background.GetType(), kDocumentBackgroundType); - const DisplayItemClient* expected_client; - if (!prefer_compositing_to_lcd_text) - expected_client = &ViewScrollingBackgroundClient(); - else - expected_client = &GetLayoutView(); - EXPECT_EQ(&background.Client(), expected_client); sk_sp<const PaintRecord> record = - static_cast<const DrawingDisplayItem&>(background).GetPaintRecord(); + static_cast<const DrawingDisplayItem*>(background_display_item) + ->GetPaintRecord(); ASSERT_EQ(record->size(), 2u); cc::PaintOpBuffer::Iterator it(record.get()); ASSERT_EQ((*++it)->GetType(), cc::PaintOpType::DrawRect); - // This is the dest_rect_ calculated by BackgroundImageGeometry. For a fixed + // This is the dest_rect_ calculated by BackgroundImageGeometry. For a fixed // background in scrolling contents layer, its location is the scroll offset. SkRect rect = static_cast<const cc::DrawRectOp*>(*it)->rect; - ASSERT_EQ(prefer_compositing_to_lcd_text ? ScrollOffset() : scroll_offset, - ScrollOffset(rect.fLeft, rect.fTop)); + if (prefer_compositing_to_lcd_text) { + EXPECT_EQ(SkRect::MakeXYWH(0, 0, 800, 600), rect); + } else if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { + EXPECT_EQ(SkRect::MakeXYWH(0, 0, 800, 600), rect); + } else { + EXPECT_EQ(SkRect::MakeXYWH(scroll_offset.Width(), scroll_offset.Height(), + 800, 600), + rect); + } } TEST_P(ViewPainterTest, DocumentFixedBackgroundLowDPI) { @@ -97,27 +123,41 @@ } TEST_P(ViewPainterTest, DocumentBackgroundWithScroll) { - // TODO(crbug.com/792577): Cull rect for frame scrolling contents is too - // small. - if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) - return; + SetBodyInnerHTML(R"HTML( + <style>::-webkit-scrollbar { display: none }</style> + <div style='height: 5000px'></div> + )HTML"); - SetBodyInnerHTML("<div style='height: 5000px'></div>"); - - EXPECT_THAT(RootPaintController().GetDisplayItemList(), - ElementsAre(IsSameId(&ViewScrollingBackgroundClient(), - kDocumentBackgroundType))); - - const auto& chunks = RootPaintController().PaintChunks(); - EXPECT_EQ(1u, chunks.size()); - const auto& chunk = chunks[0]; - EXPECT_EQ(&ViewScrollingBackgroundClient(), &chunk.id.client); - - const auto& tree_state = chunk.properties; - EXPECT_EQ(&EffectPaintPropertyNode::Root(), tree_state.Effect()); - const auto* properties = GetLayoutView().FirstFragment().PaintProperties(); - EXPECT_EQ(properties->ScrollTranslation(), tree_state.Transform()); - EXPECT_EQ(properties->OverflowClip(), tree_state.Clip()); + if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { + EXPECT_THAT( + RootPaintController().GetDisplayItemList(), + ElementsAre(IsSameId(&GetLayoutView(), DisplayItem::kScrollHitTest), + IsSameId(&ViewScrollingBackgroundClient(), + kDocumentBackgroundType))); + EXPECT_THAT( + RootPaintController().PaintChunks(), + ElementsAre( + IsPaintChunk( + 0, 1, + PaintChunk::Id(*GetLayoutView().Layer(), + DisplayItem::kLayerChunkBackground), + GetLayoutView().FirstFragment().LocalBorderBoxProperties()), + IsPaintChunk( + 1, 2, + PaintChunk::Id(ViewScrollingBackgroundClient(), + kDocumentBackgroundType), + GetLayoutView().FirstFragment().ContentsProperties()))); + } else { + EXPECT_THAT(RootPaintController().GetDisplayItemList(), + ElementsAre(IsSameId(&ViewScrollingBackgroundClient(), + kDocumentBackgroundType))); + EXPECT_THAT(RootPaintController().PaintChunks(), + ElementsAre(IsPaintChunk( + 0, 1, + PaintChunk::Id(ViewScrollingBackgroundClient(), + kDocumentBackgroundType), + GetLayoutView().FirstFragment().ContentsProperties()))); + } } class ViewPainterTestWithPaintTouchAction
diff --git a/third_party/blink/renderer/core/streams/readable_stream.cc b/third_party/blink/renderer/core/streams/readable_stream.cc index 1a3d3c31..0ba774c 100644 --- a/third_party/blink/renderer/core/streams/readable_stream.cc +++ b/third_party/blink/renderer/core/streams/readable_stream.cc
@@ -459,6 +459,10 @@ ReadableStream* ReadableStream::Deserialize(ScriptState* script_state, MessagePort* port, ExceptionState& exception_state) { + // We need to execute V8 Extras JavaScript to create the new ReadableStream. + // We will not run author code. + v8::Isolate::AllowJavascriptExecutionScope allow_js( + script_state->GetIsolate()); ScriptValue internal_stream = ReadableStreamOperations::Deserialize( script_state, port, exception_state); if (exception_state.HadException())
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc index ea9f7e8d..b3217bf 100644 --- a/third_party/blink/renderer/core/style/computed_style.cc +++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -407,10 +407,6 @@ return InheritedEqual(o) && NonInheritedEqual(o); } -bool ComputedStyle::IsStyleAvailable() const { - return this != StyleResolver::StyleNotYetAvailable(); -} - const ComputedStyle* ComputedStyle::GetCachedPseudoStyle(PseudoId pid) const { if (!cached_pseudo_styles_ || !cached_pseudo_styles_->size()) return nullptr;
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index fdb526a..e4fb15c9 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -89,7 +89,7 @@ typedef Vector<scoped_refptr<ComputedStyle>, 4> PseudoStyleCache; -namespace CSSLonghand { +namespace css_longhand { class BackgroundColor; class BorderBottomColor; @@ -111,7 +111,7 @@ class WebkitTextFillColor; class WebkitTextStrokeColor; -} // namespace CSSLonghand +} // namespace css_longhand // ComputedStyle stores the computed value [1] for every CSS property on an // element and provides the interface between the style engine and the rest of @@ -183,25 +183,25 @@ // Accesses GetColor(). friend class ComputedStyleUtils; // These get visited and unvisited colors separately. - friend class CSSLonghand::BackgroundColor; - friend class CSSLonghand::BorderBottomColor; - friend class CSSLonghand::BorderLeftColor; - friend class CSSLonghand::BorderRightColor; - friend class CSSLonghand::BorderTopColor; - friend class CSSLonghand::CaretColor; - friend class CSSLonghand::Color; - friend class CSSLonghand::ColumnRuleColor; - friend class CSSLonghand::FloodColor; - friend class CSSLonghand::Fill; - friend class CSSLonghand::LightingColor; - friend class CSSLonghand::OutlineColor; - friend class CSSLonghand::StopColor; - friend class CSSLonghand::Stroke; - friend class CSSLonghand::TextDecorationColor; - friend class CSSLonghand::WebkitTapHighlightColor; - friend class CSSLonghand::WebkitTextEmphasisColor; - friend class CSSLonghand::WebkitTextFillColor; - friend class CSSLonghand::WebkitTextStrokeColor; + friend class css_longhand::BackgroundColor; + friend class css_longhand::BorderBottomColor; + friend class css_longhand::BorderLeftColor; + friend class css_longhand::BorderRightColor; + friend class css_longhand::BorderTopColor; + friend class css_longhand::CaretColor; + friend class css_longhand::Color; + friend class css_longhand::ColumnRuleColor; + friend class css_longhand::FloodColor; + friend class css_longhand::Fill; + friend class css_longhand::LightingColor; + friend class css_longhand::OutlineColor; + friend class css_longhand::StopColor; + friend class css_longhand::Stroke; + friend class css_longhand::TextDecorationColor; + friend class css_longhand::WebkitTapHighlightColor; + friend class css_longhand::WebkitTextEmphasisColor; + friend class css_longhand::WebkitTextFillColor; + friend class css_longhand::WebkitTextStrokeColor; // Editing has to only reveal unvisited info. friend class ApplyStyleCommand; // Editing has to only reveal unvisited info. @@ -2246,8 +2246,6 @@ bool HasAppearance() const { return Appearance() != kNoControlPart; } // Other utility functions. - bool IsStyleAvailable() const; - bool RequireTransformOrigin(ApplyTransformOrigin apply_origin, ApplyMotionPath) const;
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc index 10b9095..bb4bad2 100644 --- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc +++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -239,9 +239,7 @@ xhr_->DidReceiveData(data, length); } void DidFinishLoading() override { xhr_->DidFinishLoadingFromBlob(); } - void DidFail(file_error::ErrorCode error) override { - xhr_->DidFailLoadingFromBlob(); - } + void DidFail(FileErrorCode error) override { xhr_->DidFailLoadingFromBlob(); } void Cancel() { loader_->Cancel(); }
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index 43e9b66..925e8cf 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -318,6 +318,7 @@ "peerconnection/adapters/p2p_quic_stream_unittest.cc", "peerconnection/adapters/p2p_quic_transport_test.cc", "peerconnection/byte_buffer_queue_test.cc", + "peerconnection/call_setup_state_tracker_unittest.cc", "peerconnection/rtc_data_channel_test.cc", "peerconnection/rtc_ice_transport_test.cc", "peerconnection/rtc_ice_transport_test.h",
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index 8cc5373..b87b9543 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -2709,7 +2709,9 @@ if (IsHTMLSelectElement(GetNode())) { HTMLSelectElement* select = ToHTMLSelectElement(GetNode()); for (auto* const option : *select->selectedOptions()) { - options.push_back(AXObjectCache().GetOrCreate(option)); + AXObject* ax_option = AXObjectCache().GetOrCreate(option); + if (ax_option) + options.push_back(ax_option); } return; }
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 a711d4b..740d509 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
@@ -395,7 +395,7 @@ dispose(); } - void DidFail(file_error::ErrorCode error) override { + void DidFail(FileErrorCode error) override { callback_->sendFailure(ProtocolResponse::Error(String::Format( "Unable to read the cached response, error code: %d", error))); dispose();
diff --git a/third_party/blink/renderer/modules/filesystem/file_writer.cc b/third_party/blink/renderer/modules/filesystem/file_writer.cc index 7121263..63f35972 100644 --- a/third_party/blink/renderer/modules/filesystem/file_writer.cc +++ b/third_party/blink/renderer/modules/filesystem/file_writer.cc
@@ -84,11 +84,11 @@ DCHECK(data); DCHECK_EQ(truncate_length_, -1); if (ready_state_ == kWriting) { - SetError(file_error::ErrorCode::kInvalidStateErr, exception_state); + SetError(FileErrorCode::kInvalidStateErr, exception_state); return; } if (recursion_depth_ > kMaxRecursionDepth) { - SetError(file_error::ErrorCode::kSecurityErr, exception_state); + SetError(FileErrorCode::kSecurityErr, exception_state); return; } @@ -112,7 +112,7 @@ if (!GetExecutionContext()) return; if (ready_state_ == kWriting) { - SetError(file_error::ErrorCode::kInvalidStateErr, exception_state); + SetError(FileErrorCode::kInvalidStateErr, exception_state); return; } @@ -126,11 +126,11 @@ return; DCHECK_EQ(truncate_length_, -1); if (ready_state_ == kWriting || position < 0) { - SetError(file_error::ErrorCode::kInvalidStateErr, exception_state); + SetError(FileErrorCode::kInvalidStateErr, exception_state); return; } if (recursion_depth_ > kMaxRecursionDepth) { - SetError(file_error::ErrorCode::kSecurityErr, exception_state); + SetError(FileErrorCode::kSecurityErr, exception_state); return; } @@ -318,9 +318,9 @@ DCHECK_GE(recursion_depth_, 0); } -void FileWriter::SetError(file_error::ErrorCode error_code, +void FileWriter::SetError(FileErrorCode error_code, ExceptionState& exception_state) { - DCHECK_NE(error_code, file_error::ErrorCode::kOK); + DCHECK_NE(error_code, FileErrorCode::kOK); file_error::ThrowDOMException(exception_state, error_code); error_ = file_error::CreateDOMException(error_code); }
diff --git a/third_party/blink/renderer/modules/filesystem/file_writer.h b/third_party/blink/renderer/modules/filesystem/file_writer.h index d767211..08bb31cd 100644 --- a/third_party/blink/renderer/modules/filesystem/file_writer.h +++ b/third_party/blink/renderer/modules/filesystem/file_writer.h
@@ -40,14 +40,11 @@ namespace blink { -namespace file_error { -enum class ErrorCode; -} - class Blob; class DOMException; class ExceptionState; class ExecutionContext; +enum class FileErrorCode; class FileWriter final : public EventTargetWithInlineData, public FileWriterBase, @@ -119,7 +116,7 @@ void FireEvent(const AtomicString& type); - void SetError(file_error::ErrorCode, ExceptionState&); + void SetError(FileErrorCode, ExceptionState&); void Dispose();
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc b/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc index 7a35429..fc21d82 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc
@@ -106,7 +106,7 @@ StartNextValue(); } -void IDBRequestLoader::DidFail(file_error::ErrorCode) { +void IDBRequestLoader::DidFail(FileErrorCode) { #if DCHECK_IS_ON() DCHECK(started_) << "FileReaderLoader called DidFail() before it was Start()ed";
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request_loader.h b/third_party/blink/renderer/modules/indexeddb/idb_request_loader.h index 6b26321..a6d5dd98 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request_loader.h +++ b/third_party/blink/renderer/modules/indexeddb/idb_request_loader.h
@@ -52,7 +52,7 @@ void DidStartLoading() override; void DidReceiveDataForClient(const char* data, unsigned data_length) override; void DidFinishLoading() override; - void DidFail(file_error::ErrorCode) override; + void DidFail(FileErrorCode) override; private: // Starts unwrapping the next wrapped IDBValue.
diff --git a/third_party/blink/renderer/modules/peerconnection/BUILD.gn b/third_party/blink/renderer/modules/peerconnection/BUILD.gn index e8d54e9..ff6e6b92 100644 --- a/third_party/blink/renderer/modules/peerconnection/BUILD.gn +++ b/third_party/blink/renderer/modules/peerconnection/BUILD.gn
@@ -36,6 +36,8 @@ "adapters/web_rtc_cross_thread_copier.h", "byte_buffer_queue.cc", "byte_buffer_queue.h", + "call_setup_state_tracker.cc", + "call_setup_state_tracker.h", "rtc_certificate.cc", "rtc_certificate.h", "rtc_data_channel.cc",
diff --git a/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.cc b/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.cc new file mode 100644 index 0000000..bf4b8ec --- /dev/null +++ b/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.cc
@@ -0,0 +1,98 @@ +// Copyright (c) 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h" + +namespace blink { + +CallSetupStateTracker::CallSetupStateTracker() + : valid_offerer_transitions_( + {std::make_pair(OffererState::kNotStarted, + OffererState::kCreateOfferPending), + // createOffer() + std::make_pair(OffererState::kCreateOfferPending, + OffererState::kCreateOfferRejected), + std::make_pair(OffererState::kCreateOfferPending, + OffererState::kCreateOfferResolved), + std::make_pair(OffererState::kCreateOfferRejected, + OffererState::kCreateOfferResolved), + std::make_pair(OffererState::kCreateOfferResolved, + OffererState::kSetLocalOfferPending), + // setLocalDescription(offer) + std::make_pair(OffererState::kSetLocalOfferPending, + OffererState::kSetLocalOfferRejected), + std::make_pair(OffererState::kSetLocalOfferPending, + OffererState::kSetLocalOfferResolved), + std::make_pair(OffererState::kSetLocalOfferRejected, + OffererState::kSetLocalOfferResolved), + std::make_pair(OffererState::kSetLocalOfferResolved, + OffererState::kSetRemoteAnswerPending), + // setRemoteDescription(answer) + std::make_pair(OffererState::kSetRemoteAnswerPending, + OffererState::kSetRemoteAnswerRejected), + std::make_pair(OffererState::kSetRemoteAnswerPending, + OffererState::kSetRemoteAnswerResolved), + std::make_pair(OffererState::kSetRemoteAnswerRejected, + OffererState::kSetRemoteAnswerResolved)}), + valid_answerer_transitions_({ + std::make_pair(AnswererState::kNotStarted, + AnswererState::kSetRemoteOfferPending), + // setRemoteDescription(answer) + std::make_pair(AnswererState::kSetRemoteOfferPending, + AnswererState::kSetRemoteOfferRejected), + std::make_pair(AnswererState::kSetRemoteOfferPending, + AnswererState::kSetRemoteOfferResolved), + std::make_pair(AnswererState::kSetRemoteOfferRejected, + AnswererState::kSetRemoteOfferResolved), + std::make_pair(AnswererState::kSetRemoteOfferResolved, + AnswererState::kCreateAnswerPending), + // createAnswer() + std::make_pair(AnswererState::kCreateAnswerPending, + AnswererState::kCreateAnswerRejected), + std::make_pair(AnswererState::kCreateAnswerPending, + AnswererState::kCreateAnswerResolved), + std::make_pair(AnswererState::kCreateAnswerRejected, + AnswererState::kCreateAnswerResolved), + std::make_pair(AnswererState::kCreateAnswerResolved, + AnswererState::kSetLocalAnswerPending), + // setLocalDescription(answer) + std::make_pair(AnswererState::kSetLocalAnswerPending, + AnswererState::kSetLocalAnswerRejected), + std::make_pair(AnswererState::kSetLocalAnswerPending, + AnswererState::kSetLocalAnswerResolved), + std::make_pair(AnswererState::kSetLocalAnswerRejected, + AnswererState::kSetLocalAnswerResolved), + }), + offerer_state_(OffererState::kNotStarted), + answerer_state_(AnswererState::kNotStarted) {} + +OffererState CallSetupStateTracker::offerer_state() const { + return offerer_state_; +} + +AnswererState CallSetupStateTracker::answerer_state() const { + return answerer_state_; +} + +bool CallSetupStateTracker::NoteOffererStateEvent(OffererState event) { + auto transition = std::make_pair(offerer_state_, event); + if (valid_offerer_transitions_.find(transition) == + valid_offerer_transitions_.end()) { + return false; + } + offerer_state_ = event; + return true; +} + +bool CallSetupStateTracker::NoteAnswererStateEvent(AnswererState event) { + auto transition = std::make_pair(answerer_state_, event); + if (valid_answerer_transitions_.find(transition) == + valid_answerer_transitions_.end()) { + return false; + } + answerer_state_ = event; + return true; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h b/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h new file mode 100644 index 0000000..883126a --- /dev/null +++ b/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h
@@ -0,0 +1,89 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_CALL_SETUP_STATE_TRACKER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_CALL_SETUP_STATE_TRACKER_H_ + +#include <set> +#include <utility> + +#include "third_party/blink/renderer/modules/modules_export.h" + +namespace blink { + +// Represents the different states that an offerer can go through during call +// setup, where later steps involve SDP exchange. +// +// Valid transitions are from an operation's "pending" to "resolved" or +// "rejected" state. "Rejected" can transition to "resolved" if another attempt +// is made (without going to "pending" in-between). Only "resolved" can +// transition to the next operation's "pending" state. Transition between +// operations are only valid in the defined order. +// +// The model we are using is one that measures how close we get to establishing +// a connection. In reality, the peer connection may make multiple tries, and +// follow multiple paths towards reaching a connected state, but we're only +// interested in seeing how far it got on its most successful attempt. +enum class OffererState { + kNotStarted = 0, + // createOffer() + kCreateOfferPending = 1, + kCreateOfferRejected = 2, + kCreateOfferResolved = 3, + // setLocalDescription(offer) + kSetLocalOfferPending = 4, + kSetLocalOfferRejected = 5, + kSetLocalOfferResolved = 6, + // setRemoteDescription(answer) + kSetRemoteAnswerPending = 7, + kSetRemoteAnswerRejected = 8, + kSetRemoteAnswerResolved = 9, + + kMaxValue = kSetRemoteAnswerResolved, +}; + +// Represents the different states that an answerer can go through during call +// setup, where initial steps involve SDP exchange. The transition graph for +// this enum follows the same logic as OffererState, see above. +enum class AnswererState { + kNotStarted = 0, + // setRemoteDescription(offer) + kSetRemoteOfferPending = 1, + kSetRemoteOfferRejected = 2, + kSetRemoteOfferResolved = 3, + // createAnswer() + kCreateAnswerPending = 4, + kCreateAnswerRejected = 5, + kCreateAnswerResolved = 6, + // setLocalDescription(answer) + kSetLocalAnswerPending = 7, + kSetLocalAnswerRejected = 8, + kSetLocalAnswerResolved = 9, + + kMaxValue = kSetLocalAnswerResolved, +}; + +class MODULES_EXPORT CallSetupStateTracker { + public: + CallSetupStateTracker(); + + OffererState offerer_state() const; + AnswererState answerer_state() const; + + bool NoteOffererStateEvent(OffererState event); + bool NoteAnswererStateEvent(AnswererState event); + + private: + const std::set<std::pair<OffererState, OffererState>> + valid_offerer_transitions_; + const std::set<std::pair<AnswererState, AnswererState>> + valid_answerer_transitions_; + + OffererState offerer_state_; + AnswererState answerer_state_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_CALL_SETUP_STATE_TRACKER_H_
diff --git a/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker_unittest.cc b/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker_unittest.cc new file mode 100644 index 0000000..693a622 --- /dev/null +++ b/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker_unittest.cc
@@ -0,0 +1,290 @@ +// Copyright (c) 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +namespace { + +template <typename StateType> +std::vector<StateType> GetAllCallSetupStates(); + +template <> +std::vector<OffererState> GetAllCallSetupStates() { + std::vector<OffererState> states = {OffererState::kNotStarted, + OffererState::kCreateOfferPending, + OffererState::kCreateOfferRejected, + OffererState::kCreateOfferResolved, + OffererState::kSetLocalOfferPending, + OffererState::kSetLocalOfferRejected, + OffererState::kSetLocalOfferResolved, + OffererState::kSetRemoteAnswerPending, + OffererState::kSetRemoteAnswerRejected, + OffererState::kSetRemoteAnswerResolved}; + EXPECT_EQ(static_cast<size_t>(OffererState::kMaxValue) + 1u, states.size()); + return states; +} + +template <> +std::vector<AnswererState> GetAllCallSetupStates() { + std::vector<AnswererState> states = {AnswererState::kNotStarted, + AnswererState::kSetRemoteOfferPending, + AnswererState::kSetRemoteOfferRejected, + AnswererState::kSetRemoteOfferResolved, + AnswererState::kCreateAnswerPending, + AnswererState::kCreateAnswerRejected, + AnswererState::kCreateAnswerResolved, + AnswererState::kSetLocalAnswerPending, + AnswererState::kSetLocalAnswerRejected, + AnswererState::kSetLocalAnswerResolved}; + EXPECT_EQ(static_cast<size_t>(AnswererState::kMaxValue) + 1u, states.size()); + return states; +} + +} // namespace + +class CallSetupStateTrackerTest : public testing::Test { + public: + enum class Reachability { + kReachable, + kUnreachable, + }; + + template <typename StateType> + StateType current_state() const; + + template <> + OffererState current_state() const { + return tracker_.offerer_state(); + } + + template <> + AnswererState current_state() const { + return tracker_.answerer_state(); + } + + template <typename StateType> + bool NoteStateEvent(CallSetupStateTracker* tracker, StateType event) const; + + template <> + bool NoteStateEvent(CallSetupStateTracker* tracker, + OffererState event) const { + return tracker->NoteOffererStateEvent(event); + } + + template <> + bool NoteStateEvent(CallSetupStateTracker* tracker, + AnswererState event) const { + return tracker->NoteAnswererStateEvent(event); + } + + template <typename StateType> + bool VerifyReachability(Reachability reachability, + std::vector<StateType> states) const { + bool expected_state_reached = (reachability == Reachability::kReachable); + for (const auto& state : states) { + bool did_reach_state; + if (state == current_state<StateType>()) { + // The current state always counts as reachable. + did_reach_state = true; + } else { + // Perform the test on a copy to avoid mutating |tracker_|. + CallSetupStateTracker tracker_copy = tracker_; + did_reach_state = NoteStateEvent<StateType>(&tracker_copy, state); + } + if (did_reach_state != expected_state_reached) + return false; + } + return true; + } + + template <typename StateType> + bool VerifyOnlyReachableStates(std::vector<StateType> reachable_states, + bool include_current = true) const { + if (include_current) + reachable_states.push_back(current_state<StateType>()); + std::vector<StateType> unreachable_states = + GetAllCallSetupStates<StateType>(); + for (const auto& reachable_state : reachable_states) { + unreachable_states.erase(std::find(unreachable_states.begin(), + unreachable_states.end(), + reachable_state)); + } + return VerifyReachability<StateType>(Reachability::kReachable, + reachable_states) && + VerifyReachability<StateType>(Reachability::kUnreachable, + unreachable_states); + } + + protected: + CallSetupStateTracker tracker_; +}; + +TEST_F(CallSetupStateTrackerTest, InitialState) { + EXPECT_EQ(OffererState::kNotStarted, tracker_.offerer_state()); + EXPECT_EQ(AnswererState::kNotStarted, tracker_.answerer_state()); +} + +TEST_F(CallSetupStateTrackerTest, OffererSuccessfulNegotiation) { + EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>( + {OffererState::kCreateOfferPending})); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kCreateOfferPending)); + EXPECT_EQ(OffererState::kCreateOfferPending, tracker_.offerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>( + {OffererState::kCreateOfferResolved, + OffererState::kCreateOfferRejected})); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kCreateOfferResolved)); + EXPECT_EQ(OffererState::kCreateOfferResolved, tracker_.offerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>( + {OffererState::kSetLocalOfferPending})); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetLocalOfferPending)); + EXPECT_EQ(OffererState::kSetLocalOfferPending, tracker_.offerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>( + {OffererState::kSetLocalOfferResolved, + OffererState::kSetLocalOfferRejected})); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetLocalOfferResolved)); + EXPECT_EQ(OffererState::kSetLocalOfferResolved, tracker_.offerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>( + {OffererState::kSetRemoteAnswerPending})); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetRemoteAnswerPending)); + EXPECT_EQ(OffererState::kSetRemoteAnswerPending, tracker_.offerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>( + {OffererState::kSetRemoteAnswerResolved, + OffererState::kSetRemoteAnswerRejected})); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetRemoteAnswerResolved)); + EXPECT_EQ(OffererState::kSetRemoteAnswerResolved, tracker_.offerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>({})); +} + +TEST_F(CallSetupStateTrackerTest, OffererCreateOfferRejected) { + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kCreateOfferPending)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kCreateOfferRejected)); + EXPECT_EQ(OffererState::kCreateOfferRejected, tracker_.offerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>( + {OffererState::kCreateOfferResolved})); +} + +TEST_F(CallSetupStateTrackerTest, OffererSetLocalOfferRejected) { + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kCreateOfferPending)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kCreateOfferResolved)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetLocalOfferPending)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetLocalOfferRejected)); + EXPECT_EQ(OffererState::kSetLocalOfferRejected, tracker_.offerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>( + {OffererState::kSetLocalOfferResolved})); +} + +TEST_F(CallSetupStateTrackerTest, OffererSetRemoteAnswerRejected) { + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kCreateOfferPending)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kCreateOfferResolved)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetLocalOfferPending)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetLocalOfferResolved)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetRemoteAnswerPending)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetRemoteAnswerRejected)); + EXPECT_EQ(OffererState::kSetRemoteAnswerRejected, tracker_.offerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>( + {OffererState::kSetRemoteAnswerResolved})); +} + +TEST_F(CallSetupStateTrackerTest, AnswererSuccessfulNegotiation) { + EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( + {AnswererState::kSetRemoteOfferPending})); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferPending)); + EXPECT_EQ(AnswererState::kSetRemoteOfferPending, tracker_.answerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( + {AnswererState::kSetRemoteOfferResolved, + AnswererState::kSetRemoteOfferRejected})); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferResolved)); + EXPECT_EQ(AnswererState::kSetRemoteOfferResolved, tracker_.answerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( + {AnswererState::kCreateAnswerPending})); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kCreateAnswerPending)); + EXPECT_EQ(AnswererState::kCreateAnswerPending, tracker_.answerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( + {AnswererState::kCreateAnswerResolved, + AnswererState::kCreateAnswerRejected})); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kCreateAnswerResolved)); + EXPECT_EQ(AnswererState::kCreateAnswerResolved, tracker_.answerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( + {AnswererState::kSetLocalAnswerPending})); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetLocalAnswerPending)); + EXPECT_EQ(AnswererState::kSetLocalAnswerPending, tracker_.answerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( + {AnswererState::kSetLocalAnswerResolved, + AnswererState::kSetLocalAnswerRejected})); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetLocalAnswerResolved)); + EXPECT_EQ(AnswererState::kSetLocalAnswerResolved, tracker_.answerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>({})); +} + +TEST_F(CallSetupStateTrackerTest, AnswererSetRemoteOfferRejected) { + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferPending)); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferRejected)); + EXPECT_EQ(AnswererState::kSetRemoteOfferRejected, tracker_.answerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( + {AnswererState::kSetRemoteOfferResolved})); +} + +TEST_F(CallSetupStateTrackerTest, AnswererCreateAnswerRejected) { + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferPending)); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferResolved)); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kCreateAnswerPending)); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kCreateAnswerRejected)); + EXPECT_EQ(AnswererState::kCreateAnswerRejected, tracker_.answerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( + {AnswererState::kCreateAnswerResolved})); +} + +TEST_F(CallSetupStateTrackerTest, AnswererSetLocalAnswerRejected) { + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferPending)); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferResolved)); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kCreateAnswerPending)); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kCreateAnswerResolved)); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetLocalAnswerPending)); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetLocalAnswerRejected)); + EXPECT_EQ(AnswererState::kSetLocalAnswerRejected, tracker_.answerer_state()); + EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( + {AnswererState::kSetLocalAnswerResolved})); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/presentation/presentation_connection.cc b/third_party/blink/renderer/modules/presentation/presentation_connection.cc index 3cfcbd3..5f1044f 100644 --- a/third_party/blink/renderer/modules/presentation/presentation_connection.cc +++ b/third_party/blink/renderer/modules/presentation/presentation_connection.cc
@@ -137,7 +137,7 @@ presentation_connection_->DidFinishLoadingBlob( loader_->ArrayBufferResult()); } - void DidFail(file_error::ErrorCode error_code) override { + void DidFail(FileErrorCode error_code) override { presentation_connection_->DidFailLoadingBlob(error_code); } @@ -609,8 +609,7 @@ HandleMessageQueue(); } -void PresentationConnection::DidFailLoadingBlob( - file_error::ErrorCode error_code) { +void PresentationConnection::DidFailLoadingBlob(FileErrorCode error_code) { DCHECK(!messages_.IsEmpty()); DCHECK_EQ(messages_.front()->type, kMessageTypeBlob); // FIXME: generate error message?
diff --git a/third_party/blink/renderer/modules/presentation/presentation_connection.h b/third_party/blink/renderer/modules/presentation/presentation_connection.h index 1161c4e..9ac31e4 100644 --- a/third_party/blink/renderer/modules/presentation/presentation_connection.h +++ b/third_party/blink/renderer/modules/presentation/presentation_connection.h
@@ -22,12 +22,9 @@ namespace blink { -namespace file_error { -enum class ErrorCode; -} - class DOMArrayBuffer; class DOMArrayBufferView; +enum class FileErrorCode; class PresentationController; class PresentationReceiver; class PresentationRequest; @@ -134,7 +131,7 @@ // Callbacks invoked from BlobLoader. void DidFinishLoadingBlob(DOMArrayBuffer*); - void DidFailLoadingBlob(file_error::ErrorCode); + void DidFailLoadingBlob(FileErrorCode); void SendMessageToTargetConnection( mojom::blink::PresentationConnectionMessagePtr);
diff --git a/third_party/blink/renderer/modules/webdatabase/database_authorizer.cc b/third_party/blink/renderer/modules/webdatabase/database_authorizer.cc index c1a4560c..49a3eb2 100644 --- a/third_party/blink/renderer/modules/webdatabase/database_authorizer.cc +++ b/third_party/blink/renderer/modules/webdatabase/database_authorizer.cc
@@ -319,14 +319,6 @@ return security_enabled_ ? kSQLAuthDeny : kSQLAuthAllow; } -int DatabaseAuthorizer::AllowAttach(const String&) { - return security_enabled_ ? kSQLAuthDeny : kSQLAuthAllow; -} - -int DatabaseAuthorizer::AllowDetach(const String&) { - return security_enabled_ ? kSQLAuthDeny : kSQLAuthAllow; -} - int DatabaseAuthorizer::AllowFunction(const String& function_name) { if (security_enabled_ && !WhitelistedFunctions().Contains(function_name)) return kSQLAuthDeny;
diff --git a/third_party/blink/renderer/modules/webdatabase/database_authorizer.h b/third_party/blink/renderer/modules/webdatabase/database_authorizer.h index bd79fef..4461190 100644 --- a/third_party/blink/renderer/modules/webdatabase/database_authorizer.h +++ b/third_party/blink/renderer/modules/webdatabase/database_authorizer.h
@@ -89,9 +89,6 @@ int AllowFunction(const String& function_name); int AllowPragma(const String& pragma_name, const String& first_argument); - int AllowAttach(const String& filename); - int AllowDetach(const String& database_name); - void Disable(); void Enable(); void SetPermissions(int permissions);
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc index 277ae05f..ae8ea19 100644 --- a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc +++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc
@@ -47,9 +47,6 @@ : db_(nullptr), page_size_(-1), transaction_in_progress_(false), -#if DCHECK_IS_ON() - sharable_(false), -#endif opening_thread_(0), open_error_(SQLITE_ERROR), open_error_message_(), @@ -314,14 +311,13 @@ case SQLITE_UPDATE: return auth->AllowUpdate(parameter1, parameter2); case SQLITE_ATTACH: - return auth->AllowAttach(parameter1); + return kSQLAuthDeny; case SQLITE_DETACH: - return auth->AllowDetach(parameter1); + return kSQLAuthDeny; case SQLITE_ALTER_TABLE: return auth->AllowAlterTable(parameter1, parameter2); case SQLITE_REINDEX: return auth->AllowReindex(parameter1); -#if SQLITE_VERSION_NUMBER >= 3003013 case SQLITE_ANALYZE: return auth->AllowAnalyze(parameter1); case SQLITE_CREATE_VTABLE: @@ -330,11 +326,13 @@ return auth->DropVTable(parameter1, parameter2); case SQLITE_FUNCTION: return auth->AllowFunction(parameter2); -#endif - default: - NOTREACHED(); + case SQLITE_SAVEPOINT: + return kSQLAuthDeny; + case SQLITE_RECURSIVE: return kSQLAuthDeny; } + NOTREACHED(); + return kSQLAuthDeny; } void SQLiteDatabase::SetAuthorizer(DatabaseAuthorizer* auth) {
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h index 1671740..6d109ed 100644 --- a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h +++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h
@@ -35,10 +35,6 @@ #include "third_party/blink/renderer/platform/wtf/threading.h" #include "third_party/blink/renderer/platform/wtf/threading_primitives.h" -#if defined(COMPILER_MSVC) -#pragma warning(disable : 4800) -#endif - struct sqlite3; namespace blink { @@ -97,7 +93,7 @@ sqlite3* Sqlite3Handle() const { #if DCHECK_IS_ON() - DCHECK_EQ(sharable_ || CurrentThread(), opening_thread_ || !db_); + DCHECK_EQ(!!CurrentThread(), opening_thread_ || !db_); #endif return db_; } @@ -140,9 +136,6 @@ int page_size_; bool transaction_in_progress_; -#if DCHECK_IS_ON() - bool sharable_; -#endif Mutex authorizer_lock_; CrossThreadPersistent<DatabaseAuthorizer> authorizer_;
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc index 987281c..ed1d1ab 100644 --- a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc +++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc
@@ -62,9 +62,10 @@ << "InitializeSQLite() must be called before " << __func__; #endif // DCHECK_IS_ON() - return sqlite3_open_v2(filename.Utf8().data(), database, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, - "chromium_vfs"); + return sqlite3_open_v2( + filename.Utf8().data(), database, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_PRIVATECACHE, + "chromium_vfs"); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc index 5b443d1..fac805a9 100644 --- a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc +++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc
@@ -254,24 +254,21 @@ // SQLite is typed per value. optional column types are // "(mostly) ignored" - sqlite3_value* value = sqlite3_column_value(statement_, col); - switch (sqlite3_value_type(value)) { + switch (sqlite3_column_type(statement_, col)) { case SQLITE_INTEGER: // SQLValue and JS don't represent integers, so use // FLOAT -case case SQLITE_FLOAT: - return SQLValue(sqlite3_value_double(value)); + return SQLValue(sqlite3_column_double(statement_, col)); case SQLITE_BLOB: // SQLValue and JS don't represent blobs, so use TEXT // -case case SQLITE_TEXT: { - const UChar* string = - reinterpret_cast<const UChar*>(sqlite3_value_text16(value)); - unsigned length = sqlite3_value_bytes16(value) / sizeof(UChar); + const UChar* string = reinterpret_cast<const UChar*>( + sqlite3_column_text16(statement_, col)); + unsigned length = sqlite3_column_bytes16(statement_, col) / sizeof(UChar); return SQLValue(StringImpl::Create8BitIfPossible(string, length)); } case SQLITE_NULL: return SQLValue(); - default: - break; } NOTREACHED(); return SQLValue();
diff --git a/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.cc b/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.cc index 874aa27..444834b 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.cc
@@ -11,6 +11,8 @@ WebGLCompressedTextureETC::WebGLCompressedTextureETC( WebGLRenderingContextBase* context) : WebGLExtension(context) { + context->ExtensionsUtil()->EnsureExtensionEnabled( + "GL_CHROMIUM_compressed_texture_etc"); context->AddCompressedTextureFormat(GL_COMPRESSED_R11_EAC); context->AddCompressedTextureFormat(GL_COMPRESSED_SIGNED_R11_EAC); context->AddCompressedTextureFormat(GL_COMPRESSED_RGB8_ETC2);
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc index 389079e..33d9ace79 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
@@ -89,7 +89,7 @@ void DidStartLoading() override {} void DidReceiveData() override {} void DidFinishLoading() override; - void DidFail(file_error::ErrorCode) override; + void DidFail(FileErrorCode) override; void Trace(blink::Visitor* visitor) { visitor->Trace(channel_); } @@ -140,8 +140,7 @@ loader_ = nullptr; } -void WebSocketChannelImpl::BlobLoader::DidFail( - file_error::ErrorCode error_code) { +void WebSocketChannelImpl::BlobLoader::DidFail(FileErrorCode error_code) { channel_->DidFailLoadingBlob(error_code); loader_ = nullptr; } @@ -767,10 +766,9 @@ ProcessSendQueue(); } -void WebSocketChannelImpl::DidFailLoadingBlob( - file_error::ErrorCode error_code) { +void WebSocketChannelImpl::DidFailLoadingBlob(FileErrorCode error_code) { blob_loader_.Clear(); - if (error_code == file_error::ErrorCode::kAbortErr) { + if (error_code == FileErrorCode::kAbortErr) { // The error is caused by cancel(). return; }
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h index a732bc15..40eadb1 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h
@@ -54,11 +54,8 @@ namespace blink { -namespace file_error { -enum class ErrorCode; -} - class BaseFetchContext; +enum class FileErrorCode; class WebSocketChannelClient; class WebSocketHandshakeThrottle; @@ -180,7 +177,7 @@ // Methods for BlobLoader. void DidFinishLoadingBlob(DOMArrayBuffer*); - void DidFailLoadingBlob(file_error::ErrorCode); + void DidFailLoadingBlob(FileErrorCode); void TearDownFailedConnection(); bool ShouldDisallowConnection(const KURL&);
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index cdfcde71..ec33c84 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1460,6 +1460,8 @@ "//third_party/blink/public/common", "//third_party/ced", "//third_party/icu", + "//third_party/webrtc/p2p:rtc_p2p", + "//third_party/webrtc_overrides:init_webrtc", "//third_party/zlib/google:compression_utils", "//ui/base:base", "//ui/gfx",
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 0a9dd3b..f2e7148 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -116,6 +116,10 @@ RuntimeEnabledFeatures::SetIsolatedCodeCacheEnabled(enable); } +void WebRuntimeFeatures::EnableWasmCodeCache(bool enable) { + RuntimeEnabledFeatures::SetWasmCodeCacheEnabled(enable); +} + void WebRuntimeFeatures::EnableCanvas2dImageChromium(bool enable) { RuntimeEnabledFeatures::SetCanvas2dImageChromiumEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/fonts/script_run_iterator.cc b/third_party/blink/renderer/platform/fonts/script_run_iterator.cc index 86da0df..012238f 100644 --- a/third_party/blink/renderer/platform/fonts/script_run_iterator.cc +++ b/third_party/blink/renderer/platform/fonts/script_run_iterator.cc
@@ -10,6 +10,26 @@ namespace blink { +namespace { + +// UScriptCode and OpenType script are not 1:1; specifically, both Hiragana and +// Katakana map to 'kana' in OpenType. They will be mapped correctly in +// HarfBuzz, but normalizing earlier helps to reduce splitting runs between +// these scripts. +// https://docs.microsoft.com/en-us/typography/opentype/spec/scripttags +inline UScriptCode getScriptForOpenType(UChar32 ch, UErrorCode* status) { + UScriptCode script = uscript_getScript(ch, status); + if (UNLIKELY(U_FAILURE(*status))) + return script; + if (UNLIKELY(script == USCRIPT_KATAKANA || + script == USCRIPT_KATAKANA_OR_HIRAGANA)) { + return USCRIPT_HIRAGANA; + } + return script; +} + +} // namespace + typedef ScriptData::PairedBracketType PairedBracketType; constexpr int ScriptRunIterator::kMaxScriptCount; @@ -27,6 +47,10 @@ // regardless of the capacity passed to the call. So count can be greater // than dst->size(), if a later version of the unicode data has more // than kMaxScriptCount items. + + // |uscript_getScriptExtensions| do not need to be collated to + // USCRIPT_HIRAGANA because when ScriptExtensions contains Kana, it contains + // Hira as well, and Hira is always before Kana. int count = uscript_getScriptExtensions(ch, &dst[0], dst.size(), &status); if (status == U_BUFFER_OVERFLOW_ERROR) { // Allow this, we'll just use what we have. @@ -35,7 +59,7 @@ count = dst.size(); status = U_ZERO_ERROR; } - UScriptCode primary_script = uscript_getScript(ch, &status); + UScriptCode primary_script = getScriptForOpenType(ch, &status); if (U_FAILURE(status)) { DLOG(ERROR) << "Could not get icu script data: " << status << " for 0x"
diff --git a/third_party/blink/renderer/platform/fonts/script_run_iterator_test.cc b/third_party/blink/renderer/platform/fonts/script_run_iterator_test.cc index 3e2a7a0..a792bdf 100644 --- a/third_party/blink/renderer/platform/fonts/script_run_iterator_test.cc +++ b/third_party/blink/renderer/platform/fonts/script_run_iterator_test.cc
@@ -370,6 +370,50 @@ CHECK_SCRIPT_RUNS({{"萬國碼", USCRIPT_HAN}}); } +struct JapaneseMixedScript { + const char* string; + // The expected primary_script when the string alone was evaluated. + UScriptCode script; +} japanese_mixed_scripts[] = {{"あ", USCRIPT_HIRAGANA}, + // Katakana should be normalized to Hiragana + {"ア", USCRIPT_HIRAGANA}, + // Script_Extensions=Hira Kana + {"\u30FC", USCRIPT_HIRAGANA}, + // Script_Extensions=Hani Hira Kana + {"\u303C", USCRIPT_HAN}, + // Script_Extensions=Bopo Hang Hani Hira Kana + {"\u3003", USCRIPT_BOPOMOFO}, + // Script_Extensions=Bopo Hang Hani Hira Kana Yiii + {"\u3001", USCRIPT_BOPOMOFO}}; + +class JapaneseMixedScriptTest + : public ScriptRunIteratorTest, + public testing::WithParamInterface<JapaneseMixedScript> {}; + +INSTANTIATE_TEST_CASE_P(ScriptRunIteratorTest, + JapaneseMixedScriptTest, + testing::ValuesIn(japanese_mixed_scripts)); + +TEST_P(JapaneseMixedScriptTest, Data) { + const auto& data = GetParam(); + std::string string(data.string); + + CheckRuns({{string.data(), data.script}}); + + // If the string follows Hiragana or Katakana, or is followed by Hiragnaa or + // Katakana, it should be normalized as Hiragana. + std::string hiragana("か"); + std::string katakana("カ"); + CheckRuns({{(hiragana + string).data(), USCRIPT_HIRAGANA}}); + CheckRuns({{(string + hiragana).data(), USCRIPT_HIRAGANA}}); + + CheckRuns({{(katakana + string).data(), USCRIPT_HIRAGANA}}); + CheckRuns({{(string + katakana).data(), USCRIPT_HIRAGANA}}); + + CheckRuns({{(hiragana + string + katakana).data(), USCRIPT_HIRAGANA}}); + CheckRuns({{(katakana + string + hiragana).data(), USCRIPT_HIRAGANA}}); +} + // Close bracket without matching open is ignored TEST_F(ScriptRunIteratorTest, UnbalancedParens1) { CHECK_SCRIPT_RUNS(
diff --git a/third_party/blink/renderer/platform/graphics/OWNERS b/third_party/blink/renderer/platform/graphics/OWNERS index aef11af..78c0ada 100644 --- a/third_party/blink/renderer/platform/graphics/OWNERS +++ b/third_party/blink/renderer/platform/graphics/OWNERS
@@ -11,6 +11,9 @@ senorblanco@chromium.org vollick@chromium.org +# For surface ID propagation and synchronization +samans@chromium.org + # lowLatency canvas mcasas@chromium.org
diff --git a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc index f09986c..b4e0e82 100644 --- a/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc +++ b/third_party/blink/renderer/platform/graphics/paint/cull_rect.cc
@@ -6,6 +6,7 @@ #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" +#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h" #include "third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h" #include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" @@ -44,25 +45,90 @@ rect_.Move(offset); } -void CullRect::ApplyTransform(const TransformPaintPropertyNode* transform) { +CullRect::ApplyTransformResult CullRect::ApplyTransformInternal( + const TransformPaintPropertyNode* transform) { if (IsInfinite()) - return; + return kNotExpanded; if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { if (const auto* scroll = transform->ScrollNode()) { rect_.Intersect(scroll->ContainerRect()); + if (rect_.IsEmpty()) + return kNotExpanded; rect_ = transform->Matrix().Inverse().MapRect(rect_); - // Expand the cull rect for scrolling contents in case of - // composited scrolling. - // TODO(wangxianzhu): Implement more sophisticated interst rect expansion. + // Expand the cull rect for scrolling contents in case of composited + // scrolling. + // TODO(wangxianzhu): the expansion distance needs to be scaled to + // screen pixels. + // TODO(wangxianzhu): options for non-composited-scrolling contents: + // 1. to use non-composted-scrolling heuristics to avoid expansion; + // 2. to reduce the 4000px distance, no matter if the contents with be + // composited scrolling. + // 3. mixed method of 1 and 2, e.g. the distance could be a function of + // confidence that the contents will be composited scrolling. static const int kPixelDistanceToExpand = 4000; rect_.Inflate(kPixelDistanceToExpand); - return; + // Don't clip the cull rect by contents size to let ChangedEnough() work + // even if the new cull rect exceeds the bounds of contents rect. + return rect_.Contains(IntRect(IntPoint(), scroll->ContentsSize())) + ? kExpandedForWholeScrollingContents + : kExpandedForPartialScrollingContents; } } rect_ = transform->Matrix().Inverse().MapRect(rect_); + return kNotExpanded; +} + +void CullRect::ApplyTransforms(const TransformPaintPropertyNode* from, + const TransformPaintPropertyNode* to, + const base::Optional<CullRect>& old_cull_rect) { + DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled()); + + Vector<const TransformPaintPropertyNode*> scroll_translations; + for (const auto* t = to; t != from; t = t->Parent()) { + if (!t) { + // |from| is not an ancestor of |to|. Simply map. + GeometryMapper::SourceToDestinationRect(from, to, rect_); + return; + } + if (t->ScrollNode()) + scroll_translations.push_back(t); + } + + const auto* last_transform = from; + ApplyTransformResult last_scroll_translation_result = kNotExpanded; + for (auto it = scroll_translations.rbegin(); it != scroll_translations.rend(); + ++it) { + const auto* scroll_translation = *it; + GeometryMapper::SourceToDestinationRect( + last_transform, scroll_translation->Parent(), rect_); + last_scroll_translation_result = ApplyTransformInternal(scroll_translation); + last_transform = scroll_translation; + } + GeometryMapper::SourceToDestinationRect(last_transform, to, rect_); + + if (last_scroll_translation_result == kExpandedForPartialScrollingContents && + old_cull_rect && !ChangedEnough(*old_cull_rect)) + rect_ = old_cull_rect->Rect(); +} + +bool CullRect::ChangedEnough(const CullRect& old_cull_rect) const { + DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled()); + + const auto& new_rect = Rect(); + const auto& old_rect = old_cull_rect.Rect(); + if (old_rect == new_rect || (old_rect.IsEmpty() && new_rect.IsEmpty())) + return false; + + if (old_rect.IsEmpty()) + return true; + + auto expanded_old_rect = old_rect; + static const int kChangedEnoughMinimumDistance = 512; + expanded_old_rect.Inflate(kChangedEnoughMinimumDistance); + return !expanded_old_rect.Contains(new_rect); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/paint/cull_rect.h b/third_party/blink/renderer/platform/graphics/paint/cull_rect.h index be806a5..73ef85d 100644 --- a/third_party/blink/renderer/platform/graphics/paint/cull_rect.h +++ b/third_party/blink/renderer/platform/graphics/paint/cull_rect.h
@@ -39,13 +39,54 @@ void MoveBy(const IntPoint& offset); void Move(const IntSize& offset); - void ApplyTransform(const TransformPaintPropertyNode*); + + // Applies one transform to the cull rect. Before this function is called, + // the cull rect is in the space of the parent the transform node. + // For SlimmingPaintV2, when the transform is a scroll translation, the cull + // rect is converted in the following steps: + // 1. it's clipped by the container rect, + // 2. transformed by inverse of the scroll translation, + // 3. expanded by thousands of pixels for composited scrolling. + void ApplyTransform(const TransformPaintPropertyNode* transform) { + ApplyTransformInternal(transform); + } + + // For SlimmingPaintV2 only. Applies transforms from |source| (not included) + // to |destination| (included). For each scroll translation, the cull rect is + // converted as described in ApplyTransform(). If |old_cull_rect| is provided, + // and the cull rect converted by the last scroll translation doesn't cover + // the whole scrolling contents, and the new cull rect doesn't change enough + // (by hundreds of pixels) from |old_cull_rect|, the cull rect will be set to + // |old_cull_rect| to avoid repaint on each composited scroll. + void ApplyTransforms(const TransformPaintPropertyNode* source, + const TransformPaintPropertyNode* destination, + const base::Optional<CullRect>& old_cull_rect); const IntRect& Rect() const { return rect_; } String ToString() const { return rect_.ToString(); } private: + friend class CullRectTest; + + enum ApplyTransformResult { + // The cull rect is transformed into the target transform space (by mapping + // the cull rect with the inverse of the transform) without expansion. + // In SlimmingPaintV1, the functions always return this value. + kNotExpanded, + // The cull rect is converted by a scroll translation (in the steps + // described in ApplyTransform(), and the result covers the whole scrolling + // contents. + kExpandedForWholeScrollingContents, + // The cull rect is converted by a scroll translation, and the result + // doesn't cover the whole scrolling contents. + kExpandedForPartialScrollingContents, + }; + ApplyTransformResult ApplyTransformInternal( + const TransformPaintPropertyNode*); + + bool ChangedEnough(const CullRect& old_cull_rect) const; + IntRect rect_; };
diff --git a/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc b/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc index 12d6cc27..b77244c87 100644 --- a/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc +++ b/third_party/blink/renderer/platform/graphics/paint/cull_rect_test.cc
@@ -13,7 +13,24 @@ namespace blink { -using CullRectTest = testing::Test; +class CullRectTest : public testing::Test { + protected: + const CullRect::ApplyTransformResult kNotExpanded = CullRect::kNotExpanded; + const CullRect::ApplyTransformResult kExpandedForPartialScrollingContents = + CullRect::kExpandedForPartialScrollingContents; + const CullRect::ApplyTransformResult kExpandedForWholeScrollingContents = + CullRect::kExpandedForWholeScrollingContents; + + CullRect::ApplyTransformResult ApplyTransform( + CullRect& cull_rect, + const TransformPaintPropertyNode* t) { + return cull_rect.ApplyTransformInternal(t); + } + + bool ChangedEnough(const IntRect& old_rect, const IntRect& new_rect) { + return CullRect(new_rect).ChangedEnough(CullRect(old_rect)); + } +}; TEST_F(CullRectTest, IntersectsIntRect) { CullRect cull_rect(IntRect(0, 0, 50, 50)); @@ -44,27 +61,296 @@ CullRect cull_rect(IntRect(1, 1, 50, 50)); auto transform = CreateTransform(t0(), TransformationMatrix().Translate(1, 1)); - cull_rect.ApplyTransform(transform.get()); + EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, transform.get())); EXPECT_EQ(IntRect(0, 0, 50, 50), cull_rect.Rect()); } -TEST_F(CullRectTest, ApplyScrollTranslation) { +TEST_F(CullRectTest, ApplyScrollTranslationPartialScrollingContents) { ScopedSlimmingPaintV2ForTest spv2(true); ScrollPaintPropertyNode::State scroll_state; scroll_state.container_rect = IntRect(20, 10, 40, 50); + scroll_state.contents_size = IntSize(8000, 8000); auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(), std::move(scroll_state)); - auto scroll_translation = CreateScrollTranslation(t0(), 10, 15, *scroll); + auto scroll_translation = + CreateScrollTranslation(t0(), -3000, -5000, *scroll); CullRect cull_rect(IntRect(0, 0, 50, 100)); - cull_rect.ApplyTransform(scroll_translation.get()); + EXPECT_EQ(kExpandedForPartialScrollingContents, + ApplyTransform(cull_rect, scroll_translation.get())); // Clipped: (20, 10, 30, 50) - // Inverse transformed: (10, -5, 30, 50) - // Expanded: (-3990, -4005, 8030, 8050) - EXPECT_EQ(IntRect(-3990, -4005, 8030, 8050), cull_rect.Rect()); + // Inverse transformed: (3020, 5010, 30, 50) + // Expanded: (-980, 1010, 8030, 8050) + EXPECT_EQ(IntRect(-980, 1010, 8030, 8050), cull_rect.Rect()); +} + +TEST_F(CullRectTest, ApplyScrollTranslationNoIntersectionWithContainerRect) { + ScopedSlimmingPaintV2ForTest spv2(true); + + ScrollPaintPropertyNode::State scroll_state; + scroll_state.container_rect = IntRect(200, 100, 40, 50); + scroll_state.contents_size = IntSize(2000, 2000); + auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(), + std::move(scroll_state)); + auto scroll_translation = CreateScrollTranslation(t0(), -10, -15, *scroll); + + CullRect cull_rect(IntRect(0, 0, 50, 100)); + EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, scroll_translation.get())); + EXPECT_TRUE(cull_rect.Rect().IsEmpty()); +} + +TEST_F(CullRectTest, ApplyScrollTranslationWholeScrollingContents) { + ScopedSlimmingPaintV2ForTest spv2(true); + + ScrollPaintPropertyNode::State scroll_state; + scroll_state.container_rect = IntRect(20, 10, 40, 50); + scroll_state.contents_size = IntSize(2000, 2000); + auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(), + std::move(scroll_state)); + auto scroll_translation = CreateScrollTranslation(t0(), -10, -15, *scroll); + + CullRect cull_rect(IntRect(0, 0, 50, 100)); + EXPECT_EQ(kExpandedForWholeScrollingContents, + ApplyTransform(cull_rect, scroll_translation.get())); + + // Clipped: (20, 10, 30, 50) + // Inverse transformed: (30, 25, 30, 50) + // Expanded: (-3970, -3975, 8030, 8050) + EXPECT_EQ(IntRect(-3970, -3975, 8030, 8050), cull_rect.Rect()); +} + +TEST_F(CullRectTest, ChangedEnoughEmpty) { + ScopedSlimmingPaintV2ForTest spv2(true); + EXPECT_FALSE(ChangedEnough(IntRect(), IntRect())); + EXPECT_FALSE(ChangedEnough(IntRect(1, 1, 0, 0), IntRect(2, 2, 0, 0))); + EXPECT_TRUE(ChangedEnough(IntRect(), IntRect(0, 0, 1, 1))); + EXPECT_FALSE(ChangedEnough(IntRect(0, 0, 1, 1), IntRect())); +} + +TEST_F(CullRectTest, ChangedNotEnough) { + ScopedSlimmingPaintV2ForTest spv2(true); + IntRect old_rect(100, 100, 100, 100); + EXPECT_FALSE(ChangedEnough(old_rect, old_rect)); + EXPECT_FALSE(ChangedEnough(old_rect, IntRect(100, 100, 90, 90))); + EXPECT_FALSE(ChangedEnough(old_rect, IntRect(100, 100, 100, 100))); + EXPECT_FALSE(ChangedEnough(old_rect, IntRect(1, 1, 200, 200))); +} + +TEST_F(CullRectTest, ChangedEnoughScrollScenarios) { + ScopedSlimmingPaintV2ForTest spv2(true); + IntRect old_rect(100, 100, 100, 100); + IntRect new_rect(old_rect); + new_rect.Move(500, 0); + EXPECT_FALSE(ChangedEnough(old_rect, new_rect)); + new_rect.Move(0, 500); + EXPECT_FALSE(ChangedEnough(old_rect, new_rect)); + new_rect.Move(50, 0); + EXPECT_TRUE(ChangedEnough(old_rect, new_rect)); + new_rect.Move(-50, 50); + EXPECT_TRUE(ChangedEnough(old_rect, new_rect)); +} + +TEST_F(CullRectTest, ApplyTransformsSameTransform) { + ScopedSlimmingPaintV2ForTest spv2(true); + auto transform = + CreateTransform(t0(), TransformationMatrix().Translate(1, 2)); + CullRect cull_rect1(IntRect(1, 1, 50, 50)); + cull_rect1.ApplyTransforms(transform.get(), transform.get(), base::nullopt); + EXPECT_EQ(IntRect(1, 1, 50, 50), cull_rect1.Rect()); + + CullRect old_cull_rect = cull_rect1; + old_cull_rect.Move(IntSize(1, 1)); + CullRect cull_rect2(IntRect(1, 1, 50, 50)); + // Should ignore old_cull_rect. + cull_rect2.ApplyTransforms(transform.get(), transform.get(), old_cull_rect); + EXPECT_EQ(cull_rect1, cull_rect2); +} + +TEST_F(CullRectTest, ApplyTransformsWithoutScroll) { + ScopedSlimmingPaintV2ForTest spv2(true); + auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2)); + auto t2 = CreateTransform(*t1, TransformationMatrix().Translate(10, 20)); + + CullRect cull_rect1(IntRect(1, 1, 50, 50)); + cull_rect1.ApplyTransforms(t1.get(), t2.get(), base::nullopt); + EXPECT_EQ(IntRect(-9, -19, 50, 50), cull_rect1.Rect()); + + CullRect cull_rect2(IntRect(1, 1, 50, 50)); + cull_rect2.ApplyTransforms(&t0(), t2.get(), base::nullopt); + EXPECT_EQ(IntRect(-10, -21, 50, 50), cull_rect2.Rect()); + + CullRect old_cull_rect = cull_rect2; + old_cull_rect.Move(IntSize(1, 1)); + CullRect cull_rect3(IntRect(1, 1, 50, 50)); + // Should ignore old_cull_rect. + cull_rect3.ApplyTransforms(&t0(), t2.get(), old_cull_rect); + EXPECT_EQ(cull_rect2, cull_rect3); +} + +TEST_F(CullRectTest, ApplyTransformsSingleScrollWholeScrollingContents) { + ScopedSlimmingPaintV2ForTest spv2(true); + auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2)); + + ScrollPaintPropertyNode::State scroll_state; + scroll_state.container_rect = IntRect(20, 10, 40, 50); + scroll_state.contents_size = IntSize(2000, 2000); + auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(), + std::move(scroll_state)); + auto scroll_translation = CreateScrollTranslation(*t1, -10, -15, *scroll); + + // Same as ApplyScrollTranslationWholeScrollingContents. + CullRect cull_rect1(IntRect(0, 0, 50, 100)); + cull_rect1.ApplyTransforms(t1.get(), scroll_translation.get(), base::nullopt); + EXPECT_EQ(IntRect(-3970, -3975, 8030, 8050), cull_rect1.Rect()); + + CullRect old_cull_rect = cull_rect1; + old_cull_rect.Move(IntSize(1, 1)); + CullRect cull_rect2(IntRect(0, 0, 50, 100)); + // Should ignore old_cull_rect. + cull_rect2.ApplyTransforms(t1.get(), scroll_translation.get(), old_cull_rect); + EXPECT_EQ(cull_rect1, cull_rect2); +} + +TEST_F(CullRectTest, ApplyTransformsSingleScrollPartialScrollingContents) { + ScopedSlimmingPaintV2ForTest spv2(true); + auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2)); + + ScrollPaintPropertyNode::State scroll_state; + scroll_state.container_rect = IntRect(20, 10, 40, 50); + scroll_state.contents_size = IntSize(8000, 8000); + auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(), + std::move(scroll_state)); + auto scroll_translation = CreateScrollTranslation(*t1, -3000, -5000, *scroll); + + // Same as ApplyScrollTranslationPartialScrollingContents. + CullRect cull_rect1(IntRect(0, 0, 50, 100)); + cull_rect1.ApplyTransforms(t1.get(), scroll_translation.get(), base::nullopt); + EXPECT_EQ(IntRect(-980, 1010, 8030, 8050), cull_rect1.Rect()); + + CullRect old_cull_rect = cull_rect1; + old_cull_rect.Move(IntSize(1, 1)); + CullRect cull_rect2(IntRect(0, 0, 50, 100)); + // Use old_cull_rect if the new cull rect didn't change enough. + cull_rect2.ApplyTransforms(t1.get(), scroll_translation.get(), old_cull_rect); + EXPECT_EQ(old_cull_rect, cull_rect2); + + old_cull_rect.Move(IntSize(1000, 1000)); + CullRect cull_rect3(IntRect(0, 0, 50, 100)); + // Use the new cull rect if it changed enough. + cull_rect3.ApplyTransforms(t1.get(), scroll_translation.get(), old_cull_rect); + EXPECT_EQ(cull_rect1, cull_rect3); +} + +TEST_F(CullRectTest, ApplyTransformsEscapingScroll) { + ScopedSlimmingPaintV2ForTest spv2(true); + auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2)); + + ScrollPaintPropertyNode::State scroll_state; + scroll_state.container_rect = IntRect(20, 10, 40, 50); + scroll_state.contents_size = IntSize(8000, 8000); + auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(), + std::move(scroll_state)); + auto scroll_translation = CreateScrollTranslation(*t1, -3000, -5000, *scroll); + auto t2 = CreateTransform(*scroll_translation, + TransformationMatrix().Translate(100, 200)); + + CullRect cull_rect1(IntRect(0, 0, 50, 100)); + // Just apply tranforms without clipping and expansion for scroll translation. + cull_rect1.ApplyTransforms(t2.get(), t1.get(), base::nullopt); + EXPECT_EQ(IntRect(-2900, -4800, 50, 100), cull_rect1.Rect()); + + CullRect old_cull_rect = cull_rect1; + old_cull_rect.Move(IntSize(1, 1)); + CullRect cull_rect2(IntRect(0, 0, 50, 100)); + // Should ignore old_cull_rect. + cull_rect2.ApplyTransforms(t2.get(), t1.get(), old_cull_rect); + EXPECT_EQ(cull_rect1, cull_rect2); +} + +TEST_F(CullRectTest, ApplyTransformsSmallScrollContentsAfterBigScrollContents) { + ScopedSlimmingPaintV2ForTest spv2(true); + auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2)); + + ScrollPaintPropertyNode::State scroll_state1; + scroll_state1.container_rect = IntRect(20, 10, 40, 50); + scroll_state1.contents_size = IntSize(8000, 8000); + auto scroll1 = ScrollPaintPropertyNode::Create( + ScrollPaintPropertyNode::Root(), std::move(scroll_state1)); + auto scroll_translation1 = CreateScrollTranslation(*t1, -10, -15, *scroll1); + + auto t2 = CreateTransform(*scroll_translation1, + TransformationMatrix().Translate(2000, 3000)); + + ScrollPaintPropertyNode::State scroll_state2; + scroll_state2.container_rect = IntRect(30, 20, 100, 200); + scroll_state2.contents_size = IntSize(200, 400); + auto scroll2 = ScrollPaintPropertyNode::Create( + ScrollPaintPropertyNode::Root(), std::move(scroll_state2)); + auto scroll_translation2 = CreateScrollTranslation(*t2, -10, -15, *scroll2); + + CullRect cull_rect1(IntRect(0, 0, 50, 100)); + cull_rect1.ApplyTransforms(t1.get(), scroll_translation2.get(), + base::nullopt); + EXPECT_EQ(IntRect(-3960, -3965, 8100, 8200), cull_rect1.Rect()); + + CullRect old_cull_rect = cull_rect1; + old_cull_rect.Move(IntSize(1, 1)); + CullRect cull_rect2(IntRect(0, 0, 50, 100)); + // Should ignore old_cull_rect. + cull_rect2.ApplyTransforms(t1.get(), scroll_translation2.get(), + old_cull_rect); + EXPECT_EQ(cull_rect1, cull_rect2); +} + +TEST_F(CullRectTest, ApplyTransformsBigScrollContentsAfterSmallScrollContents) { + ScopedSlimmingPaintV2ForTest spv2(true); + auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2)); + + ScrollPaintPropertyNode::State scroll_state1; + scroll_state1.container_rect = IntRect(30, 20, 100, 200); + scroll_state1.contents_size = IntSize(200, 400); + auto scroll1 = ScrollPaintPropertyNode::Create( + ScrollPaintPropertyNode::Root(), std::move(scroll_state1)); + auto scroll_translation1 = CreateScrollTranslation(*t1, -10, -15, *scroll1); + + auto t2 = CreateTransform(*scroll_translation1, + TransformationMatrix().Translate(10, 20)); + + ScrollPaintPropertyNode::State scroll_state2; + scroll_state2.container_rect = IntRect(20, 10, 50, 100); + scroll_state2.contents_size = IntSize(10000, 20000); + auto scroll2 = ScrollPaintPropertyNode::Create( + ScrollPaintPropertyNode::Root(), std::move(scroll_state2)); + auto scroll_translation2 = + CreateScrollTranslation(*t2, -3000, -5000, *scroll2); + + CullRect cull_rect1(IntRect(0, 0, 100, 200)); + cull_rect1.ApplyTransforms(t1.get(), scroll_translation2.get(), + base::nullopt); + // After the first scroll: (-3960, -3965, 8070, 8180) + // After t2: (-3980, -3975, 8070, 8180) + // Clipped by the container rect of the second scroll: (20, 10, 50, 100) + // After the second scroll offset: (3020, 5010, 50, 100) + // Expanded: (-980, 1010, 8050, 8100) + EXPECT_EQ(IntRect(-980, 1010, 8050, 8100), cull_rect1.Rect()); + + CullRect old_cull_rect = cull_rect1; + old_cull_rect.Move(IntSize(1, 1)); + CullRect cull_rect2(IntRect(0, 0, 100, 200)); + // Use old_cull_rect if the new cull rect didn't change enough. + cull_rect2.ApplyTransforms(t1.get(), scroll_translation2.get(), + old_cull_rect); + EXPECT_EQ(old_cull_rect, cull_rect2); + + old_cull_rect.Move(IntSize(1000, 1000)); + CullRect cull_rect3(IntRect(0, 0, 100, 200)); + // Use the new cull rect if it changed enough. + cull_rect3.ApplyTransforms(t1.get(), scroll_translation2.get(), + old_cull_rect); + EXPECT_EQ(cull_rect1, cull_rect3); } TEST_F(CullRectTest, IntersectsVerticalRange) {
diff --git a/third_party/blink/renderer/platform/heap/marking_verifier.h b/third_party/blink/renderer/platform/heap/marking_verifier.h index 33f084dc..2075952 100644 --- a/third_party/blink/renderer/platform/heap/marking_verifier.h +++ b/third_party/blink/renderer/platform/heap/marking_verifier.h
@@ -63,11 +63,18 @@ private: void VerifyChild(void* base_object_payload) { + // The following check ensures that an object is currently not under + // construction. All verifier runs are assumed to be run outside of mixin + // construction. Consequently, the following cases can lead to a failing + // check: + // 1. The garbage collector ignoring no-GC scopes for mixin construction. + // 2. Missing macro USING_GARBAGE_COLLECTED_MIXIN for users of + // GarbageCollectedMixin. CHECK(base_object_payload); HeapObjectHeader* child_header = HeapObjectHeader::FromPayload(base_object_payload); - // This CHECKs ensure that any children reachable from marked parents are - // also marked. If you hit these CHECKs then marking is in an inconsistent + // These checks ensure that any children reachable from marked parents are + // also marked. If you hit these checks then marking is in an inconsistent // state meaning that there are unmarked objects reachable from marked // ones. CHECK(child_header);
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc index 3b7e355..c7dc8cf3 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.cc +++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -631,6 +631,16 @@ if (IsGCForbidden() || SweepForbidden()) return; + // This method should not call out to V8 during unified heap garbage + // collections. Specifically, reporting memory to V8 may trigger a marking + // step which is not allowed during construction of an object. The reason is + // that a parent object's constructor is potentially being invoked which may + // have already published the object. In that case the object may be colored + // black in a v8 marking step which invalidates the assumption that write + // barriers may be avoided when constructing an object as it is white. + if (IsUnifiedGCMarkingInProgress()) + return; + ReportMemoryToV8(); if (ShouldForceMemoryPressureGC()) {
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index 3198a25..ed19048 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -327,6 +327,9 @@ bool ResourceLoader::ShouldFetchCodeCache() { if (!RuntimeEnabledFeatures::IsolatedCodeCacheEnabled()) return false; + if (resource_->GetType() == ResourceType::kRaw && + !RuntimeEnabledFeatures::WasmCodeCacheEnabled()) + return false; // TODO(crbug.com/867347): Enable fetching of code caches on non-main threads // once code cache has its own mojo interface. Currently it is using
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 16d9f3e..57e6387 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1279,6 +1279,10 @@ status: "experimental", }, { + name: "WasmCodeCache", + status: "experimental", + }, + { name: "WebAnimationsAPI", status: "experimental", implied_by: ['AnimationWorklet']
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc index c12e7b3..f53a86b5 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc
@@ -51,8 +51,9 @@ nullptr, task_environment_.GetMainThreadTaskRunner(), task_environment_.GetMockTickClock()); compositor_task_queue_ = - manager_->CreateTaskQueue<base::sequence_manager::TestTaskQueue>( - base::sequence_manager::TaskQueue::Spec("test_tq")); + manager_ + ->CreateTaskQueueWithType<base::sequence_manager::TestTaskQueue>( + base::sequence_manager::TaskQueue::Spec("test_tq")); estimator_.reset(new IdleTimeEstimatorForTest( compositor_task_queue_, task_environment_.GetMockTickClock(), 10, 50)); }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc index 6222ae6..c2f50406 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc
@@ -56,7 +56,7 @@ scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerHelper::NewTaskQueue( const MainThreadTaskQueue::QueueCreationParams& params) { scoped_refptr<MainThreadTaskQueue> task_queue = - sequence_manager_->CreateTaskQueue<MainThreadTaskQueue>( + sequence_manager_->CreateTaskQueueWithType<MainThreadTaskQueue>( params.spec, params, main_thread_scheduler_); if (params.fixed_priority) task_queue->SetQueuePriority(params.fixed_priority.value());
diff --git a/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.cc b/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.cc index e6146f1..697d151 100644 --- a/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.cc +++ b/third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.cc
@@ -56,7 +56,7 @@ TaskQueue::Spec spec = TaskQueue::Spec("default_task_queue"); task_queues_.emplace_back(std::make_unique<TaskQueueWithVoters>( - manager_->CreateTaskQueue<TestTaskQueue>(spec))); + manager_->CreateTaskQueueWithType<TestTaskQueue>(spec))); } ThreadManager::~ThreadManager() = default; @@ -155,7 +155,7 @@ { AutoLock lock(lock_); task_queues_.emplace_back(std::make_unique<TaskQueueWithVoters>( - manager_->CreateTaskQueue<TestTaskQueue>(spec))); + manager_->CreateTaskQueueWithType<TestTaskQueue>(spec))); chosen_task_queue = task_queues_.back()->queue.get(); } chosen_task_queue->SetQueuePriority(
diff --git a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.cc b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.cc index 85b34bd..906c538f 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.cc
@@ -51,7 +51,7 @@ scoped_refptr<NonMainThreadTaskQueue> NonMainThreadSchedulerHelper::NewTaskQueue(const TaskQueue::Spec& spec) { - return sequence_manager_->CreateTaskQueue<NonMainThreadTaskQueue>( + return sequence_manager_->CreateTaskQueueWithType<NonMainThreadTaskQueue>( spec, non_main_thread_scheduler_); }
diff --git a/third_party/blink/tools/blinkpy/common/net/git_cl_mock.py b/third_party/blink/tools/blinkpy/common/net/git_cl_mock.py index c9fbae1..6e302cb 100644 --- a/third_party/blink/tools/blinkpy/common/net/git_cl_mock.py +++ b/third_party/blink/tools/blinkpy/common/net/git_cl_mock.py
@@ -32,7 +32,7 @@ return 'mock output' def trigger_try_jobs(self, builders, bucket=None): - bucket = bucket or 'master.tryserver.blink' + bucket = bucket or 'luci.chromium.try' command = ['try', '-B', bucket] for builder in sorted(builders): command.extend(['-b', builder])
diff --git a/third_party/blink/tools/blinkpy/common/net/git_cl_unittest.py b/third_party/blink/tools/blinkpy/common/net/git_cl_unittest.py index 738341c..6fd5a5d 100644 --- a/third_party/blink/tools/blinkpy/common/net/git_cl_unittest.py +++ b/third_party/blink/tools/blinkpy/common/net/git_cl_unittest.py
@@ -39,7 +39,7 @@ self.assertEqual(host.executive.calls, [['git', 'cl', 'issue']]) def test_trigger_try_jobs_with_list(self): - # When no bucket is specified, master.tryserver.blink is used by + # When no bucket is specified, luci.chromium.try is used by # default. Besides, `git cl try` invocations are grouped by buckets. host = MockHost() git_cl = GitCL(host, auth_refresh_token_json='token.json')
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index 7b3a22f..14e2fcf 100755 --- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -379,6 +379,12 @@ ], }, { + 'paths': ['third_party/blink/renderer/core/style/computed_style.h'], + 'allowed': [ + 'css_longhand::.+', + ], + }, + { 'paths': ['third_party/blink/renderer/core/inspector/inspector_memory_agent.cc'], 'allowed': [ 'base::ModuleCache',
diff --git a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl_unittest.py b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl_unittest.py index a920cd9e..ba88c33 100644 --- a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl_unittest.py +++ b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl_unittest.py
@@ -395,7 +395,7 @@ self.command.trigger_try_jobs(['MOCK Try Linux', 'MOCK Try Win']) self.assertEqual( self.command.git_cl.calls, - [['git', 'cl', 'try', '-B', 'master.tryserver.blink', + [['git', 'cl', 'try', '-B', 'luci.chromium.try', '-b', 'MOCK Try Linux', '-b', 'MOCK Try Win']]) self.assertLog([ 'INFO: Triggering try jobs:\n',
diff --git a/third_party/ced/BUILD.gn b/third_party/ced/BUILD.gn index 3323c1e..bbb49f58 100644 --- a/third_party/ced/BUILD.gn +++ b/third_party/ced/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//testing/test.gni") +import("//testing/libfuzzer/fuzzer_test.gni") config("ced_config") { include_dirs = [ "src" ] @@ -96,3 +97,13 @@ "//testing/gtest:gtest_main", ] } + +fuzzer_test("compact_enc_det_fuzzer") { + sources = [ + "compact_enc_det_fuzzer.cc", + ] + deps = [ + ":ced", + "//base/test:test_support", + ] +}
diff --git a/third_party/ced/DEPS b/third_party/ced/DEPS new file mode 100644 index 0000000..e7074e0 --- /dev/null +++ b/third_party/ced/DEPS
@@ -0,0 +1,5 @@ +specific_include_rules = { + 'compact_enc_det_fuzzer\.cc': [ + '+base/test/fuzzed_data_provider.h', + ], +}
diff --git a/third_party/ced/compact_enc_det_fuzzer.cc b/third_party/ced/compact_enc_det_fuzzer.cc new file mode 100644 index 0000000..008cd57 --- /dev/null +++ b/third_party/ced/compact_enc_det_fuzzer.cc
@@ -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. + +#include <string> + +#include "base/test/fuzzed_data_provider.h" +#include "third_party/ced/src/compact_enc_det/compact_enc_det.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + base::FuzzedDataProvider data_provider(data, size); + + CompactEncDet::TextCorpusType corpus = + static_cast<CompactEncDet::TextCorpusType>( + data_provider.ConsumeInt32InRange(0, CompactEncDet::NUM_CORPA)); + Encoding encoding_hint = static_cast<Encoding>( + data_provider.ConsumeInt32InRange(0, NUM_ENCODINGS)); + Language langauge_hint = static_cast<Language>( + data_provider.ConsumeInt32InRange(0, NUM_LANGUAGES)); + bool ignore_7bit_mail_encodings = data_provider.ConsumeBool(); + + std::string text = data_provider.ConsumeRemainingBytes(); + int bytes_consumed = 0; + bool is_reliable = false; + CompactEncDet::DetectEncoding( + text.c_str(), text.length(), nullptr /* url_hint */, + nullptr /* http_charset_hint */, nullptr /* meta_charset_hint */, + encoding_hint, langauge_hint, corpus, ignore_7bit_mail_encodings, + &bytes_consumed, &is_reliable); + + return 0; +}
diff --git a/third_party/closure_compiler/externs/automation.js b/third_party/closure_compiler/externs/automation.js index 859930cc..6355a3a 100644 --- a/third_party/closure_compiler/externs/automation.js +++ b/third_party/closure_compiler/externs/automation.js
@@ -537,15 +537,17 @@ /** * Computes the bounding box of a subrange of this node in global screen - * coordinates. Returns the same as |location| if range information is not - * available. The start and end indices are zero-based offsets into the node's - * "name" string attribute. + * coordinates. The start and end indices are zero-based offsets into the node's + * "name" string attribute. A callback will also be provided, which will + * be called if node bounds are available, and called with undefined when + * boundsForRange is not available. * @param {number} startIndex * @param {number} endIndex - * @return {!chrome.automation.Rect} + * @param {function(!chrome.automation.Rect):void} callback * @see https://developer.chrome.com/extensions/automation#method-boundsForRange */ -chrome.automation.AutomationNode.prototype.boundsForRange = function(startIndex, endIndex) {}; +chrome.automation.AutomationNode.prototype.boundsForRange = function( + startIndex, endIndex, callback) {}; /** * The location (as a bounding box) of this node in global screen coordinates without applying any clipping from ancestors.
diff --git a/third_party/glfw/README.chromium b/third_party/glfw/README.chromium index eb4f2dc9..2d3d03d 100644 --- a/third_party/glfw/README.chromium +++ b/third_party/glfw/README.chromium
@@ -12,3 +12,5 @@ Vulkan application development. It provides a simple, platform-independent API for creating windows, contexts and surfaces, reading input, handling events, etc. + +It is used by third_party/dawn, for building tests and samples only. \ No newline at end of file
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium index 382ed39..fa38b09 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: Sunday November 11 2018 +Date: Monday November 19 2018 Branch: master -Commit: 4a8c248744500f9caf00588ca312efce5659e45e +Commit: ac3eccdc24bccece5f73ee67b88154f3bf4a4e9a 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 bd7597e..160a434 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 "1341-g4a8c24874" +#define VERSION_EXTRA "1367-gac3eccdc2" #define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.7.0-1341-g4a8c24874" -#define VERSION_STRING " v1.7.0-1341-g4a8c24874" +#define VERSION_STRING_NOSP "v1.7.0-1367-gac3eccdc2" +#define VERSION_STRING " v1.7.0-1367-gac3eccdc2"
diff --git a/third_party/sqlite/BUILD.gn b/third_party/sqlite/BUILD.gn index 04abadc..023c286 100644 --- a/third_party/sqlite/BUILD.gn +++ b/third_party/sqlite/BUILD.gn
@@ -28,22 +28,12 @@ "SQLITE_DISABLE_FTS4_DEFERRED", "SQLITE_ENABLE_ICU", - # Enables memory tracking needed to release unused memory. - # - # Needed for sqlite3_release_memory() and its variants to work. Without this - # option, the interfaces exist, but the methods are no-ops. - "SQLITE_ENABLE_MEMORY_MANAGEMENT", - # Defaults the secure_delete pragma to 1. # # This causes SQLite to overwrite all deleted information with zeroes, # trading additional I/O for better privacy guarantees. "SQLITE_SECURE_DELETE", - # Custom flag to tweak pcache pools. - # TODO(pwnall): This shouldn't use faux-SQLite naming. - "SQLITE_SEPARATE_CACHE_POOLS", - # TODO(pwnall): SQLite adds mutexes to protect structures which cross # threads. In theory Chrome should be able to turn this to "2" which # should give a slight speed boost. "2" is safe as long as a single @@ -62,11 +52,6 @@ # TODO(pwnall): Figure out if exceeding this is costly. "SQLITE_MAX_MMAP_SIZE=268435456", - # Use a read-only memory map when mmap'ed I/O is enabled to prevent memory - # stompers from directly corrupting the database. - # TODO(pwnall): Upstream the ability to use this define. - "SQLITE_MMAP_READ_ONLY=1", - # The default POSIX permissions for a newly created SQLite database. # # If unspecified, this defaults to 0644. All the data stored by Chrome is
diff --git a/third_party/sqlite/README.chromium b/third_party/sqlite/README.chromium index 04998ac..b34116f 100644 --- a/third_party/sqlite/README.chromium +++ b/third_party/sqlite/README.chromium
@@ -1,6 +1,6 @@ Name: sqlite URL: https://sqlite.org/ -Version: 3.24.0 +Version: 3.25.3 Included In Release: Yes Security Critical: Yes License: Public domain @@ -138,8 +138,10 @@ # The steps below are easier if done in the SQLite directory. cd third_party/sqlite -export OLD=3240000 -export NEW=3250000 +# The numbers below are SQLite version numbers, and use upstream's convention +# for tagging release binaries and source zipballs. +export OLD=3250300 +export NEW=3260000 export GNU_SED=sed # OSX: "brew install gnu-sed", then use "gsed" here. #### Download and unpack the new SQLite release. @@ -156,11 +158,11 @@ #### Add the new release code in a separate CL, for code review sanity. git add sqlite-src-$NEW # Committing the code as downloaded, on purpose. git clean -i -d -x sqlite-src-$NEW # Make sure no file is git-ignored. -git commit -m "sqlite: Add code for release 3.25.0" +git commit -m "sqlite: Add code for release 3.26.0" git cl upload # Have the new code in a separate (impossible to review) CL. #### Create a branch for the old SQLite release's upstream version. -git new-branch --upstream-current sqlite-old-base +git new-branch sqlite-old-base git rm -rf src cp -r sqlite-src-${OLD}/ src # Clean up trailing whitespace and CRLF so any patches look clean. @@ -169,7 +171,7 @@ -not -iname "*.tiff" -not -iname "*.vsix" \ -exec $GNU_SED --in-place 's/[[:space:]]\+$//' {} \+ git add src/ -git clean -i -d -x sqlite-src-$NEW # Make sure no file is git-ignored. +git clean -i -d -x src # Make sure no file is git-ignored. git commit -m "Squash: Reset SQLite src/ to sqlite-src-${OLD}." # This branch will not build. It will be used for rebasing, then deleted. @@ -183,14 +185,15 @@ git checkout sqlite-old-base git new-branch --upstream-current sqlite-new-base git rm -rf src -cp -r sqlite-src-${NEW}/ src +git checkout sqlite-new-upstream -- sqlite-src-$NEW/ +git mv sqlite-src-${NEW}/ src # Clean up trailing whitespace and CRLF so any patches look clean. find src/ -type f -not -iname "*.db" -not -iname "*.eps" -not -iname "*.ico" \ -not -iname "*.jpg" -not -iname "*.pfx" -not -iname "*.png" \ -not -iname "*.tiff" -not -iname "*.vsix" \ -exec $GNU_SED --in-place 's/[[:space:]]\+$//' {} \+ git add src/ -git clean -i -d -x sqlite-src-$NEW # Make sure no file is git-ignored. +git clean -i -d -x src # Make sure no file is git-ignored. git commit -m "Squash: Reset SQLite src/ to sqlite-src-${NEW}." # This branch will not build. It will be used for rebasing, then deleted. @@ -213,23 +216,23 @@ # handle conflicts. So use git-rebase and slipstream fixups back into their # original CL until everything builds and works. cd ../.. -ninja -C out/Default +autoninja -C out/Default # Check that extract_sqlite_api.py added chrome_ to all exported symbols. # Only "_fini" and "_init" should be unprefixed. nm -B out/Default/libchromium_sqlite3.so | cut -c 18- | sort | grep '^T' out/Default/sql_unittests -third_party/blink/tools/run_web_tests.py -t Default storage/websql/* +third_party/blink/tools/run_web_tests.py -t Default storage/websql/ cd third_party/sqlite #### Create the review. # Rebuild the patch set. git rm patches/* git format-patch --output-directory=patches --ignore-space-change \ - sqlite-new-base..sqlite-new + --zero-commit sqlite-new-base..sqlite-new git add amalgamation/ git add patches/*.patch git commit -m "Squash: regenerate amalgamation and patches." -git branch --set-upstream-to=sqlite-new-upstream +git branch --set-upstream-to=origin/master git cl upload --squash # Edit the commit message appropriately to reflect anything from # <https://www.sqlite.org/changes.html> which might be deemed important. Don't @@ -241,8 +244,9 @@ #### Drop the old version of SQLite. git new-branch sqlite-rm-old -git rm -r sqlite_${BASE} +git rm -r sqlite-src-${OLD} git commit -m "sqlite: Remove source code for old release ${OLD}." +git cl upload Note that things can be broken down differently, if you prefer. For instance, adding the new version of the SQLite distro and removing the old one can be
diff --git a/tools/android/eclipse/.classpath b/tools/android/eclipse/.classpath index a373272..155fec1 100644 --- a/tools/android/eclipse/.classpath +++ b/tools/android/eclipse/.classpath
@@ -65,6 +65,7 @@ <classpathentry kind="src" path="components/navigation_interception/android/java/src"/> <classpathentry kind="src" path="components/ntp_tiles/android/java/src"/> <classpathentry kind="src" path="components/offline_items_collection/core/android/java/src"/> + <classpathentry kind="src" path="components/omnibox/browser/android/java/src"/> <classpathentry kind="src" path="components/payments/content/android/java/src"/> <classpathentry kind="src" path="components/policy/android/java/src"/> <classpathentry kind="src" path="components/policy/android/javatests/src"/> @@ -267,6 +268,7 @@ <classpathentry kind="lib" path="out/Debug/lib.java/components/invalidation/impl/java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/components/invalidation/impl/proto_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/components/navigation_interception/android/navigation_interception_java.jar"/> + <classpathentry kind="lib" path="out/Debug/lib.java/components/omnibox/browser/browser_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/components/policy/android/policy_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/components/payments/content/payment_request_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/components/precache/android/precache_java.jar"/>
diff --git a/tools/android/roll/android_deps/build.gradle b/tools/android/roll/android_deps/build.gradle index dc25e548f..544ac68 100644 --- a/tools/android/roll/android_deps/build.gradle +++ b/tools/android/roll/android_deps/build.gradle
@@ -73,6 +73,7 @@ // Matches version depended on by Dagger. compile "com.squareup:javapoet:1.11.0" + compile "com.google.protobuf:protobuf-lite:3.0.1" } task setUpRepository(type: BuildConfigGenerator) {
diff --git a/tools/binary_size/README.md b/tools/binary_size/README.md index d3c71e1..f044898 100644 --- a/tools/binary_size/README.md +++ b/tools/binary_size/README.md
@@ -65,6 +65,8 @@ * Map files contain some unique pieces of information compared to `nm` output, such as `** merge strings` entries, and some unnamed symbols (which although unnamed, contain the `.o` path). + * Generated in `is_official_build=true` builds if `generate_linker_map` is + true. In official builds on Android generate_linker_map is true by default. 1. `.o` files are mapped to `.cc` files by parsing `.ninja` files. * This means that `.h` files are never listed as sources. No information about inlined symbols is gathered.
diff --git a/tools/binary_size/libsupersize/archive.py b/tools/binary_size/libsupersize/archive.py index 95a440b372..73e7569 100644 --- a/tools/binary_size/libsupersize/archive.py +++ b/tools/binary_size/libsupersize/archive.py
@@ -1507,8 +1507,8 @@ map_path += '.gz' if not os.path.exists(map_path): parser.error('Could not find .map(.gz)? file. Ensure you have built with ' - 'is_official_build=true, or use --map-file to point me a ' - 'linker map file.') + 'is_official_build=true and generate_linker_map=true, or ' + 'use --map-file to point me a linker map file.') linker_name = _DetectLinkerName(map_path) logging.info('Linker name: %s' % linker_name)
diff --git a/tools/cygprofile/orderfile_generator_backend.py b/tools/cygprofile/orderfile_generator_backend.py index 2ddac970..7d29f537 100755 --- a/tools/cygprofile/orderfile_generator_backend.py +++ b/tools/cygprofile/orderfile_generator_backend.py
@@ -662,6 +662,13 @@ self._orderfile_updater.UploadToCloudStorage( filename, use_debug_location=False) + def UploadReadyOrderfiles(self): + self._step_recorder.BeginStep('Upload Ready Orderfiles') + for file_name in [self._GetUnpatchedOrderfileFilename(), + self._GetPathToOrderfile()]: + self._orderfile_updater.UploadToCloudStorage( + file_name, use_debug_location=False) + def _GetHashFilePathAndContents(self, base_file): """Gets the name and content of the hash file created from uploading the given file. @@ -846,6 +853,11 @@ help=('Directory to save any profiles created. These can ' 'be used with --pregenerated-profiles. Cannot be ' 'used with --skip-profiles.')) + parser.add_argument('--upload-ready-orderfiles', action='store_true', + help=('Skip orderfile generation and manually upload ' + 'orderfiles (both patched and unpatched) from ' + 'their normal location in the tree to the cloud ' + 'storage. DANGEROUS! USE WITH CARE!')) profile_android_startup.AddProfileCollectionArguments(parser) return parser @@ -868,6 +880,8 @@ try: if options.verify: generator._VerifySymbolOrder() + elif options.upload_ready_orderfiles: + return generator.UploadReadyOrderfiles() else: return generator.Generate() finally:
diff --git a/tools/grit/grit/format/resource_map.py b/tools/grit/grit/format/resource_map.py index b28141b..aa39c50 100644 --- a/tools/grit/grit/format/resource_map.py +++ b/tools/grit/grit/format/resource_map.py
@@ -144,4 +144,9 @@ def _GetItemPath(item): - return item.GetInputPath().replace("\\", "/") + path = item.GetInputPath().replace("\\", "/") + # resource_maps don't currently work with variables. See crbug.com/899437 + # for why you might not need this, and if you still think you need it then + # comment 17 has a patch for how to make it work. + assert '$' not in path, 'see comment above' + return path
diff --git a/tools/ipc_fuzzer/scripts/play_testcase.py b/tools/ipc_fuzzer/scripts/play_testcase.py index bac348b5..dd5b0e2 100644 --- a/tools/ipc_fuzzer/scripts/play_testcase.py +++ b/tools/ipc_fuzzer/scripts/play_testcase.py
@@ -87,7 +87,6 @@ prefixes = { '--renderer-cmd-prefix', - '--gpu-launcher', '--plugin-launcher', '--ppapi-plugin-launcher', '--utility-cmd-prefix',
diff --git a/tools/ipc_fuzzer/scripts/utils.py b/tools/ipc_fuzzer/scripts/utils.py index 24c3285..3f19845 100644 --- a/tools/ipc_fuzzer/scripts/utils.py +++ b/tools/ipc_fuzzer/scripts/utils.py
@@ -17,11 +17,13 @@ IPC_FUZZER_APPLICATION = 'ipc_fuzzer' IPC_REPLAY_APPLICATION = 'ipc_fuzzer_replay' IPCDUMP_EXTENSION = '.ipcdump' -LAUNCH_PREFIXES = [ - '--gpu-launcher', +UNCOMMON_PREFIX_CHANCE = 10 # 1 in 10 +COMMON_LAUNCH_PREFIXES = [ + '--renderer-cmd-prefix', +] +UNCOMMON_LAUNCH_PEFIXES = [ '--plugin-launcher', '--ppapi-plugin-launcher', - '--renderer-cmd-prefix', '--utility-cmd-prefix', ] @@ -35,7 +37,10 @@ def create_flags_file(ipcdump_testcase_path): """Create a flags file to add launch prefix to application command line.""" - random_launch_prefix = random.choice(LAUNCH_PREFIXES) + prefixes = (UNCOMMON_LAUNCH_PREFIXES if + random.randint(1, UNCOMMON_PREFIX_CHANCE) == 1 else + COMMON_LAUNCH_PREFIXES) + random_launch_prefix = random.choice(prefixes) application_name = application_name_for_platform(IPC_REPLAY_APPLICATION) file_content = '%s=%%APP_DIR%%%s%s' % (random_launch_prefix, os.path.sep, application_name)
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 2203e0d8..ee4505a 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -547,6 +547,15 @@ 'mac10.13_retina-blink-rel': 'release_bot_minimal_symbols', 'win7-blink-rel': 'release_bot_x86_minimal_symbols', 'win10-blink-rel': 'release_bot_x86_minimal_symbols', + # TODO(dpranke): Delete all the old names once things have been updated. + 'linux_trusty_blink_rel': 'release_bot_minimal_symbols', + 'mac10.10_blink_rel': 'release_bot_minimal_symbols', + 'mac10.11_blink_rel': 'release_bot_minimal_symbols', + 'mac10.12_blink_rel': 'release_bot_minimal_symbols', + 'mac10.13_blink_rel': 'release_bot_minimal_symbols', + 'mac10.13_retina_blink_rel': 'release_bot_minimal_symbols', + 'win7_blink_rel': 'release_bot_x86_minimal_symbols', + 'win10_blink_rel': 'release_bot_x86_minimal_symbols', }, 'tryserver.chromium.android': { @@ -621,6 +630,8 @@ }, 'tryserver.chromium.dawn': { + 'linux-dawn-rel': 'gpu_fyi_tests_release_trybot', + 'mac-dawn-rel': 'gpu_fyi_tests_release_trybot', 'win-dawn-rel': 'gpu_fyi_tests_release_trybot_x86', },
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 96ecf6b..75b4bb3 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -11650,6 +11650,45 @@ </description> </action> +<action name="MobileOmniboxShortcutsOpenBookmarks"> + <owner>stkhapugin@chromium.org</owner> + <description> + The user clicked the Bookmarks shortcut in Omnibox popup shortcuts. iOS + only. + </description> +</action> + +<action name="MobileOmniboxShortcutsOpenHistory"> + <owner>stkhapugin@chromium.org</owner> + <description> + The user clicked the History shortcut in Omnibox popup shortcuts. iOS only. + </description> +</action> + +<action name="MobileOmniboxShortcutsOpenMostVisitedItem"> + <owner>stkhapugin@chromium.org</owner> + <description> + The user clicked one of the Most Visited tiles in Omnibox popup shortcuts. + iOS only. + </description> +</action> + +<action name="MobileOmniboxShortcutsOpenReadingList"> + <owner>stkhapugin@chromium.org</owner> + <description> + The user clicked the Reading List shortcut in Omnibox popup shortcuts. iOS + only. + </description> +</action> + +<action name="MobileOmniboxShortcutsOpenRecentTabs"> + <owner>stkhapugin@chromium.org</owner> + <description> + The user clicked the Recent Tabs shortcut in Omnibox popup shortcuts. iOS + only. + </description> +</action> + <action name="MobileOmniboxUse"> <owner>mpearson@chromium.org</owner> <owner>tedchoc@chromium.org</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index bf1b379..a8677dc 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -14916,6 +14916,7 @@ <int value="499" label="ReportExtensionsAndPluginsData"/> <int value="500" label="ReportSafeBrowsingData"/> <int value="501" label="DeviceWiFiFastTransitionEnabled"/> + <int value="502" label="DeviceDisplayResolution"/> </enum> <enum name="EnterprisePolicyInvalidations"> @@ -15938,6 +15939,7 @@ <int value="425" label="ARC_APPS_PRIVATE_ON_INSTALLED"/> <int value="426" label="FILE_MANAGER_PRIVATE_ON_CROSTINI_SHARED_PATHS_CHANGED"/> + <int value="427" label="AUTOMATION_INTERNAL_ON_GET_TEXT_LOCATION_RESULT"/> </enum> <enum name="ExtensionFileWriteResult"> @@ -17291,6 +17293,7 @@ label="BRAILLEDISPLAYPRIVATE_UPDATEBLUETOOTHBRAILLEDISPLAYADDRESS"/> <int value="1292" label="AUTOTESTPRIVATE_SETASSISTANTENABLED"/> <int value="1293" label="AUTOTESTPRIVATE_ISARCPROVISIONED"/> + <int value="1294" label="CRYPTOTOKENPRIVATE_CANPROXYTOWEBAUTHN"/> </enum> <enum name="ExtensionIconState"> @@ -23600,6 +23603,27 @@ <int value="3" label="Timeout"/> </enum> +<enum name="GestureEventFilterResults"> + <int value="0" + label="GestureScrollBegin allowed by main thread touch action"/> + <int value="1" + label="GestureScrollBegin allowed by compositor thread touch action"/> + <int value="2" + label="GestureScrollBegin filtered by main thread touch action"/> + <int value="3" + label="GestureScrollBegin filtered by compositor thread touch action"/> + <int value="4" label="GestureScrollBegin deferred"/> + <int value="5" + label="GestureScrollUpdate allowed by main thread touch action"/> + <int value="6" + label="GestureScrollUpdate allowed by compositor thread touch action"/> + <int value="7" + label="GestureScrollUpdate filtered by main thread touch action"/> + <int value="8" + label="GestureScrollUpdate filtered by compositor thread touch action"/> + <int value="9" label="GestureScrollUpdate deferred"/> +</enum> + <enum name="GestureMergeState"> <int value="0" label="Neither token had a gesture"/> <int value="1" label="Only the old token had a gesture"/> @@ -26039,6 +26063,13 @@ <int value="2" label="Has access"/> </enum> +<enum name="InitiatorAccess2"> + <int value="0" label="Initiator absent"/> + <int value="1" label="Initiator opaque"/> + <int value="2" label="No access"/> + <int value="3" label="Has access"/> +</enum> + <enum name="InjectedAdType"> <int value="0" label="Invalid"/> <int value="1" label="IFrame"/> @@ -29410,6 +29441,7 @@ <int value="-1555510175" label="PasswordImport:enabled"/> <int value="-1553477903" label="ash-disable-text-filtering-in-overview-mode"/> <int value="-1552898031" label="SingleTabMode:enabled"/> + <int value="-1550760918" label="PipRoundedCorners:disabled"/> <int value="-1549871007" label="OneGoogleBarOnLocalNtp:disabled"/> <int value="-1549356351" label="SyncPseudoUSSExtensionSettings:enabled"/> <int value="-1547247328" label="OverrideTranslateTriggerInIndia:disabled"/> @@ -30530,6 +30562,7 @@ <int value="533064367" label="WebRtcHideLocalIpsWithMdns:disabled"/> <int value="535131384" label="OmniboxTailSuggestions:enabled"/> <int value="535976218" label="enable-plugin-power-saver"/> + <int value="537857256" label="PipRoundedCorners:enabled"/> <int value="538468149" label="OfflinePagesCT:enabled"/> <int value="538600423" label="OmniboxDocumentProvider:enabled"/> <int value="546520086" label="enable-data-reduction-proxy-savings-promo"/> @@ -33803,6 +33836,9 @@ <int value="2" label="Resumption button clicked"/> <int value="3" label="Resumption failed"/> <int value="4" label="Resumption auto started"/> + <int value="5" label="Resumption started while browser process is running"/> + <int value="6" + label="Resumption started while browser process is not running"/> </enum> <enum name="MobileDownloadStoragePermission"> @@ -34964,17 +35000,22 @@ An error page was shown with at least a "Download Page Later" button on it and the user pressed that button. </int> - <int value="24" label="Offline Suggestions Shown"> - An error page was shown with at least one offline content suggestion. + <int value="24" label="Offline Suggestions List Shown"> + A list containing at least one item of offline content suggestions was shown + in the expanded/shown state. </int> - <int value="25" label="Offline Suggestion Clicked"> - The user pressed a button to open an offline content suggestion. + <int value="25" label="Offline Suggestion List Item Clicked"> + An item from the offline content suggestions list was clicked. </int> <int value="26" label="Downloads Page Button Clicked"> - The user pressed a button to open the downloads page. + A link that opens the downloads page was clicked. </int> <int value="27" label="Offline Content Summary Shown"> - A summary of available offline content was presented. + A summary of available offline content was shown. + </int> + <int value="28" label="Offline Suggestions List Shown Collapsed"> + A list containing at least one item of offline content suggestions was shown + in the collapsed/hidden state. </int> </enum> @@ -39459,6 +39500,21 @@ <int value="1" label="From Android"/> </enum> +<enum name="PasswordManagerHttpCredentialType"> + <summary> + This enum records the type of a given HTTP credential. Depending on its + username and the password, an HTTP credential can have no matching, an + equivalent or a conflicting HTTPS credentials. Also the corresponding + website can be served with or without HSTS enabled. + </summary> + <int value="0" label="Conflicting HTTPS, HSTS disabled"/> + <int value="1" label="Conflicting HTTPS, HSTS enabled"/> + <int value="2" label="Equivalent HTTPS, HSTS disabled"/> + <int value="3" label="Equivalent HTTPS, HSTS enabled"/> + <int value="4" label="No Matching HTTPS, HSTS disabled"/> + <int value="5" label="No Matching HTTPS, HSTS enabled"/> +</enum> + <enum name="PasswordManagerOfferedAndroidCredentials"> <int value="0" label="None from Android"/> <int value="1" label="1+ from Android"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index df63cd5..e8e5887 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -7957,6 +7957,16 @@ </summary> </histogram> +<histogram name="Autofill.StrikeDatabase.StrikeDatabaseInitFailed" + units="attempts" expires_after="2019-03-18"> + <owner>jsaul@google.com</owner> + <owner>annelim@google.com</owner> + <summary> + When a StrikeDatabase fails to initialize, records the number of consecutive + failed initialization attempts. + </summary> +</histogram> + <histogram name="Autofill.StrikeDatabase.StrikesPresentWhenLocalCardSaved" units="strikes" expires_after="2019-03-18"> <owner>jsaul@google.com</owner> @@ -21189,8 +21199,10 @@ </summary> </histogram> -<histogram base="true" name="DisplayScheduler.ShouldNotDraw" enum="Boolean" - expires_after="M72"> +<histogram base="true" name="DisplayScheduler.ShouldNotDraw" enum="Boolean"> + <obsolete> + Deprecated after M72 since no longer needed. + </obsolete> <!-- Name completed by histogram_suffixes name="DisplaySchedulerNotDrawReason" --> @@ -31571,7 +31583,7 @@ </histogram> <histogram name="Extensions.ExtensionUpdaterFirstUpdateCheckErrorsGoogleUrl" - enum="CombinedHttpResponseAndNetErrorCode" expires_after="M72"> + enum="CombinedHttpResponseAndNetErrorCode" expires_after="M75"> <owner>mxnguyen@chromium.org</owner> <summary> Records the error codes of the extension updater update check errors. These @@ -31582,7 +31594,7 @@ </histogram> <histogram name="Extensions.ExtensionUpdaterFirstUpdateCheckErrorsNonGoogleUrl" - enum="CombinedHttpResponseAndNetErrorCode" expires_after="M72"> + enum="CombinedHttpResponseAndNetErrorCode" expires_after="M75"> <owner>mxnguyen@chromium.org</owner> <summary> Records the error codes of the extension updater update check errors. These @@ -33731,6 +33743,10 @@ <histogram name="Extensions.WebRequest.InitiatorAccess" enum="InitiatorAccess" expires_after="2018-12-31"> + <obsolete> + Deprecated November 2018. Replaced with + Extensions.WebRequest.InitiatorAccess2. + </obsolete> <owner>karandeepb@chromium.org</owner> <owner>rdevlin.cronin@chromium.org</owner> <summary> @@ -33740,6 +33756,18 @@ </summary> </histogram> +<histogram name="Extensions.WebRequest.InitiatorAccess2" + enum="InitiatorAccess2" expires_after="2019-04-30"> + <owner>karandeepb@chromium.org</owner> + <owner>rdevlin.cronin@chromium.org</owner> + <summary> + Describes the different cases pertaining to host permissions check for the + initiator URL of a network request. This is emitted whenever an extension is + found to have access to a request url for the WebRequest or Declarative Net + Request API. + </summary> +</histogram> + <histogram name="Extensions.WebRequest.ModifiedResponseHeaders" enum="WebRequestResponseHeaderType"> <obsolete> @@ -51249,6 +51277,14 @@ </summary> </histogram> +<histogram name="MobileOmnibox.PopupOpenDuration" units="ms"> + <owner>stkhapugin@chromium.org</owner> + <summary> + Recorded when the omnibox popup is closed. Indicates the duration it was + open. + </summary> +</histogram> + <histogram name="MobileOmnibox.PressedClipboardSuggestionAge" units="ms"> <owner>jif@chromium.org</owner> <owner>mpearson@chromium.org</owner> @@ -52101,6 +52137,36 @@ </histogram> <histogram + name="MultiDevice.SecureChannel.BLE.Performance.ConnectionToAuthenticationDuration.Background" + units="ms"> + <owner>hansberry@chromium.org</owner> + <summary> + A time histogram measuring the time from the moment a GATT connection is + made to the remote device, to the moment that an authenticated channel is + established with the remote device. + + In this context, "background" refers to the BLE advertising scheme + under which the remote device is persistently advertising "in the + background" at low power. + </summary> +</histogram> + +<histogram + name="MultiDevice.SecureChannel.BLE.Performance.ReceiveAdvertisementToConnectionDuration.Background" + units="ms"> + <owner>hansberry@chromium.org</owner> + <summary> + A time histogram measuring the time from the moment a background + advertisement is received, to the moment that a GATT connection is made to + the remote device. + + In this context, "background" refers to the BLE advertising scheme + under which the remote device is persistently advertising "in the + background" at low power. + </summary> +</histogram> + +<histogram name="MultiDevice.SecureChannel.BLE.Performance.StartScanToAuthenticationDuration.Background" units="ms"> <owner>hansberry@chromium.org</owner> @@ -52116,6 +52182,36 @@ </summary> </histogram> +<histogram + name="MultiDevice.SecureChannel.BLE.Performance.StartScanToConnectionDuration.Background" + units="ms"> + <owner>hansberry@chromium.org</owner> + <summary> + A time histogram measuring the time it from the moment SecureChannelService + starts scanning for a background advertisement, to the moment that it + establishes a GATT connection to the remote device. + + In this context, "background" refers to the BLE advertising scheme + under which the remote device is persistently advertising "in the + background" at low power. + </summary> +</histogram> + +<histogram + name="MultiDevice.SecureChannel.BLE.Performance.StartScanToReceiveAdvertisementDuration.Background" + units="ms"> + <owner>hansberry@chromium.org</owner> + <summary> + A time histogram measuring the time it from the moment SecureChannelService + starts scanning for a background advertisement, to the moment that it + receives an advertisement from the expected remote device. + + In this context, "background" refers to the BLE advertising scheme + under which the remote device is persistently advertising "in the + background" at low power. + </summary> +</histogram> + <histogram name="MultiDevice.Setup.HostStatus" enum="MultiDevice_Setup_HostStatus"> <owner>hansberry@chromium.org</owner> @@ -76477,8 +76573,23 @@ </summary> </histogram> +<histogram name="PasswordManager.HttpCredentials" + enum="PasswordManagerHttpCredentialType"> + <owner>jdoerrie@chromium.org</owner> + <owner>vasilii@chromium.org</owner> + <summary> + Breakdown of HTTP credentials with regard to the existence of a HTTPS + credential with the same username and whether the corresponding website has + HSTS enabled. Recorded once for each HTTP credential of the profile on + startup. + </summary> +</histogram> + <histogram name="PasswordManager.HttpCredentialsWithConflictingHttpsCredential" units="saved credentials" expires_after="M72"> + <obsolete> + Deprecated as of M72. Superseded by PasswordManager.HttpCredentials. + </obsolete> <owner>gemene@google.com</owner> <owner>jdoerrie@chromium.org</owner> <summary> @@ -76490,6 +76601,9 @@ <histogram name="PasswordManager.HttpCredentialsWithEquivalentHttpsCredential" units="saved credentials" expires_after="M72"> + <obsolete> + Deprecated as of M72. Superseded by PasswordManager.HttpCredentials. + </obsolete> <owner>gemene@google.com</owner> <owner>jdoerrie@chromium.org</owner> <summary> @@ -76501,6 +76615,9 @@ <histogram name="PasswordManager.HttpCredentialsWithoutMatchingHttpsCredential" units="saved credentials" expires_after="M72"> + <obsolete> + Deprecated as of M72. Superseded by PasswordManager.HttpCredentials. + </obsolete> <owner>gemene@google.com</owner> <owner>jdoerrie@chromium.org</owner> <summary> @@ -90038,6 +90155,19 @@ </summary> </histogram> +<histogram + name="ResourceLoadingHints.ResourcePatternsAvailableAtCommitForRedirect" + enum="BooleanAvailable"> + <owner>tbansal@chromium.org</owner> + <owner>dougarnett@chromium.org</owner> + <summary> + Records if the resource patterns were available at the time of page commit + if the committed previews type was RESOURCE_LOADING_HINTS and the navigation + was redirected. This is a subset of the ResourcePatternsAvailableAtCommit + histogram. + </summary> +</histogram> + <histogram name="ResourcePrefetchPredictor.CachePattern" enum="HttpCachePattern"> <obsolete> @@ -113786,6 +113916,15 @@ </summary> </histogram> +<histogram name="TouchAction.GestureEventFilterResults" + enum="GestureEventFilterResults"> + <owner>xidachen@chromium.org</owner> + <owner>nzolghadr@chromium.org</owner> + <summary> + Track whether a gesture event is allowed or filtered or deferred. + </summary> +</histogram> + <histogram name="TouchBar.Default.Metrics" enum="DefaultTouchBarActions"> <owner>spqchan@chromium.org</owner> <summary>Tracks the usage of the default touch bar buttons.</summary> @@ -128473,6 +128612,9 @@ </histogram_suffixes> <histogram_suffixes name="DisplaySchedulerNotDrawReason" separator="."> + <obsolete> + Deprecated after M72 since no longer needed. + </obsolete> <suffix name="DrawNotNeeded" label="DrawNotNeeded"/> <suffix name="NotVisible" label="NotVisible"/> <suffix name="OutputSurfaceLost" label="OutputSurfaceLost"/>
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index 719c789..c41bad9 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -19,7 +19,8 @@ crbug.com/882881 [ Nexus_5X ] blink_perf.bindings/worker-structured-clone-json-to-worker.html [ Skip ] crbug.com/882881 [ Nexus_5 ] blink_perf.bindings/worker-structured-clone-json-from-worker.html [ Skip ] crbug.com/882881 [ Nexus_5X ] blink_perf.bindings/worker-structured-clone-json-from-worker.html [ Skip ] - +crbug.com/865400 [ Pixel_2 ] blink_perf.bindings/structured-clone-long-string-deserialize.html [ Skip ] +crbug.com/865400 [ Pixel_2 ] blink_perf.bindings/structured-clone-long-string-serialize.html [ Skip ] # Benchmark: blink_perf.canvas crbug.com/593973 [ Android_Svelte ] blink_perf.canvas/* [ Skip ]
diff --git a/ui/accessibility/ax_action_data.h b/ui/accessibility/ax_action_data.h index 543c072..575db7f 100644 --- a/ui/accessibility/ax_action_data.h +++ b/ui/accessibility/ax_action_data.h
@@ -54,6 +54,12 @@ int focus_node_id = -1; int focus_offset = -1; + // Start index of the text which should be queried for. + int32_t start_index = -1; + + // End index of the text which should be queried for. + int32_t end_index = -1; + // For custom action. int custom_action_id = -1;
diff --git a/ui/accessibility/ax_enum_util.cc b/ui/accessibility/ax_enum_util.cc index af11d49..cb523c4 100644 --- a/ui/accessibility/ax_enum_util.cc +++ b/ui/accessibility/ax_enum_util.cc
@@ -997,6 +997,8 @@ return "setValue"; case ax::mojom::Action::kShowContextMenu: return "showContextMenu"; + case ax::mojom::Action::kGetTextLocation: + return "getTextLocation"; } return ""; @@ -1549,6 +1551,8 @@ return "clipsChildren"; case ax::mojom::BoolAttribute::kSelected: return "selected"; + case ax::mojom::BoolAttribute::kSupportsTextLocation: + return "supportsTextLocation"; } return ""; @@ -1581,6 +1585,8 @@ return ax::mojom::BoolAttribute::kClipsChildren; if (0 == strcmp(bool_attribute, "selected")) return ax::mojom::BoolAttribute::kSelected; + if (0 == strcmp(bool_attribute, "supportsTextLocation")) + return ax::mojom::BoolAttribute::kSupportsTextLocation; return ax::mojom::BoolAttribute::kNone; }
diff --git a/ui/accessibility/ax_enums.mojom b/ui/accessibility/ax_enums.mojom index 58d6802b..905352e5 100644 --- a/ui/accessibility/ax_enums.mojom +++ b/ui/accessibility/ax_enums.mojom
@@ -381,6 +381,7 @@ kSetValue, kShowContextMenu, + kGetTextLocation, }; enum ActionFlags { @@ -615,6 +616,9 @@ // Indicates whether this node is selected or unselected. kSelected, + + // Indicates whether this node supports text location. + kSupportsTextLocation, }; enum IntListAttribute {
diff --git a/ui/accessibility/ax_node_data.cc b/ui/accessibility/ax_node_data.cc index aea446b0..7dfeb256 100644 --- a/ui/accessibility/ax_node_data.cc +++ b/ui/accessibility/ax_node_data.cc
@@ -577,6 +577,7 @@ case ax::mojom::Action::kScrollDown: case ax::mojom::Action::kScrollLeft: case ax::mojom::Action::kScrollRight: + case ax::mojom::Action::kGetTextLocation: break; } @@ -1177,6 +1178,9 @@ case ax::mojom::BoolAttribute::kSelected: result += " selected=" + value; break; + case ax::mojom::BoolAttribute::kSupportsTextLocation: + result += " supports_text_location=" + value; + break; case ax::mojom::BoolAttribute::kNone: break; }
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index e46865b..f456af56 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -116,10 +116,6 @@ "cocoa/focus_tracker.mm", "cocoa/focus_window_set.h", "cocoa/focus_window_set.mm", - "cocoa/hover_button.h", - "cocoa/hover_button.mm", - "cocoa/hover_image_button.h", - "cocoa/hover_image_button.mm", "cocoa/menu_controller.h", "cocoa/menu_controller.mm", "cocoa/nib_loading.h", @@ -851,8 +847,6 @@ "cocoa/cocoa_base_utils_unittest.mm", "cocoa/constrained_window/constrained_window_animation_unittest.mm", "cocoa/focus_tracker_unittest.mm", - "cocoa/hover_button_unittest.mm", - "cocoa/hover_image_button_unittest.mm", "cocoa/menu_controller_unittest.mm", "cocoa/touch_bar_util_unittest.mm", "cocoa/tracking_area_unittest.mm",
diff --git a/ui/base/cocoa/hover_button.h b/ui/base/cocoa/hover_button.h deleted file mode 100644 index 9249a30..0000000 --- a/ui/base/cocoa/hover_button.h +++ /dev/null
@@ -1,84 +0,0 @@ -// Copyright (c) 2011 The Chromium 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_BASE_COCOA_HOVER_BUTTON_ -#define UI_BASE_COCOA_HOVER_BUTTON_ - -#import <Cocoa/Cocoa.h> - -#import "ui/base/cocoa/tracking_area.h" -#import "ui/base/ui_base_export.h" - -@class HoverButtonCocoa; - -// Assign an object which conforms to this protocol to a HoverButtonCocoa's -// dragDelegate property to make the button draggable. -UI_BASE_EXPORT -@protocol HoverButtonDragDelegate - -// When the user performs a drag on the HoverButtonCocoa, this method will be -// called with the button and the mouse down event. The delegate is expected to -// begin a drag by calling -[NSView beginDraggingSessionWithItems:event:source:] -// with the event or run a nested tracking loop. When it returns, the -// HoverButtonCocoa returns to kHoverStateNone and stops tracking the mouse. -- (void)beginDragFromHoverButton:(HoverButtonCocoa*)button - event:(NSEvent*)event; - -@end - -// A button that changes when you hover over it and click it. -UI_BASE_EXPORT -@interface HoverButtonCocoa : NSButton { - @protected - // Enumeration of the hover states that the close button can be in at any one - // time. The button cannot be in more than one hover state at a time. - enum CloseButtonHoverState { - kHoverStateNone = 0, - kHoverStateMouseOver = 1, - kHoverStateMouseDown = 2 - }; - - CloseButtonHoverState hoverState_; - - @private - // Tracking area for button mouseover states. Nil if not enabled. - ui::ScopedCrTrackingArea trackingArea_; - BOOL mouseDown_; - BOOL sendActionOnMouseDown_; -} - -@property(nonatomic) CloseButtonHoverState hoverState; - -// Enables or disables the tracking for the button. -@property(nonatomic) BOOL trackingEnabled; - -// Assign an object to make the button a drag source. -@property(nonatomic, assign) id<HoverButtonDragDelegate> dragDelegate; - -// Enables or disables sending the action on mouse down event. -@property(nonatomic) BOOL sendActionOnMouseDown; - -// An NSRect in the view's coordinate space which is used for hover and hit -// testing. Default value is NSZeroRect, which makes the hitbox equal to the -// view's bounds. May be overridden by subclasses. Example: A button in the -// corner of a fullscreen window might extend its hitbox to the edges of the -// window so that it can be clicked more easily (Fitts's law). -@property(readonly, nonatomic) NSRect hitbox; - -// Common initialization called from initWithFrame: and awakeFromNib. -// Subclassers should call [super commonInit]. -- (void)commonInit; - -// Text that would be announced by screen readers. -- (void)setAccessibilityTitle:(NSString*)accessibilityTitle; - -// Checks to see whether the mouse is in the button's bounds and update -// the image in case it gets out of sync. This occurs to the close button -// when you close a tab so the tab to the left of it takes its place, and -// drag the button without moving the mouse before you press the button down. -- (void)checkImageState; - -@end - -#endif // UI_BASE_COCOA_HOVER_BUTTON_
diff --git a/ui/base/cocoa/hover_button.mm b/ui/base/cocoa/hover_button.mm deleted file mode 100644 index d9dd53d8a..0000000 --- a/ui/base/cocoa/hover_button.mm +++ /dev/null
@@ -1,210 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ui/base/cocoa/hover_button.h" - -#include <cmath> - -namespace { - -// Distance to start a drag when a dragDelegate is assigned. -constexpr CGFloat kDragDistance = 5; - -} // namespace - -@implementation HoverButtonCocoa - -@synthesize hoverState = hoverState_; -@synthesize trackingEnabled = trackingEnabled_; -@synthesize dragDelegate = dragDelegate_; -@synthesize sendActionOnMouseDown = sendActionOnMouseDown_; - -- (instancetype)initWithFrame:(NSRect)frameRect { - if ((self = [super initWithFrame:frameRect])) { - [self commonInit]; - } - return self; -} - -- (void)awakeFromNib { - [self commonInit]; -} - -- (void)commonInit { - self.hoverState = kHoverStateNone; - self.trackingEnabled = YES; -} - -- (void)dealloc { - self.trackingEnabled = NO; - [super dealloc]; -} - -- (NSRect)hitbox { - return NSZeroRect; -} - -- (void)setTrackingEnabled:(BOOL)trackingEnabled { - if (trackingEnabled == trackingEnabled_) - return; - trackingEnabled_ = trackingEnabled; - [self updateTrackingAreas]; -} - -- (void)setEnabled:(BOOL)enabled { - if (enabled == self.enabled) - return; - super.enabled = enabled; - [self updateTrackingAreas]; -} - -- (void)mouseEntered:(NSEvent*)theEvent { - if (trackingArea_.get()) - self.hoverState = kHoverStateMouseOver; -} - -- (void)mouseMoved:(NSEvent*)theEvent { - [self checkImageState]; -} - -- (void)mouseExited:(NSEvent*)theEvent { - if (trackingArea_.get()) - self.hoverState = kHoverStateNone; -} - -- (void)mouseDown:(NSEvent*)theEvent { - if (!self.enabled) - return; - mouseDown_ = YES; - self.hoverState = kHoverStateMouseDown; - - if (sendActionOnMouseDown_) - [self sendAction:self.action to:self.target]; - - // The hover button needs to hold onto itself here for a bit. Otherwise, - // it can be freed while in the tracking loop below. - // http://crbug.com/28220 - base::scoped_nsobject<HoverButtonCocoa> myself([self retain]); - - // Begin tracking the mouse. - if ([theEvent type] == NSLeftMouseDown) { - NSWindow* window = [self window]; - NSEvent* nextEvent = nil; - - // For the tracking loop ignore key events so that they don't pile up in - // the queue and get processed after the user releases the mouse. - const NSEventMask eventMask = (NSLeftMouseDraggedMask | NSLeftMouseUpMask | - NSKeyDownMask | NSKeyUpMask); - - while ((nextEvent = [window nextEventMatchingMask:eventMask])) { - if ([nextEvent type] == NSLeftMouseUp) - break; - // Update the image state, which will change if the user moves the mouse - // into or out of the button. - [self checkImageState]; - if (dragDelegate_ && [nextEvent type] == NSLeftMouseDragged) { - const NSPoint startPos = [theEvent locationInWindow]; - const NSPoint pos = [nextEvent locationInWindow]; - if (std::abs(startPos.x - pos.x) > kDragDistance || - std::abs(startPos.y - pos.y) > kDragDistance) { - [dragDelegate_ beginDragFromHoverButton:self event:nextEvent]; - mouseDown_ = NO; - self.hoverState = kHoverStateNone; - return; - } - } - } - } - - // If the mouse is still over the button, it means the user clicked the - // button. - if (!sendActionOnMouseDown_ && self.hoverState == kHoverStateMouseDown) { - [self sendAction:self.action to:self.target]; - } - - // Clean up. - mouseDown_ = NO; - [self checkImageState]; -} - -- (void)setAccessibilityTitle:(NSString*)accessibilityTitle { - NSCell* cell = [self cell]; - [cell accessibilitySetOverrideValue:accessibilityTitle - forAttribute:NSAccessibilityTitleAttribute]; -} - -- (void)updateTrackingAreas { - if (trackingEnabled_ && self.enabled) { - NSRect hitbox = self.hitbox; - if (CrTrackingArea* trackingArea = trackingArea_.get()) { - if (NSEqualRects(trackingArea.rect, hitbox)) - return; - [self removeTrackingArea:trackingArea]; - } - trackingArea_.reset([[CrTrackingArea alloc] - initWithRect:hitbox - options:NSTrackingMouseEnteredAndExited | - NSTrackingMouseMoved | - NSTrackingActiveAlways | - (NSIsEmptyRect(hitbox) ? NSTrackingInVisibleRect : 0) - owner:self - userInfo:nil]); - [self addTrackingArea:trackingArea_.get()]; - - // If you have a separate window that overlaps the close button, and you - // move the mouse directly over the close button without entering another - // part of the tab strip, we don't get any mouseEntered event since the - // tracking area was disabled when we entered. - // Done with a delay of 0 because sometimes an event appears to be missed - // between the activation of the tracking area and the call to - // checkImageState resulting in the button state being incorrect. - [self performSelector:@selector(checkImageState) - withObject:nil - afterDelay:0]; - } else { - if (trackingArea_.get()) { - self.hoverState = kHoverStateNone; - [self removeTrackingArea:trackingArea_.get()]; - trackingArea_.reset(nil); - } - } - [super updateTrackingAreas]; - [self checkImageState]; -} - -- (void)checkImageState { - if (!trackingArea_.get()) - return; - - NSEvent* currentEvent = [NSApp currentEvent]; - if (!currentEvent || currentEvent.window != self.window) - return; - - // Update the button's state if the button has moved. - const NSPoint mouseLoc = - [self.superview convertPoint:currentEvent.locationInWindow fromView:nil]; - BOOL mouseInBounds = [self hitTest:mouseLoc] != nil; - if (mouseDown_ && mouseInBounds) { - self.hoverState = kHoverStateMouseDown; - } else { - self.hoverState = mouseInBounds ? kHoverStateMouseOver : kHoverStateNone; - } -} - -- (void)setHoverState:(CloseButtonHoverState)hoverState { - if (hoverState == hoverState_) - return; - hoverState_ = hoverState; - self.needsDisplay = YES; -} - -- (NSView*)hitTest:(NSPoint)point { - if (NSPointInRect([self.superview convertPoint:point toView:self], - self.hitbox)) { - return self; - } - return [super hitTest:point]; -} - -@end
diff --git a/ui/base/cocoa/hover_button_unittest.mm b/ui/base/cocoa/hover_button_unittest.mm deleted file mode 100644 index 10a8472..0000000 --- a/ui/base/cocoa/hover_button_unittest.mm +++ /dev/null
@@ -1,200 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ui/base/cocoa/hover_button.h" - -#import <Cocoa/Cocoa.h> - -#import "ui/base/test/cocoa_helper.h" -#import "ui/events/test/cocoa_test_event_utils.h" - -@interface TestHoverButton : HoverButtonCocoa -@property(readwrite, nonatomic) NSRect hitbox; -@end - -@implementation TestHoverButton -@synthesize hitbox = hitbox_; - -- (void)setHitbox:(NSRect)hitbox { - hitbox_ = hitbox; - [self updateTrackingAreas]; -} -@end - -@interface HoverButtonTestTarget : NSObject -@property(nonatomic, copy) void (^actionHandler)(id); -@end - -@implementation HoverButtonTestTarget -@synthesize actionHandler = actionHandler_; - -- (void)dealloc { - [actionHandler_ release]; - [super dealloc]; -} - -- (IBAction)action:(id)sender { - actionHandler_(sender); -} -@end - -@interface HoverButtonTestDragDelegate : NSObject<HoverButtonDragDelegate> -@property(nonatomic, copy) void (^dragHandler)(HoverButtonCocoa*, NSEvent*); -@end - -@implementation HoverButtonTestDragDelegate -@synthesize dragHandler = dragHandler_; - -- (void)dealloc { - [dragHandler_ release]; - [super dealloc]; -} - -- (void)beginDragFromHoverButton:(HoverButtonCocoa*)button - event:(NSEvent*)event { - dragHandler_(button, event); -} -@end - -namespace { - -class HoverButtonTest : public ui::CocoaTest { - public: - HoverButtonTest() { - NSRect frame = NSMakeRect(0, 0, 20, 20); - base::scoped_nsobject<TestHoverButton> button( - [[TestHoverButton alloc] initWithFrame:frame]); - button_ = button; - target_.reset([[HoverButtonTestTarget alloc] init]); - button_.target = target_; - button_.action = @selector(action:); - [[test_window() contentView] addSubview:button_]; - } - - protected: - void HoverAndExpect(CloseButtonHoverState hoverState) { - EXPECT_EQ(kHoverStateNone, button_.hoverState); - [button_ mouseEntered:cocoa_test_event_utils::EnterEvent()]; - EXPECT_EQ(hoverState, button_.hoverState); - [button_ mouseExited:cocoa_test_event_utils::ExitEvent()]; - EXPECT_EQ(kHoverStateNone, button_.hoverState); - } - - bool HandleMouseDown(NSEvent* mouseDownEvent) { - __block bool action_sent = false; - target_.get().actionHandler = ^(id sender) { - action_sent = true; - EXPECT_EQ(kHoverStateMouseDown, button_.hoverState); - }; - [NSApp sendEvent:mouseDownEvent]; - target_.get().actionHandler = nil; - return action_sent; - } - - TestHoverButton* button_; // Weak, owned by test_window(). - base::scoped_nsobject<HoverButtonTestTarget> target_; -}; - -TEST_VIEW(HoverButtonTest, button_) - -TEST_F(HoverButtonTest, Hover) { - EXPECT_EQ(kHoverStateNone, button_.hoverState); - - // Default - HoverAndExpect(kHoverStateMouseOver); - - // Tracking disabled - button_.trackingEnabled = NO; - HoverAndExpect(kHoverStateNone); - button_.trackingEnabled = YES; - - // Button disabled - button_.enabled = NO; - HoverAndExpect(kHoverStateNone); - button_.enabled = YES; - - // Back to normal - HoverAndExpect(kHoverStateMouseOver); -} - -TEST_F(HoverButtonTest, Click) { - EXPECT_EQ(kHoverStateNone, button_.hoverState); - const auto click = cocoa_test_event_utils::MouseClickInView(button_, 1); - - [NSApp postEvent:click.second atStart:YES]; - EXPECT_TRUE(HandleMouseDown(click.first)); - - button_.enabled = NO; - EXPECT_FALSE(HandleMouseDown(click.first)); - - EXPECT_EQ(kHoverStateNone, button_.hoverState); -} - -TEST_F(HoverButtonTest, CustomHitbox) { - NSRect hitbox = button_.frame; - hitbox.size.width += 10; - - NSPoint inside_hit_point = - NSMakePoint(NSMaxX(button_.frame) + 5, NSMidY(button_.frame)); - NSPoint outside_hit_point = - NSMakePoint(inside_hit_point.x + 10, inside_hit_point.y); - - { - NSRect trackingRect = button_.trackingAreas[0].rect; - EXPECT_FALSE(NSPointInRect(inside_hit_point, trackingRect)); - EXPECT_FALSE(NSPointInRect(outside_hit_point, trackingRect)); - EXPECT_NE(button_, [button_ hitTest:inside_hit_point]); - EXPECT_EQ(nil, [button_ hitTest:outside_hit_point]); - } - - button_.hitbox = hitbox; - { - NSRect trackingRect = button_.trackingAreas[0].rect; - EXPECT_TRUE(NSPointInRect(inside_hit_point, trackingRect)); - EXPECT_FALSE(NSPointInRect(outside_hit_point, trackingRect)); - EXPECT_EQ(button_, [button_ hitTest:inside_hit_point]); - EXPECT_EQ(nil, [button_ hitTest:outside_hit_point]); - } - - button_.hitbox = NSZeroRect; - { - NSRect trackingRect = button_.trackingAreas[0].rect; - EXPECT_FALSE(NSPointInRect(inside_hit_point, trackingRect)); - EXPECT_FALSE(NSPointInRect(outside_hit_point, trackingRect)); - EXPECT_NE(button_, [button_ hitTest:inside_hit_point]); - EXPECT_EQ(nil, [button_ hitTest:outside_hit_point]); - } -} - -TEST_F(HoverButtonTest, DragDelegate) { - base::scoped_nsobject<HoverButtonTestDragDelegate> dragDelegate( - [[HoverButtonTestDragDelegate alloc] init]); - - __block bool dragged = false; - dragDelegate.get().dragHandler = ^(HoverButtonCocoa* button, NSEvent* event) { - dragged = true; - }; - button_.dragDelegate = dragDelegate; - - const auto click = cocoa_test_event_utils::MouseClickInView(button_, 1); - NSPoint targetPoint = click.first.locationInWindow; - targetPoint.x += 5; // *Not* enough to trigger a drag. - [NSApp postEvent:cocoa_test_event_utils::MouseEventAtPointInWindow( - targetPoint, NSEventTypeLeftMouseDragged, - [button_ window], 1) - atStart:NO]; - [NSApp postEvent:click.second atStart:NO]; - EXPECT_TRUE(HandleMouseDown(click.first)); - EXPECT_FALSE(dragged); - - targetPoint.x += 1; // Now it's enough to trigger a drag. - [NSApp postEvent:cocoa_test_event_utils::MouseEventAtPointInWindow( - targetPoint, NSEventTypeLeftMouseDragged, - [button_ window], 1) - atStart:NO]; - [NSApp postEvent:click.second atStart:NO]; - EXPECT_FALSE(HandleMouseDown(click.first)); - EXPECT_TRUE(dragged); -} -} // namespace
diff --git a/ui/base/cocoa/hover_image_button.h b/ui/base/cocoa/hover_image_button.h deleted file mode 100644 index 789ecd6..0000000 --- a/ui/base/cocoa/hover_image_button.h +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright (c) 2011 The Chromium 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_BASE_COCOA_HOVER_IMAGE_BUTTON_H_ -#define UI_BASE_COCOA_HOVER_IMAGE_BUTTON_H_ - -#import <Cocoa/Cocoa.h> - -#import "base/mac/scoped_nsobject.h" -#import "ui/base/cocoa/hover_button.h" -#include "ui/base/ui_base_export.h" - -// A button that changes images when you hover over it and click it. -UI_BASE_EXPORT -@interface HoverImageButton : HoverButtonCocoa { - @private - base::scoped_nsobject<NSImage> defaultImage_; - base::scoped_nsobject<NSImage> hoverImage_; - base::scoped_nsobject<NSImage> pressedImage_; -} - -// Disables a click within the button from activating the application. -@property(nonatomic) BOOL disableActivationOnClick; - -// Sets the default image. -- (void)setDefaultImage:(NSImage*)image; - -// Sets the hover image. -- (void)setHoverImage:(NSImage*)image; - -// Sets the pressed image. -- (void)setPressedImage:(NSImage*)image; - -@end - -#endif // UI_BASE_COCOA_HOVER_IMAGE_BUTTON_H_
diff --git a/ui/base/cocoa/hover_image_button.mm b/ui/base/cocoa/hover_image_button.mm deleted file mode 100644 index 75eea36a..0000000 --- a/ui/base/cocoa/hover_image_button.mm +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ui/base/cocoa/hover_image_button.h" - -@implementation HoverImageButton - -@synthesize disableActivationOnClick = disableActivationOnClick_; - -- (void)drawRect:(NSRect)rect { - if (hoverState_ == kHoverStateMouseDown && pressedImage_) { - [super setImage:pressedImage_.get()]; - } else if (hoverState_ == kHoverStateMouseOver && hoverImage_) { - [super setImage:hoverImage_.get()]; - } else { - [super setImage:defaultImage_.get()]; - } - - [super drawRect:rect]; -} - -- (void)setDefaultImage:(NSImage*)image { - defaultImage_.reset([image retain]); -} - -- (void)setHoverImage:(NSImage*)image { - hoverImage_.reset([image retain]); -} - -- (void)setPressedImage:(NSImage*)image { - pressedImage_.reset([image retain]); -} - -- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent*)theEvent { - // To avoid activating the app on a click inside the button, first tell - // the Appkit not to immediately order the HoverImageButton's window front in - // response to theEvent. - return disableActivationOnClick_; -} - -- (void)mouseDown:(NSEvent*)mouseDownEvent { - // If disabling activation on click, tell the Appkit to cancel window ordering - // for this mouse down. - if (disableActivationOnClick_) { - [[NSApplication sharedApplication] preventWindowOrdering]; - } - - [super mouseDown:mouseDownEvent]; -} - -@end
diff --git a/ui/base/cocoa/hover_image_button_unittest.mm b/ui/base/cocoa/hover_image_button_unittest.mm deleted file mode 100644 index 8f6c19a0..0000000 --- a/ui/base/cocoa/hover_image_button_unittest.mm +++ /dev/null
@@ -1,48 +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. - -#import "ui/base/cocoa/hover_image_button.h" - -#import "base/mac/scoped_nsobject.h" -#import "ui/base/test/cocoa_helper.h" -#include "ui/events/test/cocoa_test_event_utils.h" - -namespace { - -class HoverImageButtonTest : public ui::CocoaTest { - public: - HoverImageButtonTest() { - NSRect content_frame = [[test_window() contentView] frame]; - base::scoped_nsobject<HoverImageButton> button( - [[HoverImageButton alloc] initWithFrame:content_frame]); - button_ = button.get(); - [[test_window() contentView] addSubview:button_]; - } - - void DrawRect() { - [button_ lockFocus]; - [button_ drawRect:[button_ bounds]]; - [button_ unlockFocus]; - } - - HoverImageButton* button_; -}; - -// Test mouse events. -TEST_F(HoverImageButtonTest, ImageSwap) { - NSImage* image = [NSImage imageNamed:NSImageNameStatusAvailable]; - NSImage* hover = [NSImage imageNamed:NSImageNameStatusNone]; - [button_ setDefaultImage:image]; - [button_ setHoverImage:hover]; - - [button_ mouseEntered:cocoa_test_event_utils::EnterEvent()]; - DrawRect(); - EXPECT_EQ([button_ image], hover); - [button_ mouseExited:cocoa_test_event_utils::ExitEvent()]; - DrawRect(); - EXPECT_NE([button_ image], hover); - EXPECT_EQ([button_ image], image); -} - -} // namespace
diff --git a/ui/base/resource/resource_bundle_unittest.cc b/ui/base/resource/resource_bundle_unittest.cc index 3a7cb25..cc3c0c7 100644 --- a/ui/base/resource/resource_bundle_unittest.cc +++ b/ui/base/resource/resource_bundle_unittest.cc
@@ -175,13 +175,7 @@ resource_bundle->AddDataPackFromPath(pack_path, pack_scale_factor); } -#if defined(OS_LINUX) -// Fails consistently on Linux: crbug.com/161902 -#define MAYBE_DelegateGetPathForLocalePack DISABLED_DelegateGetPathForLocalePack -#else -#define MAYBE_DelegateGetPathForLocalePack DelegateGetPathForLocalePack -#endif -TEST_F(ResourceBundleTest, MAYBE_DelegateGetPathForLocalePack) { +TEST_F(ResourceBundleTest, DelegateGetPathForLocalePack) { MockResourceBundleDelegate delegate; ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc index de311cb9..c6c7f5f5 100644 --- a/ui/compositor/layer_unittest.cc +++ b/ui/compositor/layer_unittest.cc
@@ -57,7 +57,6 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/codec/png_codec.h" #include "ui/gfx/font_list.h" -#include "ui/gfx/gfx_paths.h" #include "ui/gfx/interpolated_transform.h" #include "ui/gfx/skia_util.h" @@ -134,17 +133,20 @@ LayerWithRealCompositorTest() : scoped_task_environment_( base::test::ScopedTaskEnvironment::MainThreadType::UI) { - if (base::PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) { - test_data_directory_ = test_data_directory_.AppendASCII("compositor"); - } else { - LOG(ERROR) << "Could not open test data directory."; - } gfx::FontList::SetDefaultFontDescription("Arial, Times New Roman, 15px"); } ~LayerWithRealCompositorTest() override {} // Overridden from testing::Test: void SetUp() override { + ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir_)); + test_data_dir_ = test_data_dir_.Append(FILE_PATH_LITERAL("ui")) + .Append(FILE_PATH_LITERAL("gfx")) + .Append(FILE_PATH_LITERAL("test")) + .Append(FILE_PATH_LITERAL("data")) + .Append(FILE_PATH_LITERAL("compositor")); + ASSERT_TRUE(base::PathExists(test_data_dir_)); + bool enable_pixel_output = true; ui::ContextFactory* context_factory = nullptr; ui::ContextFactoryPrivate* context_factory_private = nullptr; @@ -245,9 +247,7 @@ gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height())); } - const base::FilePath& test_data_directory() const { - return test_data_directory_; - } + const base::FilePath& test_data_dir() const { return test_data_dir_; } private: class ReadbackHolder : public base::RefCountedThreadSafe<ReadbackHolder> { @@ -279,7 +279,7 @@ std::unique_ptr<TestCompositorHost> compositor_host_; // The root directory for test files. - base::FilePath test_data_directory_; + base::FilePath test_data_dir_; DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest); }; @@ -1526,10 +1526,8 @@ std::unique_ptr<Layer> l12( CreateColorLayer(SK_ColorBLUE, gfx::Rect(10, 10, 25, 25))); - base::FilePath ref_img1 = - test_data_directory().AppendASCII("ModifyHierarchy1.png"); - base::FilePath ref_img2 = - test_data_directory().AppendASCII("ModifyHierarchy2.png"); + base::FilePath ref_img1 = test_data_dir().AppendASCII("ModifyHierarchy1.png"); + base::FilePath ref_img2 = test_data_dir().AppendASCII("ModifyHierarchy2.png"); SkBitmap bitmap; l0->Add(l11.get()); @@ -1594,8 +1592,7 @@ ReadPixels(&bitmap); ASSERT_FALSE(bitmap.empty()); - base::FilePath ref_img = - test_data_directory().AppendASCII("string_faded.png"); + base::FilePath ref_img = test_data_dir().AppendASCII("string_faded.png"); // WritePNGFile(bitmap, ref_img, true); float percentage_pixels_large_error = 8.0f; // 200px / (50*50) @@ -1628,7 +1625,7 @@ std::unique_ptr<Layer> l11( CreateColorLayer(SK_ColorGREEN, gfx::Rect(0, 0, 25, 25))); - base::FilePath ref_img = test_data_directory().AppendASCII("Opacity.png"); + base::FilePath ref_img = test_data_dir().AppendASCII("Opacity.png"); l11->SetOpacity(0.75); l0->Add(l11.get());
diff --git a/ui/compositor/test/test_suite.cc b/ui/compositor/test/test_suite.cc index 29a9e92..b94b5ac 100644 --- a/ui/compositor/test/test_suite.cc +++ b/ui/compositor/test/test_suite.cc
@@ -9,7 +9,6 @@ #include "ui/compositor/compositor.h" #include "ui/compositor/compositor_switches.h" #include "ui/compositor/layer.h" -#include "ui/gfx/gfx_paths.h" #include "ui/gl/test/gl_surface_test_support.h" #if defined(USE_OZONE) @@ -44,8 +43,6 @@ OzonePlatform::InitializeForUI(params); #endif - gfx::RegisterPathProvider(); - #if defined(OS_WIN) display::win::SetDefaultDeviceScaleFactor(1.0f); #endif
diff --git a/ui/display/manager/display_manager.cc b/ui/display/manager/display_manager.cc index f75e7d1d..7a432bd3 100644 --- a/ui/display/manager/display_manager.cc +++ b/ui/display/manager/display_manager.cc
@@ -1366,7 +1366,8 @@ ReconfigureDisplays(); } -void DisplayManager::AddRemoveDisplay() { +void DisplayManager::AddRemoveDisplay( + ManagedDisplayInfo::ManagedDisplayModeList display_modes) { DCHECK(!active_display_list_.empty()); DisplayInfoList new_display_info_list; @@ -1377,13 +1378,33 @@ new_display_info_list.push_back(first_display); // Add if there is only one display connected. if (num_connected_displays() == 1) { + gfx::Rect host_bounds = first_display.bounds_in_native(); + if (display_modes.empty()) { + display_modes.emplace_back( + gfx::Size(600 /* width */, host_bounds.height()), + 60.0, /* refresh_rate */ + false /* is_interlaced */, true /* native */); + } + + // Find native display mode (or just the first one if there is no + // mode marked as native) and create a display with this mode as a default + const ManagedDisplayMode* native_display_mode = &(display_modes[0]); + for (const ManagedDisplayMode& display_mode : display_modes) { + if (display_mode.native()) { + native_display_mode = &display_mode; + break; + } + } + const int kVerticalOffsetPx = 100; // Layout the 2nd display below the primary as with the real device. - gfx::Rect host_bounds = first_display.bounds_in_native(); - new_display_info_list.push_back( - ManagedDisplayInfo::CreateFromSpec(base::StringPrintf( - "%d+%d-600x%d", host_bounds.x(), - host_bounds.bottom() + kVerticalOffsetPx, host_bounds.height()))); + ManagedDisplayInfo display = ManagedDisplayInfo::CreateFromSpec( + base::StringPrintf("%d+%d-%dx%d", host_bounds.x(), + host_bounds.bottom() + kVerticalOffsetPx, + native_display_mode->size().width(), + native_display_mode->size().height())); + display.SetManagedDisplayModes(std::move(display_modes)); + new_display_info_list.push_back(std::move(display)); } num_connected_displays_ = new_display_info_list.size(); ClearMirroringSourceAndDestination();
diff --git a/ui/display/manager/display_manager.h b/ui/display/manager/display_manager.h index 86c8115..6b24e337 100644 --- a/ui/display/manager/display_manager.h +++ b/ui/display/manager/display_manager.h
@@ -420,7 +420,8 @@ // Used to emulate display change when run in a desktop environment instead // of on a device. - void AddRemoveDisplay(); + void AddRemoveDisplay( + ManagedDisplayInfo::ManagedDisplayModeList display_modes = {}); void ToggleDisplayScaleFactor(); // SoftwareMirroringController override:
diff --git a/ui/display/util/BUILD.gn b/ui/display/util/BUILD.gn index 72203f7f..86f8f99 100644 --- a/ui/display/util/BUILD.gn +++ b/ui/display/util/BUILD.gn
@@ -41,6 +41,10 @@ } if (is_chromeos) { deps += [ "//ui/display/types" ] + } else if (is_mac) { + libs = [ + "IOSurface.framework", + ] } }
diff --git a/ui/file_manager/file_manager/background/js/background.js b/ui/file_manager/file_manager/background/js/background.js index 086eb56..fd81950d 100644 --- a/ui/file_manager/file_manager/background/js/background.js +++ b/ui/file_manager/file_manager/background/js/background.js
@@ -33,7 +33,7 @@ * * @type {!importer.HistoryLoader} */ - this.historyLoader = new importer.RuntimeHistoryLoader(this.tracker); + this.historyLoader = new importer.RuntimeHistoryLoader(); /** * Event handler for progress center.
diff --git a/ui/file_manager/file_manager/background/js/import_history.js b/ui/file_manager/file_manager/background/js/import_history.js index c3ea299..fbd6b9ff0 100644 --- a/ui/file_manager/file_manager/background/js/import_history.js +++ b/ui/file_manager/file_manager/background/js/import_history.js
@@ -495,9 +495,8 @@ * @struct * * @param {function(): !Promise<!Array<!FileEntry>>} filesProvider - * @param {!analytics.Tracker} tracker */ -importer.SynchronizedHistoryLoader = function(filesProvider, tracker) { +importer.SynchronizedHistoryLoader = function(filesProvider) { /** * @return {!Promise<!Array<!FileEntry>>} History files. Will always * have at least one file (the "primary file"). When other devices @@ -508,9 +507,6 @@ */ this.getHistoryFiles_ = filesProvider; - /** @private {!analytics.Tracker} */ - this.tracker_ = tracker; - /** @private {boolean} */ this.needsInitialization_ = true; @@ -523,25 +519,21 @@ if (this.needsInitialization_) { this.needsInitialization_ = false; this.getHistoryFiles_() - .then( - (/** - * @param {!Array<!FileEntry>} fileEntries - * @this {importer.SynchronizedHistoryLoader} - */ - function(fileEntries) { - var storage = new importer.FileBasedRecordStorage( - fileEntries, - this.tracker_); - var history = new importer.PersistentImportHistory( - importer.createMetadataHashcode, - storage); - new importer.DriveSyncWatcher(history); - history.whenReady().then( - (/** @this {importer.SynchronizedHistoryLoader} */ - function() { - this.historyResolver_.resolve(history); - }).bind(this)); - }).bind(this)) + .then((/** + * @param {!Array<!FileEntry>} fileEntries + * @this {importer.SynchronizedHistoryLoader} + */ + function(fileEntries) { + var storage = new importer.FileBasedRecordStorage(fileEntries); + var history = new importer.PersistentImportHistory( + importer.createMetadataHashcode, storage); + new importer.DriveSyncWatcher(history); + history.whenReady().then( + (/** @this {importer.SynchronizedHistoryLoader} */ + function() { + this.historyResolver_.resolve(history); + }).bind(this)); + }).bind(this)) .catch(importer.getLogger().catcher('history-load-chain')); } @@ -587,10 +579,8 @@ * @constructor * @implements {importer.RecordStorage} * @struct - * - * @param {!analytics.Tracker} tracker */ -importer.FileBasedRecordStorage = function(fileEntries, tracker) { +importer.FileBasedRecordStorage = function(fileEntries) { /** @private {!Array<!importer.PromisingFileEntry>} */ this.inputFiles_ = fileEntries.map( importer.PromisingFileEntry.create); @@ -598,9 +588,6 @@ /** @private {!importer.PromisingFileEntry} */ this.outputFile_ = this.inputFiles_[0]; - /** @private {!analytics.Tracker} */ - this.tracker_ = tracker; - /** * Serializes all writes and reads on the primary file. * @private {!Promise<?>} @@ -654,10 +641,6 @@ /** @override */ importer.FileBasedRecordStorage.prototype.readAll = function(recordCallback) { - var processTiming = this.tracker_.startTiming( - metrics.Categories.ACQUISITION, - metrics.timing.Variables.HISTORY_LOAD); - return this.latestOperation_ = this.latestOperation_ .then( (/** @@ -711,16 +694,6 @@ function(recordSet) { recordSet.forEach(recordCallback); }); - - processTiming.send(); - - var fileCount = this.inputFiles_.length; - this.tracker_.send( - metrics.ImportEvents.HISTORY_LOADED - .value(fileCount) - .dimension(fileCount === 1 - ? metrics.Dimensions.MACHINE_USE_SINGLE - : metrics.Dimensions.MACHINE_USE_MULTIPLE)); }).bind(this)) .catch(importer.getLogger().catcher('file-record-store-read-all')); }; @@ -949,16 +922,11 @@ * @constructor * @implements {importer.HistoryLoader} * @struct - * - * @param {!analytics.Tracker} tracker */ -importer.RuntimeHistoryLoader = function(tracker) { - +importer.RuntimeHistoryLoader = function() { /** @return {!importer.HistoryLoader} */ this.createRealHistoryLoader_ = function() { - return new importer.SynchronizedHistoryLoader( - importer.getHistoryFiles, - tracker); + return new importer.SynchronizedHistoryLoader(importer.getHistoryFiles); }; /** @private {boolean} */
diff --git a/ui/file_manager/file_manager/background/js/import_history_unittest.js b/ui/file_manager/file_manager/background/js/import_history_unittest.js index 8d6fdde..2a4dbdc 100644 --- a/ui/file_manager/file_manager/background/js/import_history_unittest.js +++ b/ui/file_manager/file_manager/background/js/import_history_unittest.js
@@ -365,12 +365,9 @@ */ function createRealStorage(fileNames) { var filePromises = fileNames.map(createFileEntry); - var tracker = new TestTracker(); - return Promise.all(filePromises) - .then( - function(fileEntries) { - return new importer.FileBasedRecordStorage(fileEntries, tracker); - }); + return Promise.all(filePromises).then(function(fileEntries) { + return new importer.FileBasedRecordStorage(fileEntries); + }); } /**
diff --git a/ui/file_manager/file_manager/common/js/BUILD.gn b/ui/file_manager/file_manager/common/js/BUILD.gn index 90f246d7..1457e31 100644 --- a/ui/file_manager/file_manager/common/js/BUILD.gn +++ b/ui/file_manager/file_manager/common/js/BUILD.gn
@@ -160,7 +160,8 @@ js_library("progress_center_common") { } -js_unittest("unittest_util") { +js_library("unittest_util") { + testonly = true # Only files app tests use this util file. visibility = [] visibility = [ "//ui/file_manager/file_manager/*" ]
diff --git a/ui/file_manager/file_manager/common/js/util.js b/ui/file_manager/file_manager/common/js/util.js index 61e20f26..224db0b 100644 --- a/ui/file_manager/file_manager/common/js/util.js +++ b/ui/file_manager/file_manager/common/js/util.js
@@ -528,24 +528,6 @@ }; /** - * Returns true if the board of the device matches the given prefix. Caution: - * There are cases in which the name of one board is a prefix for a different - * (only slightly related) board: E.g. daisy and daisy-spring, peach-pi and - * peach-pit, and maybe others. See also base::GetLsbReleaseBoard(). - * @param {string} boardPrefix The board prefix to match against. (ex. - * "x86-mario". Prefix is used as the actual board name comes with suffix - * like "x86-mario-something". - * @return {boolean} True if the board of the device matches the given prefix. - */ -util.boardIs = function(boardPrefix) { - // The board name should be lower-cased, but making it case-insensitive for - // backward compatibility just in case. - var board = str('CHROMEOS_RELEASE_BOARD'); - var pattern = new RegExp('^' + boardPrefix, 'i'); - return board.match(pattern) != null; -}; - -/** * Adds an isFocused method to the current window object. */ util.addIsFocusedMethod = function() {
diff --git a/ui/file_manager/file_manager/foreground/css/common.css b/ui/file_manager/file_manager/foreground/css/common.css index 02298d92..97fa9d4e 100644 --- a/ui/file_manager/file_manager/foreground/css/common.css +++ b/ui/file_manager/file_manager/foreground/css/common.css
@@ -143,7 +143,8 @@ padding: auto; } -.cr-dialog-buttons > button.cr-dialog-ok { +.cr-dialog-buttons > button.cr-dialog-ok, +.cr-dialog-buttons > button.cr-dialog-ok:hover { background-color: rgb(51, 103, 214); color: white; order: 1;
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css index 4ead24c7..aa0b973 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -381,9 +381,7 @@ } body.check-select #share-menu-button > .icon { - background-image: -webkit-image-set( - url(../images/files/ui/share.png) 1x, - url(../images/files/ui/2x/share.png) 2x); + background-image: url(../images/files/ui/share.svg); } #delete-button > .icon { @@ -393,9 +391,7 @@ } body.check-select #delete-button > .icon { - background-image: -webkit-image-set( - url(../images/files/ui/delete.png) 1x, - url(../images/files/ui/2x/delete.png) 2x); + background-image: url(../images/files/ui/delete.svg); } #view-button > .icon { @@ -445,9 +441,7 @@ } #selection-menu-button > .icon { - background-image: -webkit-image-set( - url(../images/files/ui/menu.png) 1x, - url(../images/files/ui/2x/menu.png) 2x); + background-image: url(../images/files/ui/menu.svg); } body:not(.check-select) #selection-menu-button {
diff --git a/ui/file_manager/file_manager/foreground/elements/files_quick_view.html b/ui/file_manager/file_manager/foreground/elements/files_quick_view.html index 0d3c2443..b581a8224 100644 --- a/ui/file_manager/file_manager/foreground/elements/files_quick_view.html +++ b/ui/file_manager/file_manager/foreground/elements/files_quick_view.html
@@ -64,7 +64,7 @@ <div class="no-preview">[[noPlaybackText]]</div> </template> <template is="dom-if" if="[[contentUrl]]"> - <files-safe-media type="video" class="content no-close-on-click" controls autoplay="[[autoplay]]" src="[[contentUrl]]" poster="[[videoPoster]]"></files-safe-media> + <files-safe-media tabindex="0" type="video" class="content no-close-on-click" controls autoplay="[[autoplay]]" src="[[contentUrl]]" poster="[[videoPoster]]"></files-safe-media> </template> </template> <!-- Audio --> @@ -72,7 +72,7 @@ <files-safe-media type="image" id="audio-artwork" class="no-close-on-click" src="[[audioArtwork]]" hidden="[[!audioArtwork]]"></files-safe-media> </template> <div> - <files-safe-media type="audio" class="no-close-on-click" autoplay="[[autoplay]]" controls src="[[audioUrl_(contentUrl, type)]]" hidden="[[!isAudio_(type)]]"></files-safe-media> + <files-safe-media tabindex="0" type="audio" class="no-close-on-click" controls autoplay="[[autoplay]]" src="[[audioUrl_(contentUrl, type)]]" hidden="[[!isAudio_(type)]]"></files-safe-media> </div> <template is="dom-if" if="[[isAudio_(type)]]"> <template is="dom-if" if="[[!contentUrl]]">
diff --git a/ui/file_manager/file_manager/foreground/elements/files_safe_audio_webview_content.css b/ui/file_manager/file_manager/foreground/elements/files_safe_audio_webview_content.css index 6ffd692..af80dfe 100644 --- a/ui/file_manager/file_manager/foreground/elements/files_safe_audio_webview_content.css +++ b/ui/file_manager/file_manager/foreground/elements/files_safe_audio_webview_content.css
@@ -29,6 +29,11 @@ display: none; } +#content:focus { + outline: 2px solid rgba(66, 133, 244, 0.5); + outline-offset: -2px; +} + audio::-webkit-media-controls-timeline, audio::-webkit-media-controls-mute-button, audio::-webkit-media-controls-play-button { @@ -38,3 +43,11 @@ audio::-webkit-media-controls-volume-slider { display: none; } + +audio:focus, +audio::-webkit-media-controls-timeline:focus, +audio::-webkit-media-controls-mute-button:focus, +audio::-webkit-media-controls-play-button:focus { + outline: 1px solid rgba(66, 133, 244, 0.5); + outline-offset: -1px; +}
diff --git a/ui/file_manager/file_manager/foreground/elements/files_safe_audio_webview_content.html b/ui/file_manager/file_manager/foreground/elements/files_safe_audio_webview_content.html index 7561fc24..4901fc1e 100644 --- a/ui/file_manager/file_manager/foreground/elements/files_safe_audio_webview_content.html +++ b/ui/file_manager/file_manager/foreground/elements/files_safe_audio_webview_content.html
@@ -9,7 +9,7 @@ <link rel="stylesheet" type="text/css" href="files_safe_audio_webview_content.css"> </head> <body> - <audio hidden id="content" controls autoplay></audio> + <audio hidden id="content" controls autoplay controlsList="nodownload"></audio> <script src="files_safe_media_webview_content.js"></script> </body> </html>
diff --git a/ui/file_manager/file_manager/foreground/elements/files_safe_media.js b/ui/file_manager/file_manager/foreground/elements/files_safe_media.js index 4c7f199..424c361 100644 --- a/ui/file_manager/file_manager/foreground/elements/files_safe_media.js +++ b/ui/file_manager/file_manager/foreground/elements/files_safe_media.js
@@ -81,6 +81,13 @@ }, ready: function() { + this.addEventListener('focus', (event) => { + if (this.type === 'audio' || this.type === 'video') + // Avoid setting the focus on the files-safe-media itself, rather sends + // it down to its webview element. + if (this.webview_) + this.webview_.focus(); + }); window.addEventListener('message', function(event) { if (event.origin !== FILES_APP_ORIGIN) { console.log('Unknown origin.');
diff --git a/ui/file_manager/file_manager/foreground/elements/files_safe_video_webview_content.css b/ui/file_manager/file_manager/foreground/elements/files_safe_video_webview_content.css index 3cd343d9..baf7f72a 100644 --- a/ui/file_manager/file_manager/foreground/elements/files_safe_video_webview_content.css +++ b/ui/file_manager/file_manager/foreground/elements/files_safe_video_webview_content.css
@@ -40,3 +40,11 @@ video::-webkit-media-controls-volume-slider { display: none; } + +video:focus, +video::-webkit-media-controls-timeline:focus, +video::-webkit-media-controls-mute-button:focus, +video::-webkit-media-controls-play-button:focus { + outline: 2px solid rgba(66, 133, 244, 0.5); + outline-offset: -2px; +}
diff --git a/ui/file_manager/file_manager/foreground/elements/files_safe_video_webview_content.html b/ui/file_manager/file_manager/foreground/elements/files_safe_video_webview_content.html index 25f8e47..4b7c79e 100644 --- a/ui/file_manager/file_manager/foreground/elements/files_safe_video_webview_content.html +++ b/ui/file_manager/file_manager/foreground/elements/files_safe_video_webview_content.html
@@ -9,8 +9,7 @@ <link rel="stylesheet" type="text/css" href="files_safe_video_webview_content.css"> </head> <body> - <video hidden id="content" muted autoplay controls controlsList="nodownload"> - </video> + <video hidden id="content" muted autoplay controls controlsList="nodownload" disablePictureInPicture></video> <script src="files_safe_media_webview_content.js"></script> </body> </html>
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/delete.svg b/ui/file_manager/file_manager/foreground/images/files/ui/delete.svg new file mode 100644 index 0000000..592fe133 --- /dev/null +++ b/ui/file_manager/file_manager/foreground/images/files/ui/delete.svg
@@ -0,0 +1,4 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewBox="0 0 24 24" fill="#616161"> + <path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/> + <path d="M0 0h24v24H0z" fill="none"/> +</svg>
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/menu.svg b/ui/file_manager/file_manager/foreground/images/files/ui/menu.svg new file mode 100644 index 0000000..c34b180f --- /dev/null +++ b/ui/file_manager/file_manager/foreground/images/files/ui/menu.svg
@@ -0,0 +1,4 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewBox="0 0 24 24" fill="#616161"> + <path d="M0 0h24v24H0z" fill="none"/> + <path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/> +</svg>
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/share.svg b/ui/file_manager/file_manager/foreground/images/files/ui/share.svg new file mode 100644 index 0000000..032ae7d --- /dev/null +++ b/ui/file_manager/file_manager/foreground/images/files/ui/share.svg
@@ -0,0 +1,4 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewBox="0 0 24 24" fill="#616161"> + <path d="M0 0h24v24H0z" fill="none"/> + <path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/> +</svg>
diff --git a/ui/file_manager/file_manager/foreground/js/actions_model.js b/ui/file_manager/file_manager/foreground/js/actions_model.js index 4cc4715..1a6bc3e9 100644 --- a/ui/file_manager/file_manager/foreground/js/actions_model.js +++ b/ui/file_manager/file_manager/foreground/js/actions_model.js
@@ -509,7 +509,8 @@ DriveManageAction.prototype.canExecute = function() { return this.volumeManager_.getDriveConnectionState().type !== VolumeManagerCommon.DriveConnectionType.OFFLINE && - !util.isTeamDriveRoot(this.entry_); + (loadTimeData.getBoolean('DRIVE_FS_ENABLED') || + !util.isTeamDriveRoot(this.entry_)); }; /**
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js index cb2ba78b..c6ea86c9 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -727,8 +727,7 @@ var locationInfo = fileManager.volumeManager.getLocationInfo(entry); event.canExecute = locationInfo && !locationInfo.isReadOnly && CommandUtil.hasCapability([entry], 'canAddChildren'); - event.command.setHidden( - CommandUtil.isRootEntry(fileManager.volumeManager, entry)); + event.command.setHidden(false); } else { var directoryModel = fileManager.directoryModel; var directoryEntry = fileManager.getCurrentDirectoryEntry(); @@ -775,6 +774,7 @@ * @param {!CommandHandlerDeps} fileManager CommandHandlerDeps to use. */ execute: function(event, fileManager) { + fileManager.directoryModel.getFileListSelection().setCheckSelectMode(true); fileManager.directoryModel.getFileListSelection().selectAll(); }, /** @@ -1504,7 +1504,7 @@ // flickering. if (actionsModel) { event.command.setHidden(actionsModel && !action); - event.command.checked = !!offlineNotNeededAction; + event.command.checked = !!offlineNotNeededAction && !saveForOfflineAction; } } });
diff --git a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js index d904d435..72d3d38 100644 --- a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js +++ b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
@@ -1242,6 +1242,12 @@ return; } + if (this.selectionHandler_.selection.entries.find(element => { + return util.isSameEntry(element, destinationEntry); + })) { + return; + } + // Add accept class if the domElement can accept the drag. domElement.classList.add('accepts'); this.destinationEntry_ = destinationEntry;
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/BUILD.gn b/ui/file_manager/file_manager/foreground/js/metadata/BUILD.gn index aefb4d3f..484fd96 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/BUILD.gn +++ b/ui/file_manager/file_manager/foreground/js/metadata/BUILD.gn
@@ -124,6 +124,13 @@ ] } +js_unittest("metadata_cache_item_unittest") { + deps = [ + ":metadata_cache_item", + "//ui/webui/resources/js:webui_resource_test", + ] +} + js_library("metadata_cache_set") { deps = [ ":metadata_cache_item", @@ -203,9 +210,19 @@ ] } +js_unittest("thumbnail_model_unittest") { + deps = [ + ":thumbnail_model", + "//ui/file_manager/base/js:test_error_reporting", + "//ui/webui/resources/js:webui_resource_test", + ] +} + js_unit_tests("unit_tests") { deps = [ ":image_orientation_unittest", + ":metadata_cache_item_unittest", + ":thumbnail_model_unittest", ] }
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item_unittest.html b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item_unittest.html deleted file mode 100644 index 2f9c70b..0000000 --- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item_unittest.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright 2015 The Chromium Authors. All rights reserved. - -- Use of this source code is governed by a BSD-style license that can be - -- found in the LICENSE file. - --> -<script src="../../../../../webui/resources/js/assert.js"></script> -<script src="../../../../base/js/test_error_reporting.js"></script> -<script src="metadata_cache_item.js"></script> -<script src="metadata_item.js"></script> -<script src="metadata_request.js"></script> - -<script src="metadata_cache_item_unittest.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item_unittest.js index e9801d60f..a52c457 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache_item_unittest.js
@@ -2,106 +2,135 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +/** + * @type {!MetadataItem} + */ +let metadataA = new MetadataItem(); +metadataA.contentMimeType = 'value'; + + function testMetadataCacheItemBasic() { var item = new MetadataCacheItem(); - var loadRequested = item.createRequests(['propertyA']); + var loadRequested = item.createRequests(['contentMimeType']); assertEquals(1, loadRequested.length); - assertEquals('propertyA', loadRequested[0]); + assertEquals('contentMimeType', loadRequested[0]); item.startRequests(1, loadRequested); - assertTrue(item.storeProperties(1, {propertyA: 'value'})); + assertTrue(item.storeProperties(1, metadataA)); - var result = item.get(['propertyA']); - assertEquals('value', result.propertyA); + var result = item.get(['contentMimeType']); + assertEquals('value', result.contentMimeType); } function testMetadataCacheItemAvoidDoubleLoad() { var item = new MetadataCacheItem(); - item.startRequests(1, ['propertyA']); - var loadRequested = item.createRequests(['propertyA']); + item.startRequests(1, ['contentMimeType']); + var loadRequested = item.createRequests(['contentMimeType']); assertEquals(0, loadRequested.length); item.startRequests(2, loadRequested); - assertTrue(item.storeProperties(1, {propertyA: 'value'})); + assertTrue(item.storeProperties(1, metadataA)); - var result = item.get(['propertyA']); - assertEquals('value', result.propertyA); + var result = item.get(['contentMimeType']); + assertEquals('value', result.contentMimeType); } function testMetadataCacheItemInvalidate() { var item = new MetadataCacheItem(); - item.startRequests(1, item.createRequests(['propertyA'])); + item.startRequests(1, item.createRequests(['contentMimeType'])); item.invalidate(2); - assertFalse(item.storeProperties(1, {propertyA: 'value'})); + assertFalse(item.storeProperties(1, metadataA)); - var loadRequested = item.createRequests(['propertyA']); + var loadRequested = item.createRequests(['contentMimeType']); assertEquals(1, loadRequested.length); } function testMetadataCacheItemStoreInReverseOrder() { var item = new MetadataCacheItem(); - item.startRequests(1, item.createRequests(['propertyA'])); - item.startRequests(2, item.createRequests(['propertyA'])); + item.startRequests(1, item.createRequests(['contentMimeType'])); + item.startRequests(2, item.createRequests(['contentMimeType'])); - assertTrue(item.storeProperties(2, {propertyA: 'value2'})); - assertFalse(item.storeProperties(1, {propertyA: 'value1'})); + let metadataB = new MetadataItem(); + metadataB.contentMimeType = 'value2'; - var result = item.get(['propertyA']); - assertEquals('value2', result.propertyA); + assertTrue(item.storeProperties(2, metadataB)); + assertFalse(item.storeProperties(1, metadataA)); + + var result = item.get(['contentMimeType']); + assertEquals('value2', result.contentMimeType); } function testMetadataCacheItemClone() { var itemA = new MetadataCacheItem(); - itemA.startRequests(1, itemA.createRequests(['property'])); + itemA.startRequests(1, itemA.createRequests(['contentMimeType'])); var itemB = itemA.clone(); - itemA.storeProperties(1, {property: 'value'}); - assertFalse(itemB.hasFreshCache(['property'])); + itemA.storeProperties(1, metadataA); + assertFalse(itemB.hasFreshCache(['contentMimeType'])); - itemB.storeProperties(1, {property: 'value'}); - assertTrue(itemB.hasFreshCache(['property'])); + itemB.storeProperties(1, metadataA); + assertTrue(itemB.hasFreshCache(['contentMimeType'])); itemA.invalidate(2); - assertTrue(itemB.hasFreshCache(['property'])); + assertTrue(itemB.hasFreshCache(['contentMimeType'])); } function testMetadataCacheItemHasFreshCache() { var item = new MetadataCacheItem(); - assertFalse(item.hasFreshCache(['propertyA', 'propertyB'])); + assertFalse(item.hasFreshCache(['contentMimeType', 'externalFileUrl'])); - item.startRequests(1, item.createRequests(['propertyA', 'propertyB'])); - item.storeProperties(1, {propertyA: 'valueA', propertyB: 'valueB'}); - assertTrue(item.hasFreshCache(['propertyA', 'propertyB'])); + item.startRequests( + 1, item.createRequests(['contentMimeType', 'externalFileUrl'])); + + let metadata = new MetadataItem(); + metadata.contentMimeType = 'mime'; + metadata.externalFileUrl = 'url'; + + item.storeProperties(1, metadata); + assertTrue(item.hasFreshCache(['contentMimeType', 'externalFileUrl'])); item.invalidate(2); - assertFalse(item.hasFreshCache(['propertyA', 'propertyB'])); + assertFalse(item.hasFreshCache(['contentMimeType', 'externalFileUrl'])); - item.startRequests(1, item.createRequests(['propertyA'])); - item.storeProperties(1, {propertyA: 'valueA'}); - assertFalse(item.hasFreshCache(['propertyA', 'propertyB'])); - assertTrue(item.hasFreshCache(['propertyA'])); + item.startRequests(1, item.createRequests(['contentMimeType'])); + item.storeProperties(1, metadataA); + assertFalse(item.hasFreshCache(['contentMimeType', 'externalFileUrl'])); + assertTrue(item.hasFreshCache(['contentMimeType'])); } function testMetadataCacheItemShouldNotUpdateBeforeInvalidation() { var item = new MetadataCacheItem(); - item.startRequests(1, item.createRequests(['property'])); - item.storeProperties(1, {property: 'value1'}); - item.storeProperties(2, {property: 'value2'}); - assertEquals('value1', item.get(['property']).property); + item.startRequests(1, item.createRequests(['contentMimeType'])); + item.storeProperties(1, metadataA); + + let metadataB = new MetadataItem(); + metadataB.contentMimeType = 'value2'; + + item.storeProperties(2, metadataB); + assertEquals('value', item.get(['contentMimeType']).contentMimeType); } function testMetadataCacheItemError() { var item = new MetadataCacheItem(); - item.startRequests(1, item.createRequests(['property'])); - item.storeProperties( - 1, {property: 'value1', propertyError: new Error('Error')}); - assertEquals(undefined, item.get(['property']).property); - assertEquals('Error', item.get(['property']).propertyError.message); + item.startRequests(1, item.createRequests(['contentThumbnailUrl'])); + + let metadataWithError = new MetadataItem(); + metadataWithError.contentThumbnailUrlError = new Error('Error'); + + item.storeProperties(1, metadataWithError); + let property = item.get(['contentThumbnailUrl']); + assertEquals(undefined, property.contentThumbnailUrl); + assertEquals('Error', property.contentThumbnailUrlError.message); } function testMetadataCacheItemErrorShouldNotFetchedDirectly() { var item = new MetadataCacheItem(); - item.startRequests(1, item.createRequests(['property'])); - item.storeProperties( - 1, {property: 'value1', propertyError: new Error('Error')}); - assertThrows(function() { item.get(['propertyError']); }); + item.startRequests(1, item.createRequests(['contentThumbnailUrl'])); + + let metadataWithError = new MetadataItem(); + metadataWithError.contentThumbnailUrlError = new Error('Error'); + + item.storeProperties(1, metadataWithError); + assertThrows(function() { + item.get(['contentThumbnailUrlError']); + }); }
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/thumbnail_model_unittest.html b/ui/file_manager/file_manager/foreground/js/metadata/thumbnail_model_unittest.html deleted file mode 100644 index e655b9a4..0000000 --- a/ui/file_manager/file_manager/foreground/js/metadata/thumbnail_model_unittest.html +++ /dev/null
@@ -1,11 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright 2015 The Chromium Authors. All rights reserved. - -- Use of this source code is governed by a BSD-style license that can be - -- found in the LICENSE file. - --> -<script src="../../../common/js/file_type.js"></script> -<script src="../../../../base/js/test_error_reporting.js"></script> -<script src="metadata_item.js"></script> -<script src="thumbnail_model.js"></script> - -<script src="thumbnail_model_unittest.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/thumbnail_model_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/thumbnail_model_unittest.js index 61a33be..ffc1e6a 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/thumbnail_model_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/thumbnail_model_unittest.js
@@ -12,6 +12,18 @@ toURL: function() { return 'filesystem://B'; } }; +const contentThumbnailTransform = { + scaleX: 0, + scaleY: 0, + rotate90: 0, +}; + +const imageTransformation = { + scaleX: 1, + scaleY: 1, + rotate90: 2, +}; + var metadata; var contentMetadata; var thumbnailModel; @@ -23,18 +35,19 @@ metadata.thumbnailUrl = 'EXTERNAL_THUMBNAIL_URL'; metadata.customIconUrl = 'CUSTOM_ICON_URL'; metadata.contentThumbnailUrl = 'CONTENT_THUMBNAIL_URL'; - metadata.contentThumbnailTransform = 'CONTENT_THUMBNAIL_TRANSFORM'; - metadata.contentImageTransform = 'CONTENT_IMAGE_TRANSFORM'; + metadata.contentThumbnailTransform = contentThumbnailTransform; + metadata.contentImageTransform = imageTransformation; - thumbnailModel = new ThumbnailModel({ - get: function(entries, names) { - var result = new MetadataItem(); - for (var i = 0; i < names.length; i++) { - var name = names[i]; - result[name] = metadata[name]; - } - return Promise.resolve([result]); - }}); + thumbnailModel = new ThumbnailModel(/** @type {!MetadataModel} */ ({ + get: function(entries, names) { + var result = new MetadataItem(); + for (var i = 0; i < names.length; i++) { + var name = names[i]; + result[name] = metadata[name]; + } + return Promise.resolve([result]); + } + })); } function testThumbnailModelGetBasic(callback) { @@ -47,8 +60,8 @@ assertEquals('CUSTOM_ICON_URL', results[0].external.customIconUrl); assertTrue(results[0].external.present); assertEquals('CONTENT_THUMBNAIL_URL', results[0].thumbnail.url); - assertEquals('CONTENT_THUMBNAIL_TRANSFORM', results[0].thumbnail.transform); - assertEquals('CONTENT_IMAGE_TRANSFORM', results[0].media.imageTransform); + assertEquals(contentThumbnailTransform, results[0].thumbnail.transform); + assertEquals(imageTransformation, results[0].media.imageTransform); }), callback); }
diff --git a/ui/file_manager/file_manager/foreground/js/ui/actions_submenu.js b/ui/file_manager/file_manager/foreground/js/ui/actions_submenu.js index 147a74bb..9d7b869 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/actions_submenu.js +++ b/ui/file_manager/file_manager/foreground/js/ui/actions_submenu.js
@@ -79,19 +79,6 @@ util.queryDecoratedElement('#manage-in-drive', cr.ui.Command) .canExecuteChange(); - // Managing shortcuts is shown just before custom actions. - var createFolderShortcutAction = remainingActions[ - ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT]; - if (createFolderShortcutAction) { - var menuItem = this.addMenuItem_({}); - menuItem.command = '#create-folder-shortcut'; - delete remainingActions[ - ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT - ]; - } - util.queryDecoratedElement( - '#create-folder-shortcut', cr.ui.Command).canExecuteChange(); - // Removing shortcuts is not rendered in the submenu to keep the previous // behavior. Shortcuts can be removed in the left nav using the roots menu. // TODO(mtomasz): Consider rendering the menu item here for consistency.
diff --git a/ui/file_manager/file_manager/foreground/js/ui/actions_submenu_unittest.js b/ui/file_manager/file_manager/foreground/js/ui/actions_submenu_unittest.js index aeafb10..e3cb79d 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/actions_submenu_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/ui/actions_submenu_unittest.js
@@ -11,8 +11,6 @@ <command id="share" label="Share"></command> <command id="manage-in-drive" i18n-values="Manage in Drive"></command> <command id="toggle-pinned" label="Toggle pinned"></command> - <command id="create-folder-shortcut" label="Create folder shortcut"> - </command> <command id="remove-folder-shortcut" label="Remove folder shortcut"> </command>
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 1082e47..1b9ce35 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/banners.js +++ b/ui/file_manager/file_manager/foreground/js/ui/banners.js
@@ -240,8 +240,6 @@ var more; if (this.usePromoWelcomeBanner_) { var welcomeTitle = str('DRIVE_WELCOME_TITLE_ALTERNATIVE'); - if (util.boardIs('link')) - welcomeTitle = str('DRIVE_WELCOME_TITLE_ALTERNATIVE_1TB'); title.textContent = welcomeTitle; more = util.createChild(links, '', 'a'); more.href = str('GOOGLE_DRIVE_REDEEM_URL'); @@ -388,15 +386,9 @@ this.usePromoWelcomeBanner_ = false; } - // Choose the offer basing on the board name. The default one is 100 GB. var offerSize = 100; // In GB. var offerServiceId = 'drive.cros.echo.1'; - if (util.boardIs('link')) { - offerSize = 1024; // 1 TB. - offerServiceId = 'drive.cros.echo.2'; - } - // Perform asynchronous tasks in parallel. var group = new AsyncUtil.Group();
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js index a7e5a47..afafae2 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js +++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
@@ -659,9 +659,12 @@ } } else { const rootType = location.rootType || null; - const iconName = - directorytree.getIconOverrides(rootType, dirEntry) || 'folder'; - icon.setAttribute('file-type-icon', iconName); + const iconOverride = directorytree.getIconOverrides(rootType, dirEntry); + // Add Downloads icon as volume so current test code passes with + // MyFilesVolume flag enabled and disabled. + if (iconOverride) + icon.setAttribute('volume-type-icon', iconOverride); + icon.setAttribute('file-type-icon', iconOverride || 'folder'); item.updateSharedStatusIcon(); } @@ -991,9 +994,15 @@ ejectButton.addEventListener('mouseup', (event) => { event.stopPropagation(); }); + ejectButton.addEventListener('up', (event) => { + event.stopPropagation(); + }); ejectButton.addEventListener('mousedown', (event) => { event.stopPropagation(); }); + ejectButton.addEventListener('down', (event) => { + event.stopPropagation(); + }); ejectButton.className = 'root-eject'; ejectButton.setAttribute('aria-label', str('UNMOUNT_DEVICE_BUTTON_LABEL')); ejectButton.setAttribute('tabindex', '0');
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js index b355a43d..e531020d 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js
@@ -460,6 +460,7 @@ // Ctrl/Meta+A if (sm.multiple && e.keyCode == 65 && (cr.isMac && e.metaKey || !cr.isMac && e.ctrlKey)) { + sm.setCheckSelectMode(true); sm.selectAll(); e.preventDefault(); return;
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html index a8ffabc..e302729 100644 --- a/ui/file_manager/file_manager/main.html +++ b/ui/file_manager/file_manager/main.html
@@ -212,6 +212,7 @@ <hr visibleif="full-page"> <cr-menu-item command="#get-info"></cr-menu-item> <cr-menu-item command="#rename"></cr-menu-item> + <cr-menu-item command="#create-folder-shortcut"></cr-menu-item> <cr-menu-item command="#delete" i18n-content="DELETE_BUTTON_LABEL" class="hide-on-toolbar"></cr-menu-item> <cr-menu-item command="#zip-selection"></cr-menu-item> @@ -234,13 +235,13 @@ <cr-menu id="directory-tree-context-menu" class="chrome-menu files-menu" menu-item-selector="cr-menu-item,hr"> - <cr-menu-item command="#create-folder-shortcut"></cr-menu-item> <cr-menu-item command="#cut" visibleif="full-page"></cr-menu-item> <cr-menu-item command="#copy" visibleif="full-page"></cr-menu-item> <cr-menu-item command="#paste-into-folder" visibleif="full-page"></cr-menu-item> <cr-menu-item command="#share-with-linux"></cr-menu-item> <hr visibleif="full-page"> <cr-menu-item command="#rename"></cr-menu-item> + <cr-menu-item command="#create-folder-shortcut"></cr-menu-item> <cr-menu-item command="#delete" i18n-content="DELETE_BUTTON_LABEL"></cr-menu-item> <hr visibleif="saveas-file full-page"> <cr-menu-item command="#new-folder" visibleif="saveas-file full-page"></cr-menu-item> @@ -361,7 +362,7 @@ <div id="search-box"> <cr-input type="search" tabindex="14" hidden i18n-values="aria-label:SEARCH_TEXT_LABEL;placeholder:SEARCH_TEXT_LABEL"> - <span class="clear" slot="suffix"></span> + <span class="clear" slot="suffix" tabindex="14"></span> </cr-input> </div> <button id="refresh-button" class="icon-button menu-button" tabindex="15" hidden @@ -541,7 +542,7 @@ </div> <div id="drag-container"></div> <files-tooltip></files-tooltip> - <files-quick-view id="quick-view" + <files-quick-view tabindex="-1" id="quick-view" i18n-values="no-playback-text:QUICK_VIEW_NO_PLAYBACK_AVAILABLE;no-preview-text:QUICK_VIEW_NO_PREVIEW_AVAILABLE"> </files-quick-view> <iframe id="command-dispatcher" hidden aria-hidden="true"></iframe>
diff --git a/ui/file_manager/file_manager/test/check_select.js b/ui/file_manager/file_manager/test/check_select.js index cb63d8e..a9d218b 100644 --- a/ui/file_manager/file_manager/test/check_select.js +++ b/ui/file_manager/file_manager/test/check_select.js
@@ -48,3 +48,56 @@ done(); }); }; + +checkselect.testCheckSelectModeAfterSelectAllOneFile = (done) => { + const gearMenu = document.querySelector('#gear-menu'); + const cancel = document.querySelector('#cancel-selection-button-wrapper'); + const selectAll = + '#gear-menu:not([hidden]) #gear-menu-select-all:not([hidden])'; + + // Load a single file. + test.setupAndWaitUntilReady([test.ENTRIES.hello]) + .then(() => { + // Click gear menu, ensure 'Select all' is shown. + assertTrue(test.fakeMouseClick('#gear-button')); + return test.waitForElement(selectAll); + }) + .then(result => { + // Click 'Select all', gear menu now replaced with file context menu. + assertTrue(test.fakeMouseClick('#gear-menu-select-all')); + return test.repeatUntil(() => { + return getComputedStyle(gearMenu).opacity == 0 && + getComputedStyle(cancel).display == 'block' || + test.pending('waiting for check select mode'); + }); + }) + .then(result => { + // Cancel selection, ensure no items selected. + assertTrue(test.fakeMouseClick('#cancel-selection-button')); + return test.repeatUntil(() => { + return document.querySelectorAll('#file-list li[selected]').length == + 0 || + test.pending('waiting for no files selected'); + }); + }) + .then(result => { + // 'Ctrl+a' to select all. + assertTrue(test.fakeKeyDown('#file-list', 'a', true, false, false)); + return test.repeatUntil(() => { + return getComputedStyle(cancel).display == 'block' || + test.pending('waiting for check select mode'); + }); + }) + .then(result => { + // Cancel selection, ensure no items selected. + assertTrue(test.fakeMouseClick('#cancel-selection-button')); + return test.repeatUntil(() => { + return document.querySelectorAll('#file-list li[selected]').length == + 0 || + test.pending('waiting for no files selected'); + }); + }) + .then(result => { + done(); + }); +}; \ No newline at end of file
diff --git a/ui/file_manager/file_manager/test/js/strings.js b/ui/file_manager/file_manager/test/js/strings.js index 3f42618..644117f 100644 --- a/ui/file_manager/file_manager/test/js/strings.js +++ b/ui/file_manager/file_manager/test/js/strings.js
@@ -9,7 +9,6 @@ // Extend with additional fields not found in grdp files. Object.setPrototypeOf(loadTimeData.data_, { - 'CHROMEOS_RELEASE_BOARD': 'unknown', 'CROSTINI_FILES_ENABLED': true, 'DRIVE_FS_ENABLED': false, 'GOOGLE_DRIVE_REDEEM_URL': 'http://www.google.com/intl/en/chrome/devices' +
diff --git a/ui/file_manager/integration_tests/file_manager/gear_menu.js b/ui/file_manager/integration_tests/file_manager/gear_menu.js index 5c2e3c9f..99eb8264 100644 --- a/ui/file_manager/integration_tests/file_manager/gear_menu.js +++ b/ui/file_manager/integration_tests/file_manager/gear_menu.js
@@ -789,3 +789,48 @@ }, ]); }; + +/** + * Tests that new folder appears in the gear menu with Downloads focused in the + * directory tree. + */ +testcase.newFolderInDownloads = function() { + var appId; + StepsRunner.run([ + function() { + setupAndWaitUntilReady(null, RootPath.DOWNLOADS, null, [ENTRIES.hello], [ + ]).then(this.next); + }, + // Focus the directory tree. + function(results) { + appId = results.windowId; + + remoteCall.callRemoteTestUtil('focus', appId, ['#directory-tree']) + .then(this.next); + }, + // Open the gear menu. + function() { + remoteCall.waitForElement(appId, '#gear-button').then(this.next); + }, + // Open the gear meny by a shortcut (Alt-E). + function() { + remoteCall.fakeKeyDown(appId, 'body', 'e', false, false, true) + .then(this.next); + }, + // Wait for menu to appear. + function(result) { + chrome.test.assertTrue(result); + remoteCall.waitForElement(appId, '#gear-menu').then(this.next); + }, + // Wait for menu to appear, containing new folder. + function(result) { + remoteCall + .waitForElement( + appId, '#gear-menu-newfolder:not([disabled]):not([hidden])') + .then(this.next); + }, + function() { + checkIfNoErrorsOccured(this.next); + } + ]); +};
diff --git a/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js b/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js index 2d141e43..f30664f4 100644 --- a/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js +++ b/ui/file_manager/integration_tests/file_manager/share_and_manage_dialog.js
@@ -117,18 +117,20 @@ // Navigate to the specified team drive if one is specified. function(results) { appId = results.windowId; - if (!teamDrive) { + if (teamDrive === undefined) { this.next(); return; } remoteCall .navigateWithDirectoryTree( - appId, `/team_drives/${teamDrive}`, 'Team Drives', 'drive') + appId, + teamDrive === '' ? '/team_drives' : `/team_drives/${teamDrive}`, + 'Team Drives', 'drive') .then(this.next); }, // Wait for the file list to update if we navigated. function() { - if (!teamDrive) { + if (teamDrive === undefined) { this.next(); return; } @@ -349,3 +351,11 @@ manageWithDriveExpectBrowserURL( 'teamDriveAHostedDoc.gdoc', URL, 'Team Drive A'); }; + +/** + * Tests managing a team drive. + */ +testcase.manageTeamDrive = function() { + const URL = 'https://folder_alternate_link/Team%20Drive%20A'; + manageWithDriveExpectBrowserURL('Team Drive A', URL, ''); +};
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index 285a8aa..27796002 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -86,8 +86,6 @@ "font_render_params_win.cc", "gdi_util.cc", "gdi_util.h", - "gfx_paths.cc", - "gfx_paths.h", "half_float.cc", "half_float.h", "icon_util.cc",
diff --git a/ui/gfx/gfx_paths.cc b/ui/gfx/gfx_paths.cc deleted file mode 100644 index ba387ad..0000000 --- a/ui/gfx/gfx_paths.cc +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright (c) 2011 The Chromium 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/gfx/gfx_paths.h" - -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/path_service.h" - -namespace gfx { - -bool PathProvider(int key, base::FilePath* result) { - base::FilePath cur; - switch (key) { - // The following are only valid in the development environment, and - // will fail if executed from an installed executable (because the - // generated path won't exist). - case DIR_TEST_DATA: - if (!base::PathService::Get(base::DIR_SOURCE_ROOT, &cur)) - return false; - cur = cur.Append(FILE_PATH_LITERAL("ui")); - cur = cur.Append(FILE_PATH_LITERAL("gfx")); - cur = cur.Append(FILE_PATH_LITERAL("test")); - cur = cur.Append(FILE_PATH_LITERAL("data")); - if (!base::PathExists(cur)) // we don't want to create this - return false; - break; - default: - return false; - } - - *result = cur; - return true; -} - -// This cannot be done as a static initializer sadly since Visual Studio will -// eliminate this object file if there is no direct entry point into it. -void RegisterPathProvider() { - base::PathService::RegisterProvider(PathProvider, PATH_START, PATH_END); -} - -} // namespace gfx
diff --git a/ui/gfx/gfx_paths.h b/ui/gfx/gfx_paths.h deleted file mode 100644 index 7a779edb..0000000 --- a/ui/gfx/gfx_paths.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright (c) 2011 The Chromium 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_GFX_GFX_PATHS_H_ -#define UI_GFX_GFX_PATHS_H_ - -#include "ui/gfx/gfx_export.h" - -// This file declares path keys for the app module. These can be used with -// the PathService to access various special directories and files. - -namespace gfx { - -enum { - PATH_START = 2000, - - // Valid only in development environment; TODO(darin): move these - DIR_TEST_DATA, // Directory where unit test data resides. - - PATH_END -}; - -// Call once to register the provider for the path keys defined above. -GFX_EXPORT void RegisterPathProvider(); - -} // namespace gfx - -#endif // UI_GFX_GFX_PATHS_H_
diff --git a/ui/gfx/icon_util_unittest.cc b/ui/gfx/icon_util_unittest.cc index d257713..a9c73c4 100644 --- a/ui/gfx/icon_util_unittest.cc +++ b/ui/gfx/icon_util_unittest.cc
@@ -15,15 +15,14 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/geometry/size.h" -#include "ui/gfx/gfx_paths.h" #include "ui/gfx/icon_util_unittests_resource.h" #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_family.h" namespace { -static const char kSmallIconName[] = "icon_util/16_X_16_icon.ico"; -static const char kLargeIconName[] = "icon_util/128_X_128_icon.ico"; +static const char kSmallIconName[] = "16_X_16_icon.ico"; +static const char kLargeIconName[] = "128_X_128_icon.ico"; static const char kTempIconFilename[] = "temp_test_icon.ico"; } // namespace @@ -33,9 +32,14 @@ using ScopedHICON = base::win::ScopedHICON; void SetUp() override { - gfx::RegisterPathProvider(); - ASSERT_TRUE( - base::PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)); + ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir_)); + test_data_dir_ = test_data_dir_.Append(FILE_PATH_LITERAL("ui")) + .Append(FILE_PATH_LITERAL("gfx")) + .Append(FILE_PATH_LITERAL("test")) + .Append(FILE_PATH_LITERAL("data")) + .Append(FILE_PATH_LITERAL("icon_util")); + ASSERT_TRUE(base::PathExists(test_data_dir_)); + ASSERT_TRUE(temp_directory_.CreateUniqueTempDir()); } @@ -74,7 +78,7 @@ protected: // The root directory for test files. This should be treated as read-only. - base::FilePath test_data_directory_; + base::FilePath test_data_dir_; // Directory for creating files by this test. base::ScopedTempDir temp_directory_; @@ -145,8 +149,7 @@ // The following test case makes sure IconUtil::SkBitmapFromHICON fails // gracefully when called with invalid input parameters. TEST_F(IconUtilTest, TestIconToBitmapInvalidParameters) { - base::FilePath icon_filename = - test_data_directory_.AppendASCII(kSmallIconName); + base::FilePath icon_filename = test_data_dir_.AppendASCII(kSmallIconName); gfx::Size icon_size(kSmallIconWidth, kSmallIconHeight); ScopedHICON icon( LoadIconFromFile(icon_filename, icon_size.width(), icon_size.height())); @@ -270,8 +273,8 @@ // This test case makes sure that when we load an icon from disk and convert // the HICON into a bitmap, the bitmap has the expected format and dimensions. TEST_F(IconUtilTest, TestCreateSkBitmapFromHICON) { - base::FilePath small_icon_filename = test_data_directory_.AppendASCII( - kSmallIconName); + base::FilePath small_icon_filename = + test_data_dir_.AppendASCII(kSmallIconName); gfx::Size small_icon_size(kSmallIconWidth, kSmallIconHeight); ScopedHICON small_icon(LoadIconFromFile( small_icon_filename, small_icon_size.width(), small_icon_size.height())); @@ -283,8 +286,8 @@ EXPECT_EQ(bitmap.height(), small_icon_size.height()); EXPECT_EQ(bitmap.colorType(), kN32_SkColorType); - base::FilePath large_icon_filename = test_data_directory_.AppendASCII( - kLargeIconName); + base::FilePath large_icon_filename = + test_data_dir_.AppendASCII(kLargeIconName); gfx::Size large_icon_size(kLargeIconWidth, kLargeIconHeight); ScopedHICON large_icon(LoadIconFromFile( large_icon_filename, large_icon_size.width(), large_icon_size.height()));
diff --git a/ui/gfx/text_elider_unittest.cc b/ui/gfx/text_elider_unittest.cc index 1ceab0ae..43852b6a 100644 --- a/ui/gfx/text_elider_unittest.cc +++ b/ui/gfx/text_elider_unittest.cc
@@ -58,15 +58,7 @@ } // namespace -// TODO(crbug.com/546240): This test fails on iOS because iOS version of -// GetStringWidthF that calls [NSString sizeWithFont] returns the rounded string -// width. -#if defined(OS_IOS) -#define MAYBE_ElideEmail DISABLED_ElideEmail -#else -#define MAYBE_ElideEmail ElideEmail -#endif -TEST(TextEliderTest, MAYBE_ElideEmail) { +TEST(TextEliderTest, ElideEmail) { const std::string kEllipsisStr(kEllipsis); // Test emails and their expected elided forms (from which the available @@ -147,15 +139,7 @@ } } -// TODO(crbug.com/546240): This test fails on iOS because iOS version of -// GetStringWidthF that calls [NSString sizeWithFont] returns the rounded string -// width. -#if defined(OS_IOS) -#define MAYBE_TestFilenameEliding DISABLED_TestFilenameEliding -#else -#define MAYBE_TestFilenameEliding TestFilenameEliding -#endif -TEST(TextEliderTest, MAYBE_TestFilenameEliding) { +TEST(TextEliderTest, TestFilenameEliding) { const std::string kEllipsisStr(kEllipsis); const base::FilePath::StringType kPathSeparator = base::FilePath::StringType().append(1, base::FilePath::kSeparators[0]);
diff --git a/ui/gfx/text_utils_ios.mm b/ui/gfx/text_utils_ios.mm index 0fdf2ae..0794043 100644 --- a/ui/gfx/text_utils_ios.mm +++ b/ui/gfx/text_utils_ios.mm
@@ -10,7 +10,6 @@ #include "base/strings/sys_string_conversions.h" #include "ui/gfx/font_list.h" -#include "ui/gfx/ios/NSString+CrStringDrawing.h" namespace gfx { @@ -25,7 +24,8 @@ Typesetter typesetter) { NSString* ns_text = base::SysUTF16ToNSString(text); NativeFont native_font = font_list.GetPrimaryFont().GetNativeFont(); - return [ns_text cr_sizeWithFont:native_font].width; + NSDictionary* attributes = @{NSFontAttributeName : native_font}; + return [ns_text sizeWithAttributes:attributes].width; } } // namespace gfx
diff --git a/ui/message_center/BUILD.gn b/ui/message_center/BUILD.gn index 782d175..ee5189f 100644 --- a/ui/message_center/BUILD.gn +++ b/ui/message_center/BUILD.gn
@@ -62,14 +62,6 @@ "//build/config/compiler:no_size_t_to_int_warning", ] sources = [ - "cocoa/notification_controller.h", - "cocoa/notification_controller.mm", - "cocoa/opaque_views.h", - "cocoa/opaque_views.mm", - "cocoa/popup_collection.h", - "cocoa/popup_collection.mm", - "cocoa/popup_controller.h", - "cocoa/popup_controller.mm", "lock_screen/empty_lock_screen_controller.cc", "lock_screen/empty_lock_screen_controller.h", "lock_screen/lock_screen_controller.h", @@ -103,13 +95,6 @@ ] } - if (is_mac) { - libs = [ - "AppKit.framework", - "Foundation.framework", - ] - } - if (toolkit_views) { sources += [ "views/bounded_label.cc", @@ -193,9 +178,6 @@ test("message_center_unittests") { sources = [ - "cocoa/notification_controller_unittest.mm", - "cocoa/popup_collection_unittest.mm", - "cocoa/popup_controller_unittest.mm", "lock_screen/fake_lock_screen_controller.cc", "lock_screen/fake_lock_screen_controller.h", "message_center_impl_unittest.cc", @@ -242,10 +224,6 @@ ] } - if (is_mac) { - deps += [ "//ui/gfx:test_support" ] - } - if (toolkit_views) { sources += [ "views/bounded_label_unittest.cc",
diff --git a/ui/message_center/cocoa/notification_controller.h b/ui/message_center/cocoa/notification_controller.h deleted file mode 100644 index ef214f1..0000000 --- a/ui/message_center/cocoa/notification_controller.h +++ /dev/null
@@ -1,119 +0,0 @@ -// Copyright (c) 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 UI_MESSAGE_CENTER_COCOA_NOTIFICATION_CONTROLLER_H_ -#define UI_MESSAGE_CENTER_COCOA_NOTIFICATION_CONTROLLER_H_ - -#import <Cocoa/Cocoa.h> - -#include <string> - -#import "base/mac/scoped_nsobject.h" -#include "ui/message_center/message_center_export.h" - -namespace message_center { -class MessageCenter; -class Notification; -} - -@class HoverImageButton; - -namespace message_center { -// A struct that can hold all the temporary frames -// created when adjusting a view -struct NotificationLayoutParams { - NSRect rootFrame; - NSRect titleFrame; - NSRect messageFrame; - NSRect contextMessageFrame; - NSRect settingsButtonFrame; - NSRect listFrame; - NSRect progressBarFrame; -}; -} - -// The base view controller class for notifications. A notification at minimum -// has an image, title, body, and close button. This controller can be used as -// the content for both a popup bubble and a view in the notification tray. -MESSAGE_CENTER_EXPORT -@interface MCNotificationController : NSViewController { - @protected - // The message object. Weak. - const message_center::Notification* notification_; - - // A copy of the notification ID. - std::string notificationID_; - - // Controller of the notifications, where action messages are forwarded. Weak. - message_center::MessageCenter* messageCenter_; - - // The button that invokes |-close:|, in the upper-right corner. - base::scoped_nsobject<HoverImageButton> closeButton_; - - // The button that invokes |-settingsClicked:|, in the bottom right corner of - // the context message. - base::scoped_nsobject<HoverImageButton> settingsButton_; - - // The small icon associated with the notification, on the bottom right. - base::scoped_nsobject<NSImageView> smallImage_; - - // The large icon associated with the notification, on the left side. - base::scoped_nsobject<NSImageView> icon_; - - // The title of the message. - base::scoped_nsobject<NSTextView> title_; - - // Body text of the message. Hidden for list notifications. - base::scoped_nsobject<NSTextView> message_; - - // Context-giving text of the message. Alternate font used to distinguish it. - base::scoped_nsobject<NSTextView> contextMessage_; - - // Container for optional list view that contains multiple items. - base::scoped_nsobject<NSView> listView_; - - // Container for optional progress bar view. - base::scoped_nsobject<NSProgressIndicator> progressBarView_; - - // Container for optional items at the bottom of the notification. - base::scoped_nsobject<NSView> bottomView_; -} - -// Creates a new controller for a given notification. -- (id)initWithNotification:(const message_center::Notification*)notification - messageCenter:(message_center::MessageCenter*)messageCenter; - -// If the model object changes, this method will update the views to reflect -// the new model object. Returns the updated frame of the notification. -- (NSRect)updateNotification:(const message_center::Notification*)notification; - -// Action for clicking on the notification's |closeButton_|. -- (void)close:(id)sender; - -// Action for clicking on the notification's |settingsButton_|. -- (void)settingsClicked:(id)sender; - -// Accessor for the notification. -- (const message_center::Notification*)notification; - -// Gets the notification ID. This string is owned by the NotificationController -// rather than the model object, so it's safe to use after the Notification has -// been deleted. -- (const std::string&)notificationID; - -// Called when the user clicks within the notification view. -- (void)notificationClicked; - -// Adjust the position and height of all the internal frames by |delta|. -- (void)adjustFrameHeight:(message_center::NotificationLayoutParams*)frames - delta:(CGFloat)delta; - -@end - -@interface MCNotificationController (TestingInterface) -- (NSImageView*)smallImageView; -- (NSImageView*)iconView; -@end - -#endif // UI_MESSAGE_CENTER_COCOA_NOTIFICATION_CONTROLLER_H_
diff --git a/ui/message_center/cocoa/notification_controller.mm b/ui/message_center/cocoa/notification_controller.mm deleted file mode 100644 index 38cb370..0000000 --- a/ui/message_center/cocoa/notification_controller.mm +++ /dev/null
@@ -1,995 +0,0 @@ -// Copyright (c) 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. - -#import "ui/message_center/cocoa/notification_controller.h" - -#include <stddef.h> - -#include <algorithm> - -#include "base/mac/foundation_util.h" -#include "base/strings/string_util.h" -#include "base/strings/sys_string_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "components/url_formatter/elide_url.h" -#include "skia/ext/skia_utils_mac.h" -#import "ui/base/cocoa/hover_image_button.h" -#include "ui/base/l10n/l10n_util_mac.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/font_list.h" -#include "ui/gfx/text_elider.h" -#include "ui/gfx/text_utils.h" -#include "ui/message_center/message_center.h" -#include "ui/message_center/message_center_style.h" -#include "ui/message_center/public/cpp/message_center_constants.h" -#include "ui/message_center/public/cpp/notification.h" -#include "ui/resources/grit/ui_resources.h" -#include "ui/strings/grit/ui_strings.h" -#include "url/gurl.h" - -@interface MCNotificationProgressBar : NSProgressIndicator -@end - -@implementation MCNotificationProgressBar -- (void)drawRect:(NSRect)dirtyRect { - NSRect sliceRect, remainderRect; - double progressFraction = ([self doubleValue] - [self minValue]) / - ([self maxValue] - [self minValue]); - NSDivideRect(dirtyRect, &sliceRect, &remainderRect, - NSWidth(dirtyRect) * progressFraction, NSMinXEdge); - - NSBezierPath* path = [NSBezierPath bezierPathWithRoundedRect:dirtyRect - xRadius:message_center::kProgressBarCornerRadius - yRadius:message_center::kProgressBarCornerRadius]; - [skia::SkColorToCalibratedNSColor(message_center::kProgressBarBackgroundColor) - set]; - [path fill]; - - if (progressFraction == 0.0) - return; - - path = [NSBezierPath bezierPathWithRoundedRect:sliceRect - xRadius:message_center::kProgressBarCornerRadius - yRadius:message_center::kProgressBarCornerRadius]; - [skia::SkColorToCalibratedNSColor(message_center::kProgressBarSliceColor) - set]; - [path fill]; -} - -- (id)accessibilityAttributeValue:(NSString*)attribute { - double progressValue = 0.0; - if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) { - progressValue = [self doubleValue]; - } else if ([attribute isEqualToString:NSAccessibilityMinValueAttribute]) { - progressValue = [self minValue]; - } else if ([attribute isEqualToString:NSAccessibilityMaxValueAttribute]) { - progressValue = [self maxValue]; - } else { - return [super accessibilityAttributeValue:attribute]; - } - - return [NSString stringWithFormat:@"%lf", progressValue]; -} -@end - -//////////////////////////////////////////////////////////////////////////////// -@interface MCNotificationButton : NSButton -@end - -@implementation MCNotificationButton -// drawRect: needs to fill the button with a background, otherwise we don't get -// subpixel antialiasing. -- (void)drawRect:(NSRect)dirtyRect { - NSColor* color = skia::SkColorToCalibratedNSColor( - message_center::kNotificationBackgroundColor); - [color set]; - NSRectFill(dirtyRect); - [super drawRect:dirtyRect]; -} -@end - -@interface MCNotificationButtonCell : NSButtonCell { - BOOL hovered_; -} -@end - -//////////////////////////////////////////////////////////////////////////////// -@implementation MCNotificationButtonCell -- (BOOL)isOpaque { - return YES; -} - -- (void)drawBezelWithFrame:(NSRect)frame inView:(NSView*)controlView { - // Else mouseEntered: and mouseExited: won't be called and hovered_ won't be - // valid. - DCHECK([self showsBorderOnlyWhileMouseInside]); - - if (!hovered_) - return; - [skia::SkColorToCalibratedNSColor( - message_center::kHoveredButtonBackgroundColor) set]; - NSRectFill(frame); -} - -- (void)drawImage:(NSImage*)image - withFrame:(NSRect)frame - inView:(NSView*)controlView { - if (!image) - return; - NSRect rect = NSMakeRect(message_center::kButtonHorizontalPadding, - message_center::kButtonIconTopPadding, - message_center::kNotificationButtonIconSize, - message_center::kNotificationButtonIconSize); - [image drawInRect:rect - fromRect:NSZeroRect - operation:NSCompositeSourceOver - fraction:1.0 - respectFlipped:YES - hints:nil]; -} - -- (NSRect)drawTitle:(NSAttributedString*)title - withFrame:(NSRect)frame - inView:(NSView*)controlView { - CGFloat offsetX = message_center::kButtonHorizontalPadding; - if ([base::mac::ObjCCastStrict<NSButton>(controlView) image]) { - offsetX += message_center::kNotificationButtonIconSize + - message_center::kButtonIconToTitlePadding; - } - frame.origin.x = offsetX; - frame.size.width -= offsetX; - - NSDictionary* attributes = @{ - NSFontAttributeName : - [title attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL], - NSForegroundColorAttributeName : - skia::SkColorToCalibratedNSColor(message_center::kRegularTextColor), - }; - [[title string] drawWithRect:frame - options:(NSStringDrawingUsesLineFragmentOrigin | - NSStringDrawingTruncatesLastVisibleLine) - attributes:attributes]; - return frame; -} - -- (void)mouseEntered:(NSEvent*)event { - hovered_ = YES; - - // Else the cell won't be repainted on hover. - [super mouseEntered:event]; -} - -- (void)mouseExited:(NSEvent*)event { - hovered_ = NO; - [super mouseExited:event]; -} -@end - -//////////////////////////////////////////////////////////////////////////////// - -@interface MCNotificationView : NSBox { - @private - MCNotificationController* controller_; -} - -- (id)initWithController:(MCNotificationController*)controller - frame:(NSRect)frame; -@end - -@implementation MCNotificationView -- (id)initWithController:(MCNotificationController*)controller - frame:(NSRect)frame { - if ((self = [super initWithFrame:frame])) - controller_ = controller; - return self; -} - -- (void)mouseUp:(NSEvent*)event { - if (event.type != NSLeftMouseUp) { - [super mouseUp:event]; - return; - } - if (NSPointInRect([self convertPoint:event.locationInWindow fromView:nil], - self.bounds)) { - [controller_ notificationClicked]; - } -} - -- (NSView*)hitTest:(NSPoint)point { - // Route the mouse click events on NSTextView to the container view. - NSView* hitView = [super hitTest:point]; - if (hitView) - return [hitView isKindOfClass:[NSTextView class]] ? self : hitView; - return nil; -} - -- (BOOL)accessibilityIsIgnored { - return NO; -} - -- (NSArray*)accessibilityActionNames { - return @[ NSAccessibilityPressAction ]; -} - -- (void)accessibilityPerformAction:(NSString*)action { - if ([action isEqualToString:NSAccessibilityPressAction]) { - [controller_ notificationClicked]; - return; - } - [super accessibilityPerformAction:action]; -} -@end - -//////////////////////////////////////////////////////////////////////////////// - -@interface AccessibilityIgnoredBox : NSBox -@end - -// Ignore this element, but expose its children to accessibility. -@implementation AccessibilityIgnoredBox -- (BOOL)accessibilityIsIgnored { - return YES; -} - -// Pretend this element has no children. -// TODO(petewil): Until we have alt text available, we will hide the children of -// the box also. Remove this override once alt text is set (by using -// NSAccessibilityDescriptionAttribute). -- (id)accessibilityAttributeValue:(NSString*)attribute { - // If we get a request for NSAccessibilityChildrenAttribute, return an empty - // array to pretend we have no children. - if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) - return @[]; - else - return [super accessibilityAttributeValue:attribute]; -} -@end - -//////////////////////////////////////////////////////////////////////////////// - -@interface MCNotificationController (Private) -// Configures a NSBox to be borderless, titleless, and otherwise appearance- -// free. -- (void)configureCustomBox:(NSBox*)box; - -// Initializes the icon_ ivar and returns the view to insert into the hierarchy. -- (NSView*)createIconView; - -// Creates a box that shows a border when the icon is not big enough to fill the -// space. -- (NSBox*)createImageBox:(const gfx::Image&)notificationImage; - -// Initializes the closeButton_ ivar with the configured button. -- (void)configureCloseButtonInFrame:(NSRect)rootFrame; - -// Initializes the settingsButton_ ivar with the configured button. -- (void)configureSettingsButtonInFrame:(NSRect)rootFrame; - -// Creates the smallImage_ ivar with the appropriate frame. -- (NSView*)createSmallImageInFrame:(NSRect)rootFrame; - -// Initializes title_ in the given frame. -- (void)configureTitleInFrame:(NSRect)rootFrame; - -// Initializes message_ in the given frame. -- (void)configureBodyInFrame:(NSRect)rootFrame; - -// Initializes contextMessage_ in the given frame. -- (void)configureContextMessageInFrame:(NSRect)rootFrame; - -// Creates a NSTextView that the caller owns configured as a label in a -// notification. -- (NSTextView*)newLabelWithFrame:(NSRect)frame; - -// Gets the rectangle in which notification content should be placed. This -// rectangle is to the right of the icon and left of the control buttons. -// This depends on the icon_ and closeButton_ being initialized. -- (NSRect)currentContentRect; - -// Returns the wrapped text that could fit within the content rect with not -// more than the given number of lines. The wrapped text would be painted using -// the given font. The Ellipsis could be added at the end of the last line if -// it is too long. Outputs the number of lines computed in the actualLines -// parameter. -- (base::string16)wrapText:(const base::string16&)text - forFont:(NSFont*)font - maxNumberOfLines:(size_t)lines - actualLines:(size_t*)actualLines; - -// Same as above without outputting the lines formatted. -- (base::string16)wrapText:(const base::string16&)text - forFont:(NSFont*)font - maxNumberOfLines:(size_t)lines; - -@end - -//////////////////////////////////////////////////////////////////////////////// - -@implementation MCNotificationController - -- (id)initWithNotification:(const message_center::Notification*)notification - messageCenter:(message_center::MessageCenter*)messageCenter { - if ((self = [super initWithNibName:nil bundle:nil])) { - notification_ = notification; - notificationID_ = notification_->id(); - messageCenter_ = messageCenter; - } - return self; -} - -- (void)loadView { - // Create the root view of the notification. - NSRect rootFrame = NSMakeRect(0, 0, - message_center::kNotificationPreferredImageWidth, - message_center::kNotificationIconSize); - base::scoped_nsobject<MCNotificationView> rootView( - [[MCNotificationView alloc] initWithController:self frame:rootFrame]); - [self configureCustomBox:rootView]; - [rootView setFillColor:skia::SkColorToCalibratedNSColor( - message_center::kNotificationBackgroundColor)]; - [self setView:rootView]; - - [rootView addSubview:[self createIconView]]; - - // Create the close button. - [self configureCloseButtonInFrame:rootFrame]; - [rootView addSubview:closeButton_]; - - // Create the small image. - [rootView addSubview:[self createSmallImageInFrame:rootFrame]]; - - // Create the settings button. - if (notification_->should_show_settings_button()) { - [self configureSettingsButtonInFrame:rootFrame]; - [rootView addSubview:settingsButton_]; - } - - NSRect contentFrame = [self currentContentRect]; - - // Create the title. - [self configureTitleInFrame:contentFrame]; - [rootView addSubview:title_]; - - // Create the message body. - [self configureBodyInFrame:contentFrame]; - [rootView addSubview:message_]; - - // Create the context message body. - [self configureContextMessageInFrame:contentFrame]; - [rootView addSubview:contextMessage_]; - - // Populate the data. - [self updateNotification:notification_]; -} - -- (NSRect)updateNotification:(const message_center::Notification*)notification { - DCHECK_EQ(notification->id(), notificationID_); - notification_ = notification; - - message_center::NotificationLayoutParams layoutParams; - layoutParams.rootFrame = - NSMakeRect(0, 0, message_center::kNotificationPreferredImageWidth, - message_center::kNotificationIconSize); - - [smallImage_ setImage:notification_->small_image().AsNSImage()]; - - // Update the icon. - [icon_ setImage:notification_->icon().AsNSImage()]; - - // The message_center:: constants are relative to capHeight at the top and - // relative to the baseline at the bottom, but NSTextField uses the full line - // height for its height. - CGFloat titleTopGap = - roundf([[title_ font] ascender] - [[title_ font] capHeight]); - CGFloat titleBottomGap = roundf(fabs([[title_ font] descender])); - CGFloat titlePadding = message_center::kTextTopPadding - titleTopGap; - - CGFloat messageTopGap = - roundf([[message_ font] ascender] - [[message_ font] capHeight]); - CGFloat messageBottomGap = roundf(fabs([[message_ font] descender])); - CGFloat messagePadding = - message_center::kTextTopPadding - titleBottomGap - messageTopGap; - - CGFloat contextMessageTopGap = roundf( - [[contextMessage_ font] ascender] - [[contextMessage_ font] capHeight]); - CGFloat contextMessagePadding = - message_center::kTextTopPadding - messageBottomGap - contextMessageTopGap; - - // Set the title and recalculate the frame. - size_t actualTitleLines = 0; - [title_ setString:base::SysUTF16ToNSString([self - wrapText:notification_->title() - forFont:[title_ font] - maxNumberOfLines:message_center::kMaxTitleLines - actualLines:&actualTitleLines])]; - [title_ sizeToFit]; - layoutParams.titleFrame = [title_ frame]; - layoutParams.titleFrame.origin.y = NSMaxY(layoutParams.rootFrame) - - titlePadding - - NSHeight(layoutParams.titleFrame); - - // The number of message lines depends on the number of context message lines - // and the lines within the title, and whether an image exists. - int messageLineLimit = message_center::kMessageExpandedLineLimit; - if (actualTitleLines > 1) - messageLineLimit -= (actualTitleLines - 1) * 2; - if (!notification_->image().IsEmpty()) { - messageLineLimit /= 2; - - if (!notification_->context_message().empty() && - !notification_->UseOriginAsContextMessage()) - messageLineLimit -= message_center::kContextMessageLineLimit; - } - if (messageLineLimit < 0) - messageLineLimit = 0; - - // Set the message and recalculate the frame. - [message_ setString:base::SysUTF16ToNSString( - [self wrapText:notification_->message() - forFont:[message_ font] - maxNumberOfLines:messageLineLimit])]; - [message_ sizeToFit]; - layoutParams.messageFrame = [message_ frame]; - - // If there are list items, then the message_ view should not be displayed. - const std::vector<message_center::NotificationItem>& items = - notification->items(); - // If there are list items, don't show the main message. Also if the message - // is empty, mark it as hidden and set 0 height, so it doesn't take up any - // space (size to fit leaves it 15 px tall. - if (items.size() > 0 || notification_->message().empty()) { - [message_ setHidden:YES]; - layoutParams.messageFrame.origin.y = layoutParams.titleFrame.origin.y; - layoutParams.messageFrame.size.height = 0; - } else { - [message_ setHidden:NO]; - layoutParams.messageFrame.origin.y = NSMinY(layoutParams.titleFrame) - - messagePadding - - NSHeight(layoutParams.messageFrame); - layoutParams.messageFrame.size.height = NSHeight([message_ frame]); - } - - // Set the context message and recalculate the frame. - base::string16 message; - if (notification->UseOriginAsContextMessage()) { - gfx::FontList font_list((gfx::Font([message_ font]))); - message = url_formatter::ElideHost(notification->origin_url(), font_list, - message_center::kContextMessageViewWidth, - gfx::Typesetter::NATIVE); - } else { - message = notification->context_message(); - } - - base::string16 elided = - [self wrapText:message - forFont:[contextMessage_ font] - maxNumberOfLines:message_center::kContextMessageLineLimit]; - [contextMessage_ setString:base::SysUTF16ToNSString(elided)]; - [contextMessage_ sizeToFit]; - - layoutParams.contextMessageFrame = [contextMessage_ frame]; - - if (notification->context_message().empty() && - !notification->UseOriginAsContextMessage()) { - [contextMessage_ setHidden:YES]; - layoutParams.contextMessageFrame.origin.y = - layoutParams.messageFrame.origin.y; - layoutParams.contextMessageFrame.size.height = 0; - } else { - [contextMessage_ setHidden:NO]; - - // If the context message is used as a domain make sure it's placed at the - // bottom of the top section. - CGFloat contextMessageY = NSMinY(layoutParams.messageFrame) - - contextMessagePadding - - NSHeight(layoutParams.contextMessageFrame); - layoutParams.contextMessageFrame.origin.y = - notification->UseOriginAsContextMessage() - ? std::min(NSMinY([icon_ frame]) + contextMessagePadding, - contextMessageY) - : contextMessageY; - layoutParams.contextMessageFrame.size.height = - NSHeight([contextMessage_ frame]); - } - - // Calculate the settings button position. It is dependent on whether the - // context message aligns or not with the icon. - layoutParams.settingsButtonFrame = [settingsButton_ frame]; - layoutParams.settingsButtonFrame.origin.y = - MIN(NSMinY([icon_ frame]) + message_center::kSmallImagePadding, - NSMinY(layoutParams.contextMessageFrame)); - - // Create the list item views (up to a maximum). - [listView_ removeFromSuperview]; - layoutParams.listFrame = NSZeroRect; - if (items.size() > 0) { - layoutParams.listFrame = [self currentContentRect]; - layoutParams.listFrame.origin.y = 0; - layoutParams.listFrame.size.height = 0; - listView_.reset([[NSView alloc] initWithFrame:layoutParams.listFrame]); - [listView_ accessibilitySetOverrideValue:NSAccessibilityListRole - forAttribute:NSAccessibilityRoleAttribute]; - [listView_ - accessibilitySetOverrideValue:NSAccessibilityContentListSubrole - forAttribute:NSAccessibilitySubroleAttribute]; - CGFloat y = 0; - - NSFont* font = [NSFont systemFontOfSize:message_center::kMessageFontSize]; - CGFloat lineHeight = roundf(NSHeight([font boundingRectForFont])); - - const int kNumNotifications = - std::min(items.size(), message_center::kNotificationMaximumItems); - for (int i = kNumNotifications - 1; i >= 0; --i) { - NSTextView* itemView = [self - newLabelWithFrame:NSMakeRect(0, y, NSWidth(layoutParams.listFrame), - lineHeight)]; - [itemView setFont:font]; - - // Disable the word-wrap in order to show the text in single line. - [[itemView textContainer] setContainerSize:NSMakeSize(FLT_MAX, FLT_MAX)]; - [[itemView textContainer] setWidthTracksTextView:NO]; - - // Construct the text from the title and message. - base::string16 text = - items[i].title + base::UTF8ToUTF16(" ") + items[i].message; - base::string16 ellidedText = - [self wrapText:text forFont:font maxNumberOfLines:1]; - [itemView setString:base::SysUTF16ToNSString(ellidedText)]; - - // Use dim color for the title part. - NSColor* titleColor = - skia::SkColorToCalibratedNSColor(message_center::kRegularTextColor); - NSRange titleRange = NSMakeRange( - 0, - std::min(ellidedText.size(), items[i].title.size())); - [itemView setTextColor:titleColor range:titleRange]; - - // Use dim color for the message part if it has not been truncated. - if (ellidedText.size() > items[i].title.size() + 1) { - NSColor* messageColor = - skia::SkColorToCalibratedNSColor(message_center::kDimTextColor); - NSRange messageRange = NSMakeRange( - items[i].title.size() + 1, - ellidedText.size() - items[i].title.size() - 1); - [itemView setTextColor:messageColor range:messageRange]; - } - - [listView_ addSubview:itemView]; - y += lineHeight; - } - // TODO(thakis): The spacing is not completely right. - CGFloat listTopPadding = - message_center::kTextTopPadding - contextMessageTopGap; - layoutParams.listFrame.size.height = y; - layoutParams.listFrame.origin.y = NSMinY(layoutParams.contextMessageFrame) - - listTopPadding - - NSHeight(layoutParams.listFrame); - [listView_ setFrame:layoutParams.listFrame]; - [[self view] addSubview:listView_]; - } - - // Create the progress bar view if needed. - [progressBarView_ removeFromSuperview]; - layoutParams.progressBarFrame = NSZeroRect; - if (notification->type() == message_center::NOTIFICATION_TYPE_PROGRESS) { - layoutParams.progressBarFrame = [self currentContentRect]; - layoutParams.progressBarFrame.origin.y = - NSMinY(layoutParams.contextMessageFrame) - - message_center::kProgressBarTopPadding - - message_center::kProgressBarThickness; - layoutParams.progressBarFrame.size.height = - message_center::kProgressBarThickness; - progressBarView_.reset([[MCNotificationProgressBar alloc] - initWithFrame:layoutParams.progressBarFrame]); - // Setting indeterminate to NO does not work with custom drawRect. - [progressBarView_ setIndeterminate:YES]; - [progressBarView_ setStyle:NSProgressIndicatorBarStyle]; - [progressBarView_ setDoubleValue:notification->progress()]; - [[self view] addSubview:progressBarView_]; - } - - // If the bottom-most element so far is out of the rootView's bounds, resize - // the view. - CGFloat minY = NSMinY(layoutParams.contextMessageFrame); - if (listView_ && NSMinY(layoutParams.listFrame) < minY) - minY = NSMinY(layoutParams.listFrame); - if (progressBarView_ && NSMinY(layoutParams.progressBarFrame) < minY) - minY = NSMinY(layoutParams.progressBarFrame); - if (minY < messagePadding) { - CGFloat delta = messagePadding - minY; - [self adjustFrameHeight:&layoutParams delta:delta]; - } - - // Add the bottom container view. - NSRect frame = layoutParams.rootFrame; - frame.size.height = 0; - [bottomView_ removeFromSuperview]; - bottomView_.reset([[NSView alloc] initWithFrame:frame]); - CGFloat y = 0; - - // Create action buttons if appropriate, bottom-up. - std::vector<message_center::ButtonInfo> buttons = notification->buttons(); - for (int i = buttons.size() - 1; i >= 0; --i) { - message_center::ButtonInfo buttonInfo = buttons[i]; - NSRect buttonFrame = frame; - buttonFrame.origin = NSMakePoint(0, y); - buttonFrame.size.height = message_center::kButtonHeight; - base::scoped_nsobject<MCNotificationButton> button( - [[MCNotificationButton alloc] initWithFrame:buttonFrame]); - base::scoped_nsobject<MCNotificationButtonCell> cell( - [[MCNotificationButtonCell alloc] - initTextCell:base::SysUTF16ToNSString(buttonInfo.title)]); - [cell setShowsBorderOnlyWhileMouseInside:YES]; - [button setCell:cell]; - [button setImage:buttonInfo.icon.AsNSImage()]; - [button setBezelStyle:NSSmallSquareBezelStyle]; - [button setImagePosition:NSImageLeft]; - [button setTag:i]; - [button setTarget:self]; - [button setAction:@selector(buttonClicked:)]; - y += NSHeight(buttonFrame); - frame.size.height += NSHeight(buttonFrame); - [bottomView_ addSubview:button]; - - NSRect separatorFrame = frame; - separatorFrame.origin = NSMakePoint(0, y); - separatorFrame.size.height = 1; - base::scoped_nsobject<NSBox> separator( - [[AccessibilityIgnoredBox alloc] initWithFrame:separatorFrame]); - [self configureCustomBox:separator]; - [separator setFillColor:skia::SkColorToCalibratedNSColor( - message_center::kButtonSeparatorColor)]; - y += NSHeight(separatorFrame); - frame.size.height += NSHeight(separatorFrame); - [bottomView_ addSubview:separator]; - } - - // Create the image view if appropriate. - gfx::Image notificationImage = notification->image(); - if (!notificationImage.IsEmpty()) { - NSBox* imageBox = [self createImageBox:notificationImage]; - NSRect outerFrame = frame; - outerFrame.origin = NSMakePoint(0, y); - outerFrame.size = [imageBox frame].size; - [imageBox setFrame:outerFrame]; - - y += NSHeight(outerFrame); - frame.size.height += NSHeight(outerFrame); - - [bottomView_ addSubview:imageBox]; - } - - [bottomView_ setFrame:frame]; - [[self view] addSubview:bottomView_]; - [self adjustFrameHeight:&layoutParams delta:NSHeight(frame)]; - - // Make sure that there is a minimum amount of spacing below the icon and - // the edge of the frame. - CGFloat bottomDelta = - NSHeight(layoutParams.rootFrame) - NSHeight([icon_ frame]); - if (bottomDelta > 0 && bottomDelta < message_center::kIconBottomPadding) { - CGFloat bottomAdjust = message_center::kIconBottomPadding - bottomDelta; - [self adjustFrameHeight:&layoutParams delta:bottomAdjust]; - } - - [[self view] setFrame:layoutParams.rootFrame]; - [title_ setFrame:layoutParams.titleFrame]; - [message_ setFrame:layoutParams.messageFrame]; - [contextMessage_ setFrame:layoutParams.contextMessageFrame]; - [settingsButton_ setFrame:layoutParams.settingsButtonFrame]; - [listView_ setFrame:layoutParams.listFrame]; - [progressBarView_ setFrame:layoutParams.progressBarFrame]; - - return layoutParams.rootFrame; -} - -- (void)close:(id)sender { - [closeButton_ setTarget:nil]; - messageCenter_->RemoveNotification([self notificationID], /*by_user=*/true); -} - -- (void)settingsClicked:(id)sender { - [NSApp activateIgnoringOtherApps:YES]; - messageCenter_->ClickOnSettingsButton([self notificationID]); -} - -- (void)buttonClicked:(id)button { - messageCenter_->ClickOnNotificationButton([self notificationID], - [button tag]); -} - -- (const message_center::Notification*)notification { - return notification_; -} - -- (const std::string&)notificationID { - return notificationID_; -} - -- (void)notificationClicked { - messageCenter_->ClickOnNotification([self notificationID]); -} - -- (void)adjustFrameHeight:(message_center::NotificationLayoutParams*)frames - delta:(CGFloat)delta { - frames->rootFrame.size.height += delta; - frames->titleFrame.origin.y += delta; - frames->messageFrame.origin.y += delta; - frames->contextMessageFrame.origin.y += delta; - frames->settingsButtonFrame.origin.y += delta; - frames->listFrame.origin.y += delta; - frames->progressBarFrame.origin.y += delta; -} - -// Private ///////////////////////////////////////////////////////////////////// - -- (void)configureCustomBox:(NSBox*)box { - [box setBoxType:NSBoxCustom]; - [box setBorderType:NSNoBorder]; - [box setTitlePosition:NSNoTitle]; - [box setContentViewMargins:NSZeroSize]; -} - -- (NSView*)createIconView { - // Create another box that shows a background color when the icon is not - // big enough to fill the space. - NSRect imageFrame = NSMakeRect(0, 0, - message_center::kNotificationIconSize, - message_center::kNotificationIconSize); - base::scoped_nsobject<NSBox> imageBox( - [[AccessibilityIgnoredBox alloc] initWithFrame:imageFrame]); - [self configureCustomBox:imageBox]; - [imageBox setAutoresizingMask:NSViewMinYMargin]; - - // Inside the image box put the actual icon view. - icon_.reset([[NSImageView alloc] initWithFrame:imageFrame]); - [imageBox setContentView:icon_]; - - return imageBox.autorelease(); -} - -- (NSBox*)createImageBox:(const gfx::Image&)notificationImage { - using message_center::kNotificationImageBorderSize; - using message_center::kNotificationPreferredImageWidth; - using message_center::kNotificationPreferredImageHeight; - - NSRect imageFrame = NSMakeRect(0, 0, - kNotificationPreferredImageWidth, - kNotificationPreferredImageHeight); - base::scoped_nsobject<NSBox> imageBox( - [[AccessibilityIgnoredBox alloc] initWithFrame:imageFrame]); - [self configureCustomBox:imageBox]; - [imageBox setFillColor:skia::SkColorToCalibratedNSColor( - message_center::kImageBackgroundColor)]; - - // Images with non-preferred aspect ratios get a border on all sides. - gfx::Size idealSize = gfx::Size( - kNotificationPreferredImageWidth, kNotificationPreferredImageHeight); - gfx::Size scaledSize = message_center::GetImageSizeForContainerSize( - idealSize, notificationImage.Size()); - if (scaledSize != idealSize) { - NSSize borderSize = - NSMakeSize(kNotificationImageBorderSize, kNotificationImageBorderSize); - [imageBox setContentViewMargins:borderSize]; - } - - NSImage* image = notificationImage.AsNSImage(); - base::scoped_nsobject<NSImageView> imageView( - [[NSImageView alloc] initWithFrame:imageFrame]); - [imageView setImage:image]; - [imageView setImageScaling:NSImageScaleProportionallyUpOrDown]; - [imageBox setContentView:imageView]; - - return imageBox.autorelease(); -} - -- (void)configureCloseButtonInFrame:(NSRect)rootFrame { - // The close button is configured to be the same size as the small image. - int closeButtonOriginOffset = - message_center::kSmallImageSize + message_center::kSmallImagePadding; - NSRect closeButtonFrame = - NSMakeRect(NSMaxX(rootFrame) - closeButtonOriginOffset, - NSMaxY(rootFrame) - closeButtonOriginOffset, - message_center::kSmallImageSize, - message_center::kSmallImageSize); - closeButton_.reset([[HoverImageButton alloc] initWithFrame:closeButtonFrame]); - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - [closeButton_ setDefaultImage: - rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE).ToNSImage()]; - [closeButton_ setHoverImage: - rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE_HOVER).ToNSImage()]; - [closeButton_ setPressedImage: - rb.GetNativeImageNamed(IDR_NOTIFICATION_CLOSE_PRESSED).ToNSImage()]; - [[closeButton_ cell] setHighlightsBy:NSOnState]; - [closeButton_ setTrackingEnabled:YES]; - [closeButton_ setBordered:NO]; - [closeButton_ setAutoresizingMask:NSViewMinYMargin]; - [closeButton_ setTarget:self]; - [closeButton_ setAction:@selector(close:)]; - [closeButton_ setDisableActivationOnClick:YES]; - [[closeButton_ cell] - accessibilitySetOverrideValue:NSAccessibilityCloseButtonSubrole - forAttribute:NSAccessibilitySubroleAttribute]; - [[closeButton_ cell] - accessibilitySetOverrideValue: - l10n_util::GetNSString(IDS_APP_ACCNAME_CLOSE) - forAttribute:NSAccessibilityTitleAttribute]; -} - -- (void)configureSettingsButtonInFrame:(NSRect)rootFrame { - // The settings button is configured to be the same size as the small image. - int settingsButtonOriginOffset = - message_center::kSmallImageSize + message_center::kSmallImagePadding; - NSRect settingsButtonFrame = NSMakeRect( - NSMaxX(rootFrame) - settingsButtonOriginOffset, - message_center::kSmallImagePadding, message_center::kSmallImageSize, - message_center::kSmallImageSize); - - settingsButton_.reset( - [[HoverImageButton alloc] initWithFrame:settingsButtonFrame]); - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - [settingsButton_ setDefaultImage:rb.GetNativeImageNamed( - IDR_NOTIFICATION_SETTINGS_BUTTON_ICON) - .ToNSImage()]; - [settingsButton_ - setHoverImage:rb.GetNativeImageNamed( - IDR_NOTIFICATION_SETTINGS_BUTTON_ICON_HOVER) - .ToNSImage()]; - [settingsButton_ - setPressedImage:rb.GetNativeImageNamed( - IDR_NOTIFICATION_SETTINGS_BUTTON_ICON_PRESSED) - .ToNSImage()]; - [[settingsButton_ cell] setHighlightsBy:NSOnState]; - [settingsButton_ setTrackingEnabled:YES]; - [settingsButton_ setBordered:NO]; - [settingsButton_ setAutoresizingMask:NSViewMinYMargin]; - [settingsButton_ setTarget:self]; - [settingsButton_ setAction:@selector(settingsClicked:)]; - [[settingsButton_ cell] - accessibilitySetOverrideValue: - l10n_util::GetNSString( - IDS_MESSAGE_NOTIFICATION_SETTINGS_BUTTON_ACCESSIBLE_NAME) - forAttribute:NSAccessibilityTitleAttribute]; -} - -- (NSView*)createSmallImageInFrame:(NSRect)rootFrame { - int smallImageXOffset = - message_center::kSmallImagePadding + message_center::kSmallImageSize; - NSRect boxFrame = - NSMakeRect(NSMaxX(rootFrame) - smallImageXOffset, - NSMinY(rootFrame) + message_center::kSmallImagePadding, - message_center::kSmallImageSize, - message_center::kSmallImageSize); - - // Put the smallImage inside another box which can hide it from accessibility - // until we have some alt text to go with it. Once we have alt text, remove - // the box, and set NSAccessibilityDescriptionAttribute with it. - base::scoped_nsobject<NSBox> imageBox( - [[AccessibilityIgnoredBox alloc] initWithFrame:boxFrame]); - [self configureCustomBox:imageBox]; - [imageBox setAutoresizingMask:NSViewMinYMargin]; - - NSRect smallImageFrame = - NSMakeRect(0,0, - message_center::kSmallImageSize, - message_center::kSmallImageSize); - - smallImage_.reset([[NSImageView alloc] initWithFrame:smallImageFrame]); - [smallImage_ setImageScaling:NSImageScaleProportionallyUpOrDown]; - [imageBox setContentView:smallImage_]; - - return imageBox.autorelease(); -} - -- (void)configureTitleInFrame:(NSRect)contentFrame { - contentFrame.size.height = 0; - title_.reset([self newLabelWithFrame:contentFrame]); - [title_ setAutoresizingMask:NSViewMinYMargin]; - [title_ setTextColor:skia::SkColorToCalibratedNSColor( - message_center::kRegularTextColor)]; - [title_ setFont:[NSFont messageFontOfSize:message_center::kTitleFontSize]]; -} - -- (void)configureBodyInFrame:(NSRect)contentFrame { - contentFrame.size.height = 0; - message_.reset([self newLabelWithFrame:contentFrame]); - [message_ setAutoresizingMask:NSViewMinYMargin]; - [message_ setTextColor:skia::SkColorToCalibratedNSColor( - message_center::kRegularTextColor)]; - [message_ setFont: - [NSFont messageFontOfSize:message_center::kMessageFontSize]]; -} - -- (void)configureContextMessageInFrame:(NSRect)contentFrame { - contentFrame.size.height = 0; - contextMessage_.reset([self newLabelWithFrame:contentFrame]); - [contextMessage_ setAutoresizingMask:NSViewMinYMargin]; - [contextMessage_ setTextColor:skia::SkColorToCalibratedNSColor( - message_center::kDimTextColor)]; - [contextMessage_ setFont: - [NSFont messageFontOfSize:message_center::kMessageFontSize]]; -} - -- (NSTextView*)newLabelWithFrame:(NSRect)frame { - NSTextView* label = [[NSTextView alloc] initWithFrame:frame]; - - // The labels MUST draw their background so that subpixel antialiasing can - // happen on the text. - [label setDrawsBackground:YES]; - [label setBackgroundColor:skia::SkColorToCalibratedNSColor( - message_center::kNotificationBackgroundColor)]; - - [label setEditable:NO]; - [label setSelectable:NO]; - [label setTextContainerInset:NSMakeSize(0.0f, 0.0f)]; - [[label textContainer] setLineFragmentPadding:0.0f]; - return label; -} - -- (NSRect)currentContentRect { - DCHECK(icon_); - DCHECK(closeButton_); - DCHECK(smallImage_); - - NSRect iconFrame, contentFrame; - NSDivideRect([[self view] bounds], &iconFrame, &contentFrame, - NSWidth([icon_ frame]) + message_center::kIconToTextPadding, - NSMinXEdge); - // The content area is between the icon on the left and the control area - // on the right. - int controlAreaWidth = - std::max(NSWidth([closeButton_ frame]), NSWidth([smallImage_ frame])); - contentFrame.size.width -= - 2 * message_center::kSmallImagePadding + controlAreaWidth; - return contentFrame; -} - -- (base::string16)wrapText:(const base::string16&)text - forFont:(NSFont*)nsfont - maxNumberOfLines:(size_t)lines - actualLines:(size_t*)actualLines { - *actualLines = 0; - if (text.empty() || lines == 0) - return base::string16(); - gfx::FontList font_list((gfx::Font(nsfont))); - int width = NSWidth([self currentContentRect]); - int height = (lines + 1) * font_list.GetHeight(); - - std::vector<base::string16> wrapped; - gfx::ElideRectangleTextForNativeUi(text, font_list, width, height, - gfx::WRAP_LONG_WORDS, &wrapped); - - // This could be possible when the input text contains only spaces. - if (wrapped.empty()) - return base::string16(); - - if (wrapped.size() > lines) { - // Add an ellipsis to the last line. If this ellipsis makes the last line - // too wide, that line will be further elided by the gfx::ElideText below. - base::string16 last = - wrapped[lines - 1] + base::UTF8ToUTF16(gfx::kEllipsis); - if (gfx::GetStringWidth(last, font_list, gfx::Typesetter::NATIVE) > width) { - last = gfx::ElideText(last, font_list, width, gfx::ELIDE_TAIL, - gfx::Typesetter::NATIVE); - } - wrapped.resize(lines - 1); - wrapped.push_back(last); - } - - *actualLines = wrapped.size(); - return lines == 1 ? wrapped[0] - : base::JoinString(wrapped, base::ASCIIToUTF16("\n")); -} - -- (base::string16)wrapText:(const base::string16&)text - forFont:(NSFont*)nsfont - maxNumberOfLines:(size_t)lines { - size_t unused; - return [self wrapText:text - forFont:nsfont - maxNumberOfLines:lines - actualLines:&unused]; -} - -@end
diff --git a/ui/message_center/cocoa/notification_controller_unittest.mm b/ui/message_center/cocoa/notification_controller_unittest.mm deleted file mode 100644 index 1c819a46..0000000 --- a/ui/message_center/cocoa/notification_controller_unittest.mm +++ /dev/null
@@ -1,434 +0,0 @@ -// Copyright (c) 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. - -#import "ui/message_center/cocoa/notification_controller.h" - -#include <memory> - -#include "base/mac/foundation_util.h" -#include "base/mac/scoped_nsobject.h" -#include "base/macros.h" -#include "base/strings/sys_string_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "third_party/skia/include/core/SkBitmap.h" -#import "ui/base/cocoa/hover_image_button.h" -#import "ui/base/test/cocoa_helper.h" -#include "ui/message_center/fake_message_center.h" -#include "ui/message_center/public/cpp/message_center_constants.h" -#include "ui/message_center/public/cpp/notification.h" -#include "ui/message_center/public/cpp/notification_types.h" - -using base::ASCIIToUTF16; -using base::UTF8ToUTF16; - -namespace { - -class MockMessageCenter : public message_center::FakeMessageCenter { - public: - MockMessageCenter() - : last_removed_by_user_(false), - remove_count_(0), - last_clicked_index_(-1) {} - - void RemoveNotification(const std::string& id, bool by_user) override { - last_removed_id_ = id; - last_removed_by_user_ = by_user; - ++remove_count_; - } - - void ClickOnNotificationButton(const std::string& id, - int button_index) override { - last_clicked_id_ = id; - last_clicked_index_ = button_index; - } - - const std::string& last_removed_id() const { return last_removed_id_; } - bool last_removed_by_user() const { return last_removed_by_user_; } - int remove_count() const { return remove_count_; } - const std::string& last_clicked_id() const { return last_clicked_id_; } - int last_clicked_index() const { return last_clicked_index_; } - - private: - std::string last_removed_id_; - bool last_removed_by_user_; - int remove_count_; - - std::string last_clicked_id_; - int last_clicked_index_; - - DISALLOW_COPY_AND_ASSIGN(MockMessageCenter); -}; - -} // namespace - -@implementation MCNotificationController (TestingInterface) -- (NSButton*)closeButton { - return closeButton_.get(); -} - -- (NSImageView*)smallImageView { - return smallImage_.get(); -} - -- (NSButton*)secondButton { - // The buttons are in Cocoa-y-order, so the 2nd button is first. - NSView* view = [[bottomView_ subviews] objectAtIndex:0]; - return base::mac::ObjCCastStrict<NSButton>(view); -} - -- (NSArray*)bottomSubviews { - return [bottomView_ subviews]; -} - -- (NSImageView*)iconView { - return icon_.get(); -} - -- (NSTextView*)titleView { - return title_.get(); -} - -- (NSTextView*)messageView { - return message_.get(); -} - -- (NSTextView*)contextMessageView { - return contextMessage_.get(); -} - -- (HoverImageButton*)settingsButton { - return settingsButton_.get(); -} - -- (NSView*)listView { - return listView_.get(); -} -@end - -namespace message_center { - -class NotificationControllerTest : public ui::CocoaTest { - public: - NSImage* TestIcon() { - return [NSImage imageNamed:NSImageNameUser]; - } - - protected: - message_center::NotifierId DummyNotifierId() { - return message_center::NotifierId(); - } -}; - -TEST_F(NotificationControllerTest, BasicLayout) { - std::unique_ptr<message_center::Notification> notification( - new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "", - ASCIIToUTF16("Added to circles"), - ASCIIToUTF16("Jonathan and 5 others"), gfx::Image(), base::string16(), - GURL(), DummyNotifierId(), message_center::RichNotificationData(), - NULL)); - gfx::Image testIcon(TestIcon()); - notification->set_icon(testIcon); - notification->set_small_image(testIcon); - - base::scoped_nsobject<MCNotificationController> controller( - [[MCNotificationController alloc] initWithNotification:notification.get() - messageCenter:NULL]); - [controller view]; - - EXPECT_EQ(TestIcon(), [[controller iconView] image]); - EXPECT_EQ(TestIcon(), [[controller smallImageView] image]); - EXPECT_EQ(base::SysNSStringToUTF16([[controller titleView] string]), - notification->title()); - EXPECT_EQ(base::SysNSStringToUTF16([[controller messageView] string]), - notification->message()); - EXPECT_EQ(controller.get(), [[controller closeButton] target]); -} - -TEST_F(NotificationControllerTest, NotificationSetttingsButtonLayout) { - message_center::RichNotificationData data; - data.settings_button_handler = SettingsButtonHandler::INLINE; - std::unique_ptr<message_center::Notification> notification( - new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "", - ASCIIToUTF16("Added to circles"), - ASCIIToUTF16("Jonathan and 5 others"), gfx::Image(), base::string16(), - GURL("https://plus.com"), DummyNotifierId(), data, NULL)); - - base::scoped_nsobject<MCNotificationController> controller( - [[MCNotificationController alloc] initWithNotification:notification.get() - messageCenter:nullptr]); - [controller view]; - EXPECT_EQ(controller.get(), [[controller settingsButton] target]); -} - -TEST_F(NotificationControllerTest, ContextMessageAsDomainNotificationLayout) { - std::unique_ptr<message_center::Notification> notification( - new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "", - ASCIIToUTF16("Added to circles"), - ASCIIToUTF16("Jonathan and 5 others"), gfx::Image(), base::string16(), - GURL("https://plus.com"), DummyNotifierId(), - message_center::RichNotificationData(), new NotificationDelegate())); - base::scoped_nsobject<MCNotificationController> controller( - [[MCNotificationController alloc] initWithNotification:notification.get() - messageCenter:nullptr]); - [controller view]; - - EXPECT_EQ(base::SysNSStringToUTF8([[controller contextMessageView] string]), - "plus.com"); -} - -TEST_F(NotificationControllerTest, OverflowText) { - std::unique_ptr<message_center::Notification> notification( - new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "", - ASCIIToUTF16("This is a much longer title that should wrap " - "multiple lines."), - ASCIIToUTF16("And even the message is long. This sure is a wordy " - "notification. Are you really going to read this " - "entire thing?"), - gfx::Image(), base::string16(), GURL(), DummyNotifierId(), - message_center::RichNotificationData(), NULL)); - base::scoped_nsobject<MCNotificationController> controller( - [[MCNotificationController alloc] initWithNotification:notification.get() - messageCenter:NULL]); - [controller view]; - - EXPECT_GT(NSHeight([[controller view] frame]), - message_center::kNotificationIconSize); -} - -TEST_F(NotificationControllerTest, Close) { - std::unique_ptr<message_center::Notification> notification( - new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "an_id", base::string16(), - base::string16(), gfx::Image(), base::string16(), GURL(), - DummyNotifierId(), message_center::RichNotificationData(), NULL)); - MockMessageCenter message_center; - - base::scoped_nsobject<MCNotificationController> controller( - [[MCNotificationController alloc] initWithNotification:notification.get() - messageCenter:&message_center]); - [controller view]; - - [[controller closeButton] performClick:nil]; - - EXPECT_EQ(1, message_center.remove_count()); - EXPECT_EQ("an_id", message_center.last_removed_id()); - EXPECT_TRUE(message_center.last_removed_by_user()); -} - -TEST_F(NotificationControllerTest, Update) { - std::unique_ptr<message_center::Notification> notification( - new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "", - ASCIIToUTF16("A simple title"), - ASCIIToUTF16("This message isn't too long and should fit in the" - "default bounds."), - gfx::Image(), base::string16(), GURL(), DummyNotifierId(), - message_center::RichNotificationData(), NULL)); - base::scoped_nsobject<MCNotificationController> controller( - [[MCNotificationController alloc] initWithNotification:notification.get() - messageCenter:NULL]); - - // Set up the default layout. - [controller view]; - EXPECT_EQ(NSHeight([[controller view] frame]), - message_center::kNotificationIconSize); - EXPECT_FALSE([[controller iconView] image]); - EXPECT_FALSE([[controller smallImageView] image]); - - // Update the icon. - gfx::Image testIcon(TestIcon()); - notification->set_icon(testIcon); - notification->set_small_image(testIcon); - [controller updateNotification:notification.get()]; - EXPECT_EQ(TestIcon(), [[controller iconView] image]); - EXPECT_EQ(TestIcon(), [[controller smallImageView] image]); - EXPECT_EQ(NSHeight([[controller view] frame]), - message_center::kNotificationIconSize); -} - -TEST_F(NotificationControllerTest, Buttons) { - message_center::RichNotificationData optional; - message_center::ButtonInfo button1(UTF8ToUTF16("button1")); - optional.buttons.push_back(button1); - message_center::ButtonInfo button2(UTF8ToUTF16("button2")); - optional.buttons.push_back(button2); - - std::unique_ptr<message_center::Notification> notification( - new message_center::Notification( - message_center::NOTIFICATION_TYPE_BASE_FORMAT, "an_id", - base::string16(), base::string16(), gfx::Image(), base::string16(), - GURL(), DummyNotifierId(), optional, NULL)); - MockMessageCenter message_center; - - base::scoped_nsobject<MCNotificationController> controller( - [[MCNotificationController alloc] initWithNotification:notification.get() - messageCenter:&message_center]); - [controller view]; - - [[controller secondButton] performClick:nil]; - - EXPECT_EQ("an_id", message_center.last_clicked_id()); - EXPECT_EQ(1, message_center.last_clicked_index()); -} - -TEST_F(NotificationControllerTest, Image) { - std::unique_ptr<message_center::Notification> notification( - new message_center::Notification( - message_center::NOTIFICATION_TYPE_BASE_FORMAT, "an_id", - base::string16(), base::string16(), gfx::Image(), base::string16(), - GURL(), DummyNotifierId(), message_center::RichNotificationData(), - NULL)); - NSImage* image = [NSImage imageNamed:NSImageNameFolder]; - notification->set_image(gfx::Image(image)); - - MockMessageCenter message_center; - - base::scoped_nsobject<MCNotificationController> controller( - [[MCNotificationController alloc] initWithNotification:notification.get() - messageCenter:&message_center]); - [controller view]; - - ASSERT_EQ(1u, [[controller bottomSubviews] count]); - ASSERT_TRUE([[[[controller bottomSubviews] lastObject] contentView] - isKindOfClass:[NSImageView class]]); - EXPECT_EQ(image, - [[[[controller bottomSubviews] lastObject] contentView] image]); -} - -TEST_F(NotificationControllerTest, List) { - message_center::RichNotificationData optional; - message_center::NotificationItem item1{UTF8ToUTF16("First title"), - UTF8ToUTF16("first message")}; - optional.items.push_back(item1); - message_center::NotificationItem item2{ - UTF8ToUTF16("Second title"), - UTF8ToUTF16("second slightly longer message")}; - optional.items.push_back(item2); - message_center::NotificationItem item3{ - UTF8ToUTF16(""), // Test for empty string. - UTF8ToUTF16(" ")}; // Test for string containing only spaces. - optional.items.push_back(item3); - optional.context_message = UTF8ToUTF16("Context Message"); - - std::unique_ptr<message_center::Notification> notification( - new message_center::Notification( - message_center::NOTIFICATION_TYPE_BASE_FORMAT, "an_id", - UTF8ToUTF16("Notification Title"), - UTF8ToUTF16("Notification Message - should be hidden"), gfx::Image(), - base::string16(), GURL(), DummyNotifierId(), optional, NULL)); - - MockMessageCenter message_center; - base::scoped_nsobject<MCNotificationController> controller( - [[MCNotificationController alloc] initWithNotification:notification.get() - messageCenter:&message_center]); - [controller view]; - - EXPECT_FALSE([[controller titleView] isHidden]); - EXPECT_TRUE([[controller messageView] isHidden]); - EXPECT_FALSE([[controller contextMessageView] isHidden]); - - EXPECT_EQ(3u, [[[controller listView] subviews] count]); - EXPECT_LT(NSMaxY([[controller listView] frame]), - NSMinY([[controller titleView] frame])); -} - -TEST_F(NotificationControllerTest, NoMessage) { - message_center::RichNotificationData optional; - optional.context_message = UTF8ToUTF16("Context Message"); - - std::unique_ptr<message_center::Notification> notification( - new message_center::Notification( - message_center::NOTIFICATION_TYPE_BASE_FORMAT, "an_id", - UTF8ToUTF16("Notification Title"), UTF8ToUTF16(""), gfx::Image(), - base::string16(), GURL(), DummyNotifierId(), optional, NULL)); - - MockMessageCenter message_center; - base::scoped_nsobject<MCNotificationController> controller( - [[MCNotificationController alloc] initWithNotification:notification.get() - messageCenter:&message_center]); - [controller view]; - - EXPECT_FALSE([[controller titleView] isHidden]); - EXPECT_TRUE([[controller messageView] isHidden]); - EXPECT_FALSE([[controller contextMessageView] isHidden]); -} - -TEST_F(NotificationControllerTest, MessageSize) { - message_center::RichNotificationData data; - std::string id("id"); - NotifierId notifier_id(NotifierType::APPLICATION, "notifier"); - std::unique_ptr<Notification> notification(new Notification( - NOTIFICATION_TYPE_BASE_FORMAT, id, base::UTF8ToUTF16(""), - ASCIIToUTF16("And\neven\nthe\nmessage is long.\nThis sure is wordy"), - gfx::Image(), base::string16() /* display_source */, GURL(), notifier_id, - data, NULL /* delegate */)); - - base::scoped_nsobject<MCNotificationController> controller( - [[MCNotificationController alloc] initWithNotification:notification.get() - messageCenter:NULL]); - - // Set up the default layout. - [controller view]; - - auto compute_message_lines = ^{ - NSString* string = [[[controller messageView] textStorage] string]; - unsigned numberOfLines, index, stringLength = [string length]; - for (index = 0, numberOfLines = 0; index < stringLength; numberOfLines++) - index = NSMaxRange([string lineRangeForRange:NSMakeRange(index, 0)]); - - return numberOfLines; - }; - - // Message and no title: 5 lines. - EXPECT_EQ(5u, compute_message_lines()); - - // Message and one line title: 5 lines. - notification->set_title(ASCIIToUTF16("one line")); - [controller updateNotification:notification.get()]; - EXPECT_EQ(5u, compute_message_lines()); - - // Message and two line title: 3 lines. - notification->set_title(ASCIIToUTF16("two\nlines")); - [controller updateNotification:notification.get()]; - EXPECT_EQ(3u, compute_message_lines()); - - // Message, image and no title: 2 lines. - SkBitmap bitmap; - bitmap.allocN32Pixels(2, 2); - bitmap.eraseColor(SK_ColorGREEN); - notification->set_title(ASCIIToUTF16("")); - notification->set_image(gfx::Image::CreateFrom1xBitmap(bitmap)); - [controller updateNotification:notification.get()]; - EXPECT_EQ(2u, compute_message_lines()); - - // Message, image and one line title: 2 lines. - notification->set_title(ASCIIToUTF16("one line")); - [controller updateNotification:notification.get()]; - EXPECT_EQ(2u, compute_message_lines()); - - // Message, image and two line title: 1 lines. - notification->set_title(ASCIIToUTF16("two\nlines")); - [controller updateNotification:notification.get()]; - EXPECT_EQ(1u, compute_message_lines()); - - // Same as above, but context message takes away from message lines. - notification->set_context_message(UTF8ToUTF16("foo")); - notification->set_title(ASCIIToUTF16("")); - [controller updateNotification:notification.get()]; - EXPECT_EQ(1u, compute_message_lines()); - - notification->set_title(ASCIIToUTF16("one line")); - [controller updateNotification:notification.get()]; - EXPECT_EQ(1u, compute_message_lines()); - - notification->set_title(ASCIIToUTF16("two\nlines")); - [controller updateNotification:notification.get()]; - EXPECT_EQ(0u, compute_message_lines()); -} - -} // namespace message_center
diff --git a/ui/message_center/cocoa/opaque_views.h b/ui/message_center/cocoa/opaque_views.h deleted file mode 100644 index 1a2f3b0..0000000 --- a/ui/message_center/cocoa/opaque_views.h +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_MESSAGE_CENTER_COCOA_OPAQUE_VIEWS_H_ -#define UI_MESSAGE_CENTER_COCOA_OPAQUE_VIEWS_H_ - -#import <Cocoa/Cocoa.h> - -#include "base/mac/scoped_nsobject.h" - -// MCDropDown is the same as an NSPopupButton except that it fills its -// background with a settable color. -@interface MCDropDown : NSPopUpButton { - @private - base::scoped_nsobject<NSColor> backgroundColor_; -} - -// Gets and sets the bubble's background color. -- (NSColor*)backgroundColor; -- (void)setBackgroundColor:(NSColor*)backgroundColor; -@end - -// MCTextField fills its background with an opaque color. It also configures -// the view to have a plan appearance, without bezel, border, editing, etc. -@interface MCTextField : NSTextField { - @private - base::scoped_nsobject<NSColor> backgroundColor_; -} - -// Use this method to create the text field. The color is required so it -// can correctly subpixel antialias. -- (id)initWithFrame:(NSRect)frameRect backgroundColor:(NSColor*)color; -@end - -#endif // UI_MESSAGE_CENTER_COCOA_OPAQUE_VIEWS_H_
diff --git a/ui/message_center/cocoa/opaque_views.mm b/ui/message_center/cocoa/opaque_views.mm deleted file mode 100644 index b6e054f..0000000 --- a/ui/message_center/cocoa/opaque_views.mm +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ui/message_center/cocoa/opaque_views.h" - -@implementation MCDropDown -// The view must be opaque to render subpixel antialiasing. -- (BOOL)isOpaque { - return YES; -} - -// The view must also fill its background to render subpixel antialiasing. -- (void)drawRect:(NSRect)dirtyRect { - [backgroundColor_ set]; - NSRectFill(dirtyRect); - [super drawRect:dirtyRect]; -} - -- (NSColor*)backgroundColor { - return backgroundColor_; -} - -- (void)setBackgroundColor:(NSColor*)backgroundColor { - backgroundColor_.reset([backgroundColor retain]); -} -@end - -@implementation MCTextField -- (id)initWithFrame:(NSRect)frameRect backgroundColor:(NSColor*)color { - self = [self initWithFrame:frameRect]; - if (self) { - [self setBackgroundColor:color]; - backgroundColor_.reset([color retain]); - } - return self; -} - -- (id)initWithFrame:(NSRect)frameRect { - self = [super initWithFrame:frameRect]; - if (self) { - [self setAutoresizingMask:NSViewMinYMargin]; - [self setBezeled:NO]; - [self setBordered:NO]; - [self setEditable:NO]; - [self setSelectable:NO]; - [self setDrawsBackground:YES]; - } - return self; -} - -// The view must be opaque to render subpixel antialiasing. -- (BOOL)isOpaque { - return YES; -} - -// The view must also fill its background to render subpixel antialiasing. -- (void)drawRect:(NSRect)dirtyRect { - [backgroundColor_ set]; - NSRectFill(dirtyRect); - [super drawRect:dirtyRect]; -} -@end
diff --git a/ui/message_center/cocoa/popup_collection.h b/ui/message_center/cocoa/popup_collection.h deleted file mode 100644 index 736cdea..0000000 --- a/ui/message_center/cocoa/popup_collection.h +++ /dev/null
@@ -1,101 +0,0 @@ -// Copyright (c) 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 UI_MESSAGE_CENTER_COCOA_POPUP_COLLECTION_H_ -#define UI_MESSAGE_CENTER_COCOA_POPUP_COLLECTION_H_ - -#import <Cocoa/Cocoa.h> - -#include <memory> -#include <set> - -#include "base/mac/scoped_block.h" -#import "base/mac/scoped_nsobject.h" -#include "ui/message_center/message_center_export.h" - -namespace message_center { -class MessageCenter; -class MessageCenterObserver; -} - -namespace message_center { -typedef void(^AnimationEndedCallback)(); -} - -// A popup collection interfaces with the MessageCenter as an observer. It will -// arrange notifications on the screen as popups, starting in the upper-right -// corner, going to the bottom of the screen. This class maintains ownership of -// the Cocoa controllers and windows of the notifications. -MESSAGE_CENTER_EXPORT -@interface MCPopupCollection : NSObject { - @private - // The message center that is responsible for the notifications. Weak, global. - message_center::MessageCenter* messageCenter_; - - // MessageCenterObserver implementation. - std::unique_ptr<message_center::MessageCenterObserver> observer_; - - // Array of all on-screen popup notifications. - base::scoped_nsobject<NSMutableArray> popups_; - - // Array of all on-screen popup notifications that are being faded out - // for removal. - base::scoped_nsobject<NSMutableArray> popupsBeingRemoved_; - - // For testing only. If not a zero rect, this is the screen size to use - // for laying out popups. - NSRect testingScreenFrame_; - - // The duration of the popup animation, in the number of seconds. - NSTimeInterval popupAnimationDuration_; - - // Set of notification IDs for those popups to be updated when all existing - // animations end. - std::set<std::string> pendingUpdateNotificationIDs_; - - // Set of notification IDs for those popups to be closed when all existing - // animations end. - std::set<std::string> pendingRemoveNotificationIDs_; - - // Set of notification IDs for those popups that are being animated due to - // showing, bounds change or closing. - std::set<std::string> animatingNotificationIDs_; - - // For testing only. If set, the callback will be called when the animation - // ends. - base::mac::ScopedBlock<message_center::AnimationEndedCallback> - testingAnimationEndedCallback_; -} - -// Designated initializer that construct an instance to observe |messageCenter|. -- (id)initWithMessageCenter:(message_center::MessageCenter*)messageCenter; - -// Returns true if an animation is being played. -- (BOOL)isAnimating; - -// Returns the duration of the popup animation. -- (NSTimeInterval)popupAnimationDuration; - -// Called when the animation of a popup ends. -- (void)onPopupAnimationEnded:(const std::string&)notificationID; - -@end - -@interface MCPopupCollection (ExposedForTesting) -- (NSArray*)popups; - -// Setter for the testingScreenFrame_. -- (void)setScreenFrame:(NSRect)frame; - -// Setter for changing the animation duration. The testing code could set it -// to a very small value to expedite the test running. -- (void)setAnimationDuration:(NSTimeInterval)duration; - -// Setter for testingAnimationEndedCallback_. The testing code could set it -// to get called back when the animation ends. -- (void)setAnimationEndedCallback: - (message_center::AnimationEndedCallback)callback; -@end - -#endif // UI_MESSAGE_CENTER_COCOA_POPUP_COLLECTION_H_
diff --git a/ui/message_center/cocoa/popup_collection.mm b/ui/message_center/cocoa/popup_collection.mm deleted file mode 100644 index 8bf2df4..0000000 --- a/ui/message_center/cocoa/popup_collection.mm +++ /dev/null
@@ -1,403 +0,0 @@ -// Copyright (c) 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. - -#import "ui/message_center/cocoa/popup_collection.h" - -#import "ui/message_center/cocoa/notification_controller.h" -#import "ui/message_center/cocoa/popup_controller.h" -#include "ui/message_center/message_center.h" -#include "ui/message_center/message_center_observer.h" -#include "ui/message_center/public/cpp/message_center_constants.h" - -const float kAnimationDuration = 0.2; - -@interface MCPopupCollection (Private) -// Returns the primary screen's visible frame rectangle. -- (NSRect)screenFrame; - -// Shows a popup, if there is room on-screen, for the given notification. -// Returns YES if the notification was actually displayed. -- (BOOL)addNotification:(const message_center::Notification*)notification; - -// Updates the contents of the notification with the given ID. -- (void)updateNotification:(const std::string&)notificationID; - -// Removes a popup from the screen and lays out new notifications that can -// now potentially fit on the screen. -- (void)removeNotification:(const std::string&)notificationID; - -// Closes all the popups. -- (void)removeAllNotifications; - -// Returns the index of the popup showing the notification with the given ID. -- (NSUInteger)indexOfPopupWithNotificationID:(const std::string&)notificationID; - -// Repositions all popup notifications if needed. -- (void)layoutNotifications; - -// Fits as many new notifications as possible on screen. -- (void)layoutNewNotifications; - -// Process notifications pending to remove when no animation is being played. -- (void)processPendingRemoveNotifications; - -// Process notifications pending to update when no animation is being played. -- (void)processPendingUpdateNotifications; -@end - -namespace { - -class PopupCollectionObserver : public message_center::MessageCenterObserver { - public: - PopupCollectionObserver(message_center::MessageCenter* message_center, - MCPopupCollection* popup_collection) - : message_center_(message_center), - popup_collection_(popup_collection) { - message_center_->AddObserver(this); - } - - ~PopupCollectionObserver() override { message_center_->RemoveObserver(this); } - - void OnNotificationAdded(const std::string& notification_id) override { - [popup_collection_ layoutNewNotifications]; - } - - void OnNotificationRemoved(const std::string& notification_id, - bool user_id) override { - [popup_collection_ removeNotification:notification_id]; - } - - void OnNotificationUpdated(const std::string& notification_id) override { - [popup_collection_ updateNotification:notification_id]; - } - - void OnBlockingStateChanged( - message_center::NotificationBlocker* blocker) override { - [popup_collection_ layoutNewNotifications]; - } - - private: - message_center::MessageCenter* message_center_; // Weak, global. - - MCPopupCollection* popup_collection_; // Weak, owns this. -}; - -} // namespace - -@implementation MCPopupCollection - -- (id)initWithMessageCenter:(message_center::MessageCenter*)messageCenter { - if ((self = [super init])) { - messageCenter_ = messageCenter; - observer_.reset(new PopupCollectionObserver(messageCenter_, self)); - popups_.reset([[NSMutableArray alloc] init]); - popupsBeingRemoved_.reset([[NSMutableArray alloc] init]); - popupAnimationDuration_ = kAnimationDuration; - } - return self; -} - -- (void)dealloc { - [popupsBeingRemoved_ makeObjectsPerformSelector: - @selector(markPopupCollectionGone)]; - [self removeAllNotifications]; - [super dealloc]; -} - -- (BOOL)isAnimating { - return !animatingNotificationIDs_.empty(); -} - -- (NSTimeInterval)popupAnimationDuration { - return popupAnimationDuration_; -} - -- (void)onPopupAnimationEnded:(const std::string&)notificationID { - NSUInteger index = [popupsBeingRemoved_ indexOfObjectPassingTest: - ^BOOL(id popup, NSUInteger index, BOOL* stop) { - return [popup notificationID] == notificationID; - }]; - if (index != NSNotFound) - [popupsBeingRemoved_ removeObjectAtIndex:index]; - - animatingNotificationIDs_.erase(notificationID); - if (![self isAnimating]) - [self layoutNotifications]; - - // Give the testing code a chance to do something, i.e. quitting the test - // run loop. - if (![self isAnimating] && testingAnimationEndedCallback_) - testingAnimationEndedCallback_.get()(); -} - -// Testing API ///////////////////////////////////////////////////////////////// - -- (NSArray*)popups { - return popups_.get(); -} - -- (void)setScreenFrame:(NSRect)frame { - testingScreenFrame_ = frame; -} - -- (void)setAnimationDuration:(NSTimeInterval)duration { - popupAnimationDuration_ = duration; -} - -- (void)setAnimationEndedCallback: - (message_center::AnimationEndedCallback)callback { - testingAnimationEndedCallback_.reset(Block_copy(callback)); -} - -// Private ///////////////////////////////////////////////////////////////////// - -- (NSRect)screenFrame { - if (!NSIsEmptyRect(testingScreenFrame_)) - return testingScreenFrame_; - return [[[NSScreen screens] firstObject] visibleFrame]; -} - -- (BOOL)addNotification:(const message_center::Notification*)notification { - // Wait till all existing animations end. - if ([self isAnimating]) - return NO; - - // The popup is owned by itself. It will be released at close. - MCPopupController* popup = - [[MCPopupController alloc] initWithNotification:notification - messageCenter:messageCenter_ - popupCollection:self]; - - NSRect screenFrame = [self screenFrame]; - NSRect popupFrame = [popup bounds]; - - CGFloat x = NSMaxX(screenFrame) - message_center::kMarginBetweenPopups - - NSWidth(popupFrame); - CGFloat y = 0; - - MCPopupController* bottomPopup = [popups_ lastObject]; - if (!bottomPopup) { - y = NSMaxY(screenFrame); - } else { - y = NSMinY([bottomPopup bounds]); - } - - y -= message_center::kMarginBetweenPopups + NSHeight(popupFrame); - - if (y > NSMinY(screenFrame)) { - animatingNotificationIDs_.insert(notification->id()); - NSRect bounds = [popup bounds]; - bounds.origin.x = x; - bounds.origin.y = y; - [popup showWithAnimation:bounds]; - [popups_ addObject:popup]; - messageCenter_->DisplayedNotification( - notification->id(), message_center::DISPLAY_SOURCE_POPUP); - return YES; - } - - // The popup cannot fit on screen, so it has to be closed now. - [popup close]; - return NO; -} - -- (void)updateNotification:(const std::string&)notificationID { - // The notification may not be on screen. Create it if needed. - if ([self indexOfPopupWithNotificationID:notificationID] == NSNotFound) { - [self layoutNewNotifications]; - return; - } - - // Don't bother with the update if the notification is going to be removed. - if (pendingRemoveNotificationIDs_.find(notificationID) != - pendingRemoveNotificationIDs_.end()) { - return; - } - - pendingUpdateNotificationIDs_.insert(notificationID); - [self processPendingUpdateNotifications]; -} - -- (void)removeNotification:(const std::string&)notificationID { - // The notification may not be on screen. - if ([self indexOfPopupWithNotificationID:notificationID] == NSNotFound) - return; - - // Don't bother with the update if the notification is going to be removed. - pendingUpdateNotificationIDs_.erase(notificationID); - - pendingRemoveNotificationIDs_.insert(notificationID); - [self processPendingRemoveNotifications]; -} - -- (void)removeAllNotifications { - // In rare cases, the popup collection would be gone while an animation is - // still playing. For exmaple, the test code could show a new notification - // and dispose the collection immediately. Close the popup without animation - // when this is the case. - if ([self isAnimating]) - [popups_ makeObjectsPerformSelector:@selector(close)]; - else - [popups_ makeObjectsPerformSelector:@selector(closeWithAnimation)]; - [popups_ makeObjectsPerformSelector:@selector(markPopupCollectionGone)]; - [popups_ removeAllObjects]; -} - -- (NSUInteger)indexOfPopupWithNotificationID: - (const std::string&)notificationID { - return [popups_ indexOfObjectPassingTest: - ^BOOL(id popup, NSUInteger index, BOOL* stop) { - return [popup notificationID] == notificationID; - }]; -} - -- (void)layoutNotifications { - // Wait till all existing animations end. - if ([self isAnimating]) - return; - - NSRect screenFrame = [self screenFrame]; - - // The popup starts at top-right corner. - CGFloat maxY = NSMaxY(screenFrame); - - // Iterate all notifications and reposition each if needed. If one does not - // fit on screen, close it and any other on-screen popups that come after it. - NSUInteger removeAt = NSNotFound; - for (NSUInteger i = 0; i < [popups_ count]; ++i) { - MCPopupController* popup = [popups_ objectAtIndex:i]; - NSRect oldFrame = [popup bounds]; - NSRect frame = oldFrame; - frame.origin.y = - maxY - message_center::kMarginBetweenPopups - NSHeight(frame); - - // If this popup does not fit on screen, stop repositioning and close this - // and subsequent popups. - if (NSMinY(frame) < NSMinY(screenFrame)) { - removeAt = i; - break; - } - - if (!NSEqualRects(frame, oldFrame)) { - [popup setBounds:frame]; - animatingNotificationIDs_.insert([popup notificationID]); - } - - // Set the new maximum Y to be the bottom of this notification. - maxY = NSMinY(frame); - } - - if (removeAt != NSNotFound) { - // Remove any popups that are on screen but no longer fit. - while ([popups_ count] >= removeAt && [popups_ count]) { - [[popups_ lastObject] close]; - [popups_ removeLastObject]; - } - } else { - [self layoutNewNotifications]; - } - - [self processPendingRemoveNotifications]; - [self processPendingUpdateNotifications]; -} - -- (void)layoutNewNotifications { - // Wait till all existing animations end. - if ([self isAnimating]) - return; - - // Display any new popups that can now fit on screen, starting from the - // oldest notification that has not been shown up. - const auto& allPopups = messageCenter_->GetPopupNotifications(); - for (auto it = allPopups.rbegin(); it != allPopups.rend(); ++it) { - if ([self indexOfPopupWithNotificationID:(*it)->id()] == NSNotFound) { - // If there's no room left on screen to display notifications, stop - // trying. - if (![self addNotification:*it]) - break; - } - } -} - -- (void)processPendingRemoveNotifications { - // Wait till all existing animations end. - if ([self isAnimating]) - return; - - for (const auto& notificationID : pendingRemoveNotificationIDs_) { - NSUInteger index = [self indexOfPopupWithNotificationID:notificationID]; - if (index != NSNotFound) { - [[popups_ objectAtIndex:index] closeWithAnimation]; - animatingNotificationIDs_.insert(notificationID); - - // Still need to track popup object and only remove it after the animation - // ends. We need to notify these objects that the collection is gone - // in the collection destructor. - [popupsBeingRemoved_ addObject:[popups_ objectAtIndex:index]]; - [popups_ removeObjectAtIndex:index]; - } - } - pendingRemoveNotificationIDs_.clear(); -} - -- (void)processPendingUpdateNotifications { - // Wait till all existing animations end. - if ([self isAnimating]) - return; - - if (pendingUpdateNotificationIDs_.empty()) - return; - - // Go through all model objects in the message center. If there is a replaced - // notification, the controller's current model object may be stale. - const auto& modelPopups = messageCenter_->GetPopupNotifications(); - for (auto iter = modelPopups.begin(); iter != modelPopups.end(); ++iter) { - const std::string& notificationID = (*iter)->id(); - - // Does the notification need to be updated? - std::set<std::string>::iterator pendingUpdateIter = - pendingUpdateNotificationIDs_.find(notificationID); - if (pendingUpdateIter == pendingUpdateNotificationIDs_.end()) - continue; - pendingUpdateNotificationIDs_.erase(pendingUpdateIter); - - // Is the notification still on screen? - NSUInteger index = [self indexOfPopupWithNotificationID:notificationID]; - if (index == NSNotFound) - continue; - - MCPopupController* popup = [popups_ objectAtIndex:index]; - - CGFloat oldHeight = - NSHeight([[[popup notificationController] view] frame]); - CGFloat newHeight = NSHeight( - [[popup notificationController] updateNotification:*iter]); - - // The notification has changed height. This requires updating the popup - // window. - if (oldHeight != newHeight) { - NSRect popupFrame = [popup bounds]; - popupFrame.origin.y -= newHeight - oldHeight; - popupFrame.size.height += newHeight - oldHeight; - [popup setBounds:popupFrame]; - animatingNotificationIDs_.insert([popup notificationID]); - } - } - - // Notification update could be received when a notification is excluded from - // the popup notification list but still remains in the full notification - // list, as in clicking the popup. In that case, the popup should be closed. - for (auto iter = pendingUpdateNotificationIDs_.begin(); - iter != pendingUpdateNotificationIDs_.end(); ++iter) { - pendingRemoveNotificationIDs_.insert(*iter); - } - - pendingUpdateNotificationIDs_.clear(); - - // Start re-layout of all notifications, so that it readjusts the Y origin of - // all updated popups and any popups that come below them. - [self layoutNotifications]; -} - -@end
diff --git a/ui/message_center/cocoa/popup_collection_unittest.mm b/ui/message_center/cocoa/popup_collection_unittest.mm deleted file mode 100644 index d431496..0000000 --- a/ui/message_center/cocoa/popup_collection_unittest.mm +++ /dev/null
@@ -1,348 +0,0 @@ -// Copyright (c) 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. - -#import "ui/message_center/cocoa/popup_collection.h" - -#include <memory> -#include <utility> - -#include "base/mac/scoped_nsobject.h" -#include "base/run_loop.h" -#include "base/strings/sys_string_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/test/scoped_task_environment.h" -#import "ui/base/test/cocoa_helper.h" -#import "ui/message_center/cocoa/notification_controller.h" -#import "ui/message_center/cocoa/popup_controller.h" -#include "ui/message_center/message_center.h" -#include "ui/message_center/public/cpp/message_center_constants.h" -#include "ui/message_center/public/cpp/notification.h" - -using base::ASCIIToUTF16; - -namespace message_center { - -class PopupCollectionTest : public ui::CocoaTest { - public: - PopupCollectionTest() - : scoped_task_environment_( - base::test::ScopedTaskEnvironment::MainThreadType::UI) { - message_center::MessageCenter::Initialize(); - center_ = message_center::MessageCenter::Get(); - collection_.reset( - [[MCPopupCollection alloc] initWithMessageCenter:center_]); - [collection_ setAnimationDuration:0.001]; - [collection_ setAnimationEndedCallback:^{ - if (nested_run_loop_.get()) - nested_run_loop_->Quit(); - }]; - } - - void TearDown() override { - collection_.reset(); // Close all popups. - ui::CocoaTest::TearDown(); - } - - ~PopupCollectionTest() override { message_center::MessageCenter::Shutdown(); } - - message_center::NotifierId DummyNotifierId() { - return message_center::NotifierId(); - } - - void AddThreeNotifications() { - std::unique_ptr<message_center::Notification> notification; - notification.reset(new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "1", ASCIIToUTF16("One"), - ASCIIToUTF16("This is the first notification to" - " be displayed"), - gfx::Image(), base::string16(), GURL(), DummyNotifierId(), - message_center::RichNotificationData(), NULL)); - center_->AddNotification(std::move(notification)); - - notification.reset(new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "2", ASCIIToUTF16("Two"), - ASCIIToUTF16("This is the second notification."), gfx::Image(), - base::string16(), GURL(), DummyNotifierId(), - message_center::RichNotificationData(), NULL)); - center_->AddNotification(std::move(notification)); - - notification.reset(new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "3", ASCIIToUTF16("Three"), - ASCIIToUTF16("This is the third notification " - "that has a much longer body " - "than the other notifications. It " - "may not fit on the screen if we " - "set the screen size too small or " - "if the notification is way too big"), - gfx::Image(), base::string16(), GURL(), DummyNotifierId(), - message_center::RichNotificationData(), NULL)); - center_->AddNotification(std::move(notification)); - WaitForAnimationEnded(); - } - - bool CheckSpacingBetween(MCPopupController* upper, MCPopupController* lower) { - CGFloat minY = NSMinY([[upper window] frame]); - CGFloat maxY = NSMaxY([[lower window] frame]); - CGFloat delta = minY - maxY; - EXPECT_EQ(message_center::kMarginBetweenPopups, delta); - return delta == message_center::kMarginBetweenPopups; - } - - void WaitForAnimationEnded() { - if (![collection_ isAnimating]) - return; - nested_run_loop_.reset(new base::RunLoop()); - nested_run_loop_->Run(); - nested_run_loop_.reset(); - } - - base::test::ScopedTaskEnvironment scoped_task_environment_; - std::unique_ptr<base::RunLoop> nested_run_loop_; - message_center::MessageCenter* center_; - base::scoped_nsobject<MCPopupCollection> collection_; -}; - -TEST_F(PopupCollectionTest, AddThreeCloseOne) { - EXPECT_EQ(0u, [[collection_ popups] count]); - AddThreeNotifications(); - EXPECT_EQ(3u, [[collection_ popups] count]); - - center_->RemoveNotification("2", true); - WaitForAnimationEnded(); - EXPECT_EQ(2u, [[collection_ popups] count]); -} - -TEST_F(PopupCollectionTest, AttemptFourOneOffscreen) { - [collection_ setScreenFrame:NSMakeRect(0, 0, 800, 300)]; - - EXPECT_EQ(0u, [[collection_ popups] count]); - AddThreeNotifications(); - EXPECT_EQ(2u, [[collection_ popups] count]); // "3" does not fit on screen. - - std::unique_ptr<message_center::Notification> notification; - - notification.reset(new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "4", ASCIIToUTF16("Four"), - ASCIIToUTF16("This is the fourth notification."), gfx::Image(), - base::string16(), GURL(), DummyNotifierId(), - message_center::RichNotificationData(), NULL)); - center_->AddNotification(std::move(notification)); - WaitForAnimationEnded(); - - // Remove "1" and "3" should fit on screen. - center_->RemoveNotification("1", true); - WaitForAnimationEnded(); - ASSERT_EQ(2u, [[collection_ popups] count]); - - EXPECT_EQ("2", [[[collection_ popups] objectAtIndex:0] notificationID]); - EXPECT_EQ("3", [[[collection_ popups] objectAtIndex:1] notificationID]); - - // Remove "2" and "4" should fit on screen. - center_->RemoveNotification("2", true); - WaitForAnimationEnded(); - ASSERT_EQ(2u, [[collection_ popups] count]); - - EXPECT_EQ("3", [[[collection_ popups] objectAtIndex:0] notificationID]); - EXPECT_EQ("4", [[[collection_ popups] objectAtIndex:1] notificationID]); -} - -TEST_F(PopupCollectionTest, LayoutSpacing) { - const CGFloat kScreenSize = 500; - [collection_ setScreenFrame:NSMakeRect(0, 0, kScreenSize, kScreenSize)]; - - AddThreeNotifications(); - NSArray* popups = [collection_ popups]; - - EXPECT_EQ(message_center::kMarginBetweenPopups, - kScreenSize - NSMaxY([[[popups objectAtIndex:0] window] frame])); - - EXPECT_TRUE(CheckSpacingBetween([popups objectAtIndex:0], - [popups objectAtIndex:1])); - EXPECT_TRUE(CheckSpacingBetween([popups objectAtIndex:1], - [popups objectAtIndex:2])); - - // Set priority so that kMaxVisiblePopupNotifications does not hide it. - message_center::RichNotificationData optional; - optional.priority = message_center::HIGH_PRIORITY; - std::unique_ptr<message_center::Notification> notification; - notification.reset(new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "4", ASCIIToUTF16("Four"), - ASCIIToUTF16("This is the fourth notification."), gfx::Image(), - base::string16(), GURL(), DummyNotifierId(), optional, NULL)); - center_->AddNotification(std::move(notification)); - WaitForAnimationEnded(); - EXPECT_TRUE(CheckSpacingBetween([popups objectAtIndex:2], - [popups objectAtIndex:3])); - - // Remove "2". - center_->RemoveNotification("2", true); - WaitForAnimationEnded(); - EXPECT_TRUE(CheckSpacingBetween([popups objectAtIndex:0], - [popups objectAtIndex:1])); - EXPECT_TRUE(CheckSpacingBetween([popups objectAtIndex:1], - [popups objectAtIndex:2])); - - // Remove "1". - center_->RemoveNotification("2", true); - WaitForAnimationEnded(); - EXPECT_EQ(message_center::kMarginBetweenPopups, - kScreenSize - NSMaxY([[[popups objectAtIndex:0] window] frame])); - EXPECT_TRUE(CheckSpacingBetween([popups objectAtIndex:0], - [popups objectAtIndex:1])); -} - -TEST_F(PopupCollectionTest, TinyScreen) { - [collection_ setScreenFrame:NSMakeRect(0, 0, 800, 100)]; - - EXPECT_EQ(0u, [[collection_ popups] count]); - std::unique_ptr<message_center::Notification> notification; - notification.reset(new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "1", ASCIIToUTF16("One"), - ASCIIToUTF16("This is the first notification to" - " be displayed"), - gfx::Image(), base::string16(), GURL(), DummyNotifierId(), - message_center::RichNotificationData(), NULL)); - center_->AddNotification(std::move(notification)); - WaitForAnimationEnded(); - EXPECT_EQ(1u, [[collection_ popups] count]); - - // Now give the notification a longer message so that it no longer fits. - notification.reset(new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "1", ASCIIToUTF16("One"), - ASCIIToUTF16("This is now a very very very very " - "very very very very very very very " - "very very very very very very very " - "very very very very very very very " - "very very very very very very very " - "very very very very very very very " - "very very very very very very very " - "long notification."), - gfx::Image(), base::string16(), GURL(), DummyNotifierId(), - message_center::RichNotificationData(), NULL)); - center_->UpdateNotification("1", std::move(notification)); - WaitForAnimationEnded(); - EXPECT_EQ(0u, [[collection_ popups] count]); -} - -TEST_F(PopupCollectionTest, UpdateIconAndBody) { - AddThreeNotifications(); - NSArray* popups = [collection_ popups]; - - EXPECT_EQ(3u, [popups count]); - - // Update "2" icon. - MCNotificationController* controller = - [[popups objectAtIndex:1] notificationController]; - EXPECT_FALSE([[controller iconView] image]); - center_->SetNotificationIcon( - "2", gfx::Image([NSImage imageNamed:NSImageNameUser])); - WaitForAnimationEnded(); - EXPECT_TRUE([[controller iconView] image]); - - EXPECT_EQ(3u, [popups count]); - EXPECT_TRUE(CheckSpacingBetween([popups objectAtIndex:0], - [popups objectAtIndex:1])); - EXPECT_TRUE(CheckSpacingBetween([popups objectAtIndex:1], - [popups objectAtIndex:2])); - - // Replace "1". - controller = [[popups objectAtIndex:0] notificationController]; - NSRect old_frame = [[controller view] frame]; - std::unique_ptr<message_center::Notification> notification; - notification.reset(new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "1", - ASCIIToUTF16("One is going to get a much longer " - "title than it previously had."), - ASCIIToUTF16("This is the first notification to " - "be displayed, but it will also be " - "updated to have a significantly " - "longer body"), - gfx::Image(), base::string16(), GURL(), DummyNotifierId(), - message_center::RichNotificationData(), NULL)); - center_->AddNotification(std::move(notification)); - WaitForAnimationEnded(); - EXPECT_GT(NSHeight([[controller view] frame]), NSHeight(old_frame)); - - // Test updated spacing. - EXPECT_EQ(3u, [popups count]); - EXPECT_TRUE(CheckSpacingBetween([popups objectAtIndex:0], - [popups objectAtIndex:1])); - EXPECT_TRUE(CheckSpacingBetween([popups objectAtIndex:1], - [popups objectAtIndex:2])); - EXPECT_EQ("1", [[popups objectAtIndex:0] notificationID]); - EXPECT_EQ("2", [[popups objectAtIndex:1] notificationID]); - EXPECT_EQ("3", [[popups objectAtIndex:2] notificationID]); -} - -TEST_F(PopupCollectionTest, UpdatePriority) { - std::unique_ptr<message_center::Notification> notification; - notification.reset(new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "1", ASCIIToUTF16("One"), - ASCIIToUTF16("This notification should not yet toast."), gfx::Image(), - base::string16(), GURL(), DummyNotifierId(), - message_center::RichNotificationData(), NULL)); - notification->set_priority(-1); - - center_->AddNotification(std::move(notification)); - WaitForAnimationEnded(); - NSArray* popups = [collection_ popups]; - EXPECT_EQ(0u, [popups count]); - - // Raise priority -1 to 1. Notification should display. - notification.reset(new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "1", ASCIIToUTF16("One"), - ASCIIToUTF16("This notification should now toast"), gfx::Image(), - base::string16(), GURL(), DummyNotifierId(), - message_center::RichNotificationData(), NULL)); - notification->set_priority(1); - - center_->UpdateNotification("1", std::move(notification)); - WaitForAnimationEnded(); - EXPECT_EQ(1u, [popups count]); -} - -TEST_F(PopupCollectionTest, CloseCollectionBeforeNewPopupAnimationEnds) { - // Add a notification and don't wait for the animation to finish. - std::unique_ptr<message_center::Notification> notification; - notification.reset(new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "1", ASCIIToUTF16("One"), - ASCIIToUTF16("This is the first notification to" - " be displayed"), - gfx::Image(), base::string16(), GURL(), DummyNotifierId(), - message_center::RichNotificationData(), NULL)); - center_->AddNotification(std::move(notification)); - - // Release the popup collection before the animation ends. No crash should - // be expected. - collection_.reset(); -} - -TEST_F(PopupCollectionTest, CloseCollectionBeforeClosePopupAnimationEnds) { - AddThreeNotifications(); - - // Remove a notification and don't wait for the animation to finish. - center_->RemoveNotification("1", true); - - // Release the popup collection before the animation ends. No crash should - // be expected. - collection_.reset(); -} - -TEST_F(PopupCollectionTest, CloseCollectionBeforeUpdatePopupAnimationEnds) { - AddThreeNotifications(); - - // Update a notification and don't wait for the animation to finish. - std::unique_ptr<message_center::Notification> notification; - notification.reset(new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "1", ASCIIToUTF16("One"), - ASCIIToUTF16("New message."), gfx::Image(), base::string16(), GURL(), - DummyNotifierId(), message_center::RichNotificationData(), NULL)); - center_->UpdateNotification("1", std::move(notification)); - - // Release the popup collection before the animation ends. No crash should - // be expected. - collection_.reset(); -} - -} // namespace message_center
diff --git a/ui/message_center/cocoa/popup_controller.h b/ui/message_center/cocoa/popup_controller.h deleted file mode 100644 index f8527823..0000000 --- a/ui/message_center/cocoa/popup_controller.h +++ /dev/null
@@ -1,99 +0,0 @@ -// Copyright (c) 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 UI_MESSAGE_CENTER_COCOA_POPUP_CONTROLLER_H_ -#define UI_MESSAGE_CENTER_COCOA_POPUP_CONTROLLER_H_ - -#import <Cocoa/Cocoa.h> - -#include <string> - -#import "base/mac/scoped_nsobject.h" -#import "ui/base/cocoa/tracking_area.h" -#include "ui/message_center/message_center_export.h" - -namespace message_center { -class MessageCenter; -class Notification; -} - -@class MCNotificationController; -@class MCPopupCollection; - -// A window controller that hosts a notification as a popup balloon on the -// user's desktop. The window controller manages its lifetime because the -// popup collection will be destructed when the last popup is closed. -MESSAGE_CENTER_EXPORT -@interface MCPopupController : NSWindowController<NSAnimationDelegate> { - @private - // Global message center. Weak. - message_center::MessageCenter* messageCenter_; - - // The collection that contains the popup. Weak. - MCPopupCollection* popupCollection_; - - // The view controller that provide's the popup content view. - base::scoped_nsobject<MCNotificationController> notificationController_; - - // If the swipe-away gesture received NSEventPhaseEnded. - BOOL swipeGestureEnded_; - - // The frame of the popup before any swipe animation started. Used to - // calculate the animating position of the window when swiping away. - NSRect originalFrame_; - - // Is the popup currently being closed? - BOOL isClosing_; - -#ifndef NDEBUG - // Has the popup been closed before being dealloc-ed. - BOOL hasBeenClosed_; -#endif - - // The current bounds of the popup frame if no animation is playing. - // Otherwise, it is the target bounds of the popup frame. - NSRect bounds_; - - // Used to play animation when the popup shows, changes bounds and closes. - base::scoped_nsobject<NSViewAnimation> boundsAnimation_; - - // Used to track the popup for mouse entered and exited events. - ui::ScopedCrTrackingArea trackingArea_; -} - -// Designated initializer. -- (id)initWithNotification:(const message_center::Notification*)notification - messageCenter:(message_center::MessageCenter*)messageCenter - popupCollection:(MCPopupCollection*)popupCollection; - -// Accessor for the view controller. -- (MCNotificationController*)notificationController; - -// Accessor for the notification model object. -- (const message_center::Notification*)notification; - -// Gets the notification ID. This string is owned by the NotificationController -// rather than the model object, so it's safe to use after the Notification has -// been deleted. -- (const std::string&)notificationID; - -// Shows the window with the sliding animation. -- (void)showWithAnimation:(NSRect)newBounds; - -// Closes the window with the fade-out animation. -- (void)closeWithAnimation; - -// Tells that the popupCollection_ is gone. -- (void)markPopupCollectionGone; - -// Returns the window bounds. This is the target bounds to go to if the bounds -// animation is playing. -- (NSRect)bounds; - -// Changes the window bounds with animation. -- (void)setBounds:(NSRect)newBounds; - -@end - -#endif // UI_MESSAGE_CENTER_COCOA_POPUP_CONTROLLER_H_
diff --git a/ui/message_center/cocoa/popup_controller.mm b/ui/message_center/cocoa/popup_controller.mm deleted file mode 100644 index e8e77281..0000000 --- a/ui/message_center/cocoa/popup_controller.mm +++ /dev/null
@@ -1,296 +0,0 @@ -// Copyright (c) 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. - -#import "ui/message_center/cocoa/popup_controller.h" - -#include <cmath> - -#import "base/mac/foundation_util.h" -#import "base/mac/sdk_forward_declarations.h" -#import "ui/base/cocoa/window_size_constants.h" -#import "ui/message_center/cocoa/notification_controller.h" -#import "ui/message_center/cocoa/popup_collection.h" -#include "ui/message_center/message_center.h" - -//////////////////////////////////////////////////////////////////////////////// - -@interface MCPopupController (Private) -- (void)notificationSwipeStarted; -- (void)notificationSwipeMoved:(CGFloat)amount; -- (void)notificationSwipeEnded:(BOOL)ended complete:(BOOL)isComplete; - -// This setter for |boundsAnimation_| also cleans up the state of the previous -// |boundsAnimation_|. -- (void)setBoundsAnimation:(NSViewAnimation*)animation; - -// Constructs an NSViewAnimation from |dictionary|, which should be a view -// animation dictionary. -- (NSViewAnimation*)animationWithDictionary:(NSDictionary*)dictionary; -@end - -// Window Subclass ///////////////////////////////////////////////////////////// - -@interface MCPopupWindow : NSPanel { - // The cumulative X and Y scrollingDeltas since the -scrollWheel: event began. - NSPoint totalScrollDelta_; -} -@end - -@implementation MCPopupWindow - -- (void)scrollWheel:(NSEvent*)event { - // Gesture swiping only exists on 10.7+. - if (![event respondsToSelector:@selector(phase)]) - return; - - NSEventPhase phase = [event phase]; - BOOL shouldTrackSwipe = NO; - - if (phase == NSEventPhaseBegan) { - totalScrollDelta_ = NSZeroPoint; - } else if (phase == NSEventPhaseChanged) { - shouldTrackSwipe = YES; - totalScrollDelta_.x += [event scrollingDeltaX]; - totalScrollDelta_.y += [event scrollingDeltaY]; - } - - // Only allow horizontal scrolling. - if (std::abs(totalScrollDelta_.x) < std::abs(totalScrollDelta_.y)) - return; - - if (shouldTrackSwipe) { - MCPopupController* controller = - base::mac::ObjCCastStrict<MCPopupController>([self windowController]); - BOOL directionInverted = [event isDirectionInvertedFromDevice]; - - auto handler = ^(CGFloat gestureAmount, NSEventPhase phase, - BOOL isComplete, BOOL* stop) { - // The swipe direction should match the direction the user's fingers - // are moving, not the interpreted scroll direction. - if (directionInverted) - gestureAmount *= -1; - - if (phase == NSEventPhaseBegan) { - [controller notificationSwipeStarted]; - return; - } - - [controller notificationSwipeMoved:gestureAmount]; - - BOOL ended = phase == NSEventPhaseEnded; - if (ended || isComplete) - [controller notificationSwipeEnded:ended complete:isComplete]; - }; - [event trackSwipeEventWithOptions:NSEventSwipeTrackingLockDirection - dampenAmountThresholdMin:-1 - max:1 - usingHandler:handler]; - } -} - -@end - -//////////////////////////////////////////////////////////////////////////////// - -@implementation MCPopupController - -- (id)initWithNotification:(const message_center::Notification*)notification - messageCenter:(message_center::MessageCenter*)messageCenter - popupCollection:(MCPopupCollection*)popupCollection { - base::scoped_nsobject<MCPopupWindow> window([[MCPopupWindow alloc] - initWithContentRect:ui::kWindowSizeDeterminedLater - styleMask:NSNonactivatingPanelMask - backing:NSBackingStoreBuffered - defer:NO]); - if ((self = [super initWithWindow:window])) { - messageCenter_ = messageCenter; - popupCollection_ = popupCollection; - notificationController_.reset( - [[MCNotificationController alloc] initWithNotification:notification - messageCenter:messageCenter_]); - bounds_ = [[notificationController_ view] frame]; - - [window setFloatingPanel:YES]; - [window setBecomesKeyOnlyIfNeeded:YES]; - [window - setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces | - NSWindowCollectionBehaviorFullScreenAuxiliary]; - - [window setHasShadow:YES]; - [window setContentView:[notificationController_ view]]; - - trackingArea_.reset( - [[CrTrackingArea alloc] initWithRect:NSZeroRect - options:NSTrackingInVisibleRect | - NSTrackingMouseEnteredAndExited | - NSTrackingActiveAlways - owner:self - userInfo:nil]); - [[window contentView] addTrackingArea:trackingArea_.get()]; - } - return self; -} - -#ifndef NDEBUG -- (void)dealloc { - DCHECK(hasBeenClosed_); - [super dealloc]; -} -#endif - -- (void)close { -#ifndef NDEBUG - hasBeenClosed_ = YES; -#endif - [self setBoundsAnimation:nil]; - if (trackingArea_.get()) - [[[self window] contentView] removeTrackingArea:trackingArea_.get()]; - [super close]; - [self performSelectorOnMainThread:@selector(release) - withObject:nil - waitUntilDone:NO - modes:@[ NSDefaultRunLoopMode ]]; -} - -- (MCNotificationController*)notificationController { - return notificationController_.get(); -} - -- (const message_center::Notification*)notification { - return [notificationController_ notification]; -} - -- (const std::string&)notificationID { - return [notificationController_ notificationID]; -} - -// Private ///////////////////////////////////////////////////////////////////// - -- (void)notificationSwipeStarted { - originalFrame_ = [[self window] frame]; - swipeGestureEnded_ = NO; -} - -- (void)notificationSwipeMoved:(CGFloat)amount { - NSWindow* window = [self window]; - - [window setAlphaValue:1.0 - std::abs(amount)]; - NSRect frame = [window frame]; - CGFloat originalMin = NSMinX(originalFrame_); - frame.origin.x = originalMin + (NSMidX(originalFrame_) - originalMin) * - -amount; - [window setFrame:frame display:YES]; -} - -- (void)notificationSwipeEnded:(BOOL)ended complete:(BOOL)isComplete { - swipeGestureEnded_ |= ended; - if (swipeGestureEnded_ && isComplete) { - messageCenter_->RemoveNotification([self notificationID], /*by_user=*/true); - [popupCollection_ onPopupAnimationEnded:[self notificationID]]; - } -} - -- (void)setBoundsAnimation:(NSViewAnimation*)animation { - [boundsAnimation_ stopAnimation]; - [boundsAnimation_ setDelegate:nil]; - boundsAnimation_.reset([animation retain]); -} - -- (NSViewAnimation*)animationWithDictionary:(NSDictionary*)dictionary { - return [[[NSViewAnimation alloc] - initWithViewAnimations:@[ dictionary ]] autorelease]; -} - -- (void)animationDidEnd:(NSAnimation*)animation { - DCHECK_EQ(animation, boundsAnimation_.get()); - [self setBoundsAnimation:nil]; - - [popupCollection_ onPopupAnimationEnded:[self notificationID]]; - - if (isClosing_) - [self close]; -} - -- (void)showWithAnimation:(NSRect)newBounds { - bounds_ = newBounds; - NSRect startBounds = newBounds; - startBounds.origin.x += startBounds.size.width; - [[self window] setFrame:startBounds display:NO]; - [[self window] setAlphaValue:0]; - [[self window] setCanHide:NO]; - [self showWindow:nil]; - - // Slide-in and fade-in simultaneously. - NSDictionary* animationDict = @{ - NSViewAnimationTargetKey : [self window], - NSViewAnimationEndFrameKey : [NSValue valueWithRect:newBounds], - NSViewAnimationEffectKey : NSViewAnimationFadeInEffect - }; - NSViewAnimation* animation = [self animationWithDictionary:animationDict]; - [self setBoundsAnimation:animation]; - [boundsAnimation_ setDuration:[popupCollection_ popupAnimationDuration]]; - [boundsAnimation_ setDelegate:self]; - [boundsAnimation_ startAnimation]; -} - -- (void)closeWithAnimation { - if (isClosing_) - return; - -#ifndef NDEBUG - hasBeenClosed_ = YES; -#endif - isClosing_ = YES; - - // If the notification was swiped closed, do not animate it as the - // notification has already faded out. - if (swipeGestureEnded_) { - [self close]; - return; - } - - NSDictionary* animationDict = @{ - NSViewAnimationTargetKey : [self window], - NSViewAnimationEffectKey : NSViewAnimationFadeOutEffect - }; - NSViewAnimation* animation = [self animationWithDictionary:animationDict]; - [self setBoundsAnimation:animation]; - [boundsAnimation_ setDuration:[popupCollection_ popupAnimationDuration]]; - [boundsAnimation_ setDelegate:self]; - [boundsAnimation_ startAnimation]; -} - -- (void)markPopupCollectionGone { - popupCollection_ = nil; -} - -- (NSRect)bounds { - return bounds_; -} - -- (void)setBounds:(NSRect)newBounds { - if (isClosing_ || NSEqualRects(bounds_ , newBounds)) - return; - bounds_ = newBounds; - - NSDictionary* animationDict = @{ - NSViewAnimationTargetKey : [self window], - NSViewAnimationEndFrameKey : [NSValue valueWithRect:newBounds] - }; - NSViewAnimation* animation = [self animationWithDictionary:animationDict]; - [self setBoundsAnimation:animation]; - [boundsAnimation_ setDuration:[popupCollection_ popupAnimationDuration]]; - [boundsAnimation_ setDelegate:self]; - [boundsAnimation_ startAnimation]; -} - -- (void)mouseEntered:(NSEvent*)event { - messageCenter_->PausePopupTimers(); -} - -- (void)mouseExited:(NSEvent*)event { - messageCenter_->RestartPopupTimers(); -} - -@end
diff --git a/ui/message_center/cocoa/popup_controller_unittest.mm b/ui/message_center/cocoa/popup_controller_unittest.mm deleted file mode 100644 index 191b2d6..0000000 --- a/ui/message_center/cocoa/popup_controller_unittest.mm +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright (c) 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. - -#import "ui/message_center/cocoa/popup_controller.h" - -#include <memory> - -#include "base/mac/scoped_nsobject.h" -#include "base/strings/sys_string_conversions.h" -#include "base/strings/utf_string_conversions.h" -#import "ui/base/test/cocoa_helper.h" -#include "ui/message_center/public/cpp/notification.h" - -using base::ASCIIToUTF16; - -namespace message_center { - -class PopupControllerTest : public ui::CocoaTest { -}; - -TEST_F(PopupControllerTest, Creation) { - std::unique_ptr<message_center::Notification> notification( - new message_center::Notification( - message_center::NOTIFICATION_TYPE_SIMPLE, "", - ASCIIToUTF16("Added to circles"), - ASCIIToUTF16("Jonathan and 5 others"), gfx::Image(), base::string16(), - GURL(), message_center::NotifierId(), - message_center::RichNotificationData(), NULL)); - - base::scoped_nsobject<MCPopupController> controller( - [[MCPopupController alloc] initWithNotification:notification.get() - messageCenter:nil - popupCollection:nil]); - // Add an extra ref count for scoped_nsobject since MCPopupController will - // release itself when it is being closed. - [controller retain]; - - EXPECT_TRUE([controller window]); - EXPECT_EQ(notification.get(), [controller notification]); - - [controller showWindow:nil]; - [controller close]; -} - -} // namespace message_center
diff --git a/ui/message_center/test/run_all_unittests.cc b/ui/message_center/test/run_all_unittests.cc index 518bd314..31dab46c 100644 --- a/ui/message_center/test/run_all_unittests.cc +++ b/ui/message_center/test/run_all_unittests.cc
@@ -16,10 +16,6 @@ #include "ui/base/ui_base_paths.h" #include "ui/gl/test/gl_surface_test_support.h" -#if defined(OS_MACOSX) -#include "base/test/mock_chrome_application_mac.h" -#endif - namespace { class MessageCenterTestSuite : public base::TestSuite { @@ -28,9 +24,6 @@ protected: void Initialize() override { -#if defined(OS_MACOSX) - mock_cr_app::RegisterMockCrApp(); -#endif gl::GLSurfaceTestSupport::InitializeOneOff(); base::TestSuite::Initialize(); ui::RegisterPathProvider();
diff --git a/ui/message_center/views/bounded_label_unittest.cc b/ui/message_center/views/bounded_label_unittest.cc index bcdae91..45e4560 100644 --- a/ui/message_center/views/bounded_label_unittest.cc +++ b/ui/message_center/views/bounded_label_unittest.cc
@@ -8,12 +8,17 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/font_list.h" #include "ui/gfx/text_utils.h" #include "ui/views/controls/label.h" #include "ui/views/test/views_test_base.h" +#if defined(OS_MACOSX) +#include "base/mac/mac_util.h" +#endif + namespace message_center { namespace test { @@ -101,6 +106,13 @@ /* Elision tests **************************************************************/ TEST_F(BoundedLabelTest, GetWrappedTextTest) { +#if defined(OS_MACOSX) + // Skip this test on macOS 10.10, which has slightly different font metrics + // than the other OSes we support. + if (base::mac::IsOS10_10()) + return; +#endif + // One word per line: No ellision should be made when not necessary. TEST_WRAP("123", "123", 301, 1); TEST_WRAP("123", "123", 301, 2); @@ -110,9 +122,9 @@ TEST_WRAP("123\n456\n789", "123 456 789", 301, 3); // One word per line: Ellisions should be made when necessary. - TEST_WRAP("123...", "123 456", 301, 1); - TEST_WRAP("123...", "123 456 789", 301, 1); - TEST_WRAP("123\n456...", "123 456 789", 301, 2); + TEST_WRAP("123...", "123 456", 302, 1); + TEST_WRAP("123...", "123 456 789", 302, 1); + TEST_WRAP("123\n456...", "123 456 789", 302, 2); // Two words per line: No ellision should be made when not necessary. TEST_WRAP("123 456", "123 456", 621, 1);
diff --git a/ui/ozone/platform/drm/ozone_platform_gbm.cc b/ui/ozone/platform/drm/ozone_platform_gbm.cc index f3e5c12..b7f7999 100644 --- a/ui/ozone/platform/drm/ozone_platform_gbm.cc +++ b/ui/ozone/platform/drm/ozone_platform_gbm.cc
@@ -61,9 +61,8 @@ class OzonePlatformGbm : public OzonePlatform { public: - OzonePlatformGbm() - : using_mojo_(false), single_process_(false), weak_factory_(this) {} - ~OzonePlatformGbm() override {} + OzonePlatformGbm() = default; + ~OzonePlatformGbm() override = default; // OzonePlatform: ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override { @@ -291,8 +290,8 @@ } private: - bool using_mojo_; - bool single_process_; + bool using_mojo_ = false; + bool single_process_ = false; // Objects in the GPU process. std::unique_ptr<DrmThreadProxy> drm_thread_proxy_; @@ -304,7 +303,7 @@ // running in single process mode. std::vector<ozone::mojom::DeviceCursorRequest> pending_cursor_requests_; std::vector<ozone::mojom::DrmDeviceRequest> pending_gpu_adapter_requests_; - bool drm_thread_started_; + bool drm_thread_started_ = false; // gpu_platform_support_host_ is the IPC bridge to the GPU process while // host_drm_device_ is the mojo bridge to the Viz process. Only one can be in @@ -333,7 +332,7 @@ XkbEvdevCodes xkb_evdev_code_converter_; #endif - base::WeakPtrFactory<OzonePlatformGbm> weak_factory_; + base::WeakPtrFactory<OzonePlatformGbm> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(OzonePlatformGbm); };
diff --git a/ui/ozone/platform/scenic/scenic_window.cc b/ui/ozone/platform/scenic/scenic_window.cc index e0c38fe..4edb27c1 100644 --- a/ui/ozone/platform/scenic/scenic_window.cc +++ b/ui/ozone/platform/scenic/scenic_window.cc
@@ -46,7 +46,6 @@ parent_node_.BindAsRequest(&parent_export_token); // Setup entity node for the window. - parent_node_.AddChild(node_); node_.AddChild(shape_node_); shape_node_.SetMaterial(material_); @@ -106,15 +105,16 @@ } void ScenicWindow::Show() { - NOTIMPLEMENTED(); + parent_node_.AddChild(node_); } void ScenicWindow::Hide() { - NOTIMPLEMENTED(); + node_.Detach(); } void ScenicWindow::Close() { - NOTIMPLEMENTED(); + Hide(); + delegate_->OnClosed(); } void ScenicWindow::PrepareForShutdown() {
diff --git a/ui/resources/default_100_percent/common/notification_close.png b/ui/resources/default_100_percent/common/notification_close.png deleted file mode 100644 index 02e1f91..0000000 --- a/ui/resources/default_100_percent/common/notification_close.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_100_percent/common/notification_close_hover.png b/ui/resources/default_100_percent/common/notification_close_hover.png deleted file mode 100644 index aeafd96..0000000 --- a/ui/resources/default_100_percent/common/notification_close_hover.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_100_percent/common/notification_close_pressed.png b/ui/resources/default_100_percent/common/notification_close_pressed.png deleted file mode 100644 index 1c4ad59..0000000 --- a/ui/resources/default_100_percent/common/notification_close_pressed.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_100_percent/common/notification_settings_button.png b/ui/resources/default_100_percent/common/notification_settings_button.png deleted file mode 100644 index 741241e..0000000 --- a/ui/resources/default_100_percent/common/notification_settings_button.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_100_percent/common/notification_settings_button_hover.png b/ui/resources/default_100_percent/common/notification_settings_button_hover.png deleted file mode 100644 index fcd210f9..0000000 --- a/ui/resources/default_100_percent/common/notification_settings_button_hover.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_100_percent/common/notification_settings_button_pressed.png b/ui/resources/default_100_percent/common/notification_settings_button_pressed.png deleted file mode 100644 index a5194b1..0000000 --- a/ui/resources/default_100_percent/common/notification_settings_button_pressed.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_100_percent/win/notification_close.png b/ui/resources/default_100_percent/win/notification_close.png deleted file mode 100644 index 064d51d..0000000 --- a/ui/resources/default_100_percent/win/notification_close.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_100_percent/win/notification_close_hover.png b/ui/resources/default_100_percent/win/notification_close_hover.png deleted file mode 100644 index 1af2c59e..0000000 --- a/ui/resources/default_100_percent/win/notification_close_hover.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_100_percent/win/notification_close_pressed.png b/ui/resources/default_100_percent/win/notification_close_pressed.png deleted file mode 100644 index 981546c..0000000 --- a/ui/resources/default_100_percent/win/notification_close_pressed.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_200_percent/common/notification_close.png b/ui/resources/default_200_percent/common/notification_close.png deleted file mode 100644 index 80f4b9c2..0000000 --- a/ui/resources/default_200_percent/common/notification_close.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_200_percent/common/notification_close_hover.png b/ui/resources/default_200_percent/common/notification_close_hover.png deleted file mode 100644 index 743d005e..0000000 --- a/ui/resources/default_200_percent/common/notification_close_hover.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_200_percent/common/notification_close_pressed.png b/ui/resources/default_200_percent/common/notification_close_pressed.png deleted file mode 100644 index 07b69cc..0000000 --- a/ui/resources/default_200_percent/common/notification_close_pressed.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_200_percent/common/notification_settings_button.png b/ui/resources/default_200_percent/common/notification_settings_button.png deleted file mode 100644 index e6623dae..0000000 --- a/ui/resources/default_200_percent/common/notification_settings_button.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_200_percent/common/notification_settings_button_hover.png b/ui/resources/default_200_percent/common/notification_settings_button_hover.png deleted file mode 100644 index c316bd4d..0000000 --- a/ui/resources/default_200_percent/common/notification_settings_button_hover.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_200_percent/common/notification_settings_button_pressed.png b/ui/resources/default_200_percent/common/notification_settings_button_pressed.png deleted file mode 100644 index 56e4082..0000000 --- a/ui/resources/default_200_percent/common/notification_settings_button_pressed.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_200_percent/win/notification_close.png b/ui/resources/default_200_percent/win/notification_close.png deleted file mode 100644 index 627afbca..0000000 --- a/ui/resources/default_200_percent/win/notification_close.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_200_percent/win/notification_close_hover.png b/ui/resources/default_200_percent/win/notification_close_hover.png deleted file mode 100644 index 196d6dc..0000000 --- a/ui/resources/default_200_percent/win/notification_close_hover.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_200_percent/win/notification_close_pressed.png b/ui/resources/default_200_percent/win/notification_close_pressed.png deleted file mode 100644 index 3b32dd0..0000000 --- a/ui/resources/default_200_percent/win/notification_close_pressed.png +++ /dev/null Binary files differ
diff --git a/ui/resources/ui_resources.grd b/ui/resources/ui_resources.grd index a2e33da..3a46c5f 100644 --- a/ui/resources/ui_resources.grd +++ b/ui/resources/ui_resources.grd
@@ -118,21 +118,8 @@ <if expr="is_macosx or is_ios"> <structure type="chrome_scaled_image" name="IDR_MENU_HIERARCHY_ARROW" file="mac/menu_hierarchy_arrow.png" /> </if> - <if expr="toolkit_views or is_ios"> - <if expr="is_win"> - <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_CLOSE" file="win/notification_close.png"/> - <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_CLOSE_HOVER" file="win/notification_close_hover.png"/> - <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_CLOSE_PRESSED" file="win/notification_close_pressed.png"/> - </if> - <if expr="not is_win"> - <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_CLOSE" file="common/notification_close.png"/> - <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_CLOSE_HOVER" file="common/notification_close_hover.png"/> - <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_CLOSE_PRESSED" file="common/notification_close_pressed.png"/> - </if> + <if expr="toolkit_views and not is_macosx"> <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_SETTINGS" file="common/notification_settings.png"/> - <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_SETTINGS_BUTTON_ICON" file="common/notification_settings_button.png"/> - <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_SETTINGS_BUTTON_ICON_HOVER" file="common/notification_settings_button_hover.png"/> - <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_SETTINGS_BUTTON_ICON_PRESSED" file="common/notification_settings_button_pressed.png"/> </if> <if expr="not is_android and not is_ios"> <structure type="chrome_scaled_image" name="IDR_NTP_DEFAULT_FAVICON" file="common/ntp_default_favicon.png" />
diff --git a/ui/snapshot/snapshot_aura_unittest.cc b/ui/snapshot/snapshot_aura_unittest.cc index 84854e5..20bcc42f 100644 --- a/ui/snapshot/snapshot_aura_unittest.cc +++ b/ui/snapshot/snapshot_aura_unittest.cc
@@ -30,7 +30,6 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size_conversions.h" -#include "ui/gfx/gfx_paths.h" #include "ui/gfx/image/image.h" #include "ui/gfx/transform.h" #include "ui/gl/gl_implementation.h"
diff --git a/ui/strings/translations/ui_strings_te.xtb b/ui/strings/translations/ui_strings_te.xtb index 96f106e..55af393 100644 --- a/ui/strings/translations/ui_strings_te.xtb +++ b/ui/strings/translations/ui_strings_te.xtb
@@ -41,7 +41,7 @@ <translation id="2289052229480071835">మీ స్క్రీన్పై ఉన్న స్పర్శ లక్ష్యాలను నొక్కండి.</translation> <translation id="2295140143284145483">సర్వే</translation> <translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation> -<translation id="24452542372838207">నోటిఫికేషన్ని విస్తరించు</translation> +<translation id="24452542372838207">నోటిఫికేషన్ను విస్తరించు</translation> <translation id="2445449901874883781">ఎక్కువ సాంద్రతను ఉపయోగించు</translation> <translation id="2482878487686419369">ప్రకటనలు</translation> <translation id="2497284189126895209">మొత్తం ఫైళ్లు</translation> @@ -184,7 +184,7 @@ <translation id="9002566407876343676">తెరువు</translation> <translation id="9038489124413477075">పేరులేని ఫోల్డర్</translation> <translation id="9044832324875206639">{SECONDS,plural, =1{1 సెక.}other{# సెక.}}</translation> -<translation id="9059834730836941392">నోటిఫికేషన్ని కుదించు</translation> +<translation id="9059834730836941392">నోటిఫికేషన్ను కుదించు</translation> <translation id="9150735707954472829">ట్యాబ్</translation> <translation id="9161053988251441839">సూచించబడిన అనువర్తనాలు</translation> <translation id="9170848237812810038">&అన్డు</translation>
diff --git a/ui/webui/resources/js/cr/ui/menu.js b/ui/webui/resources/js/cr/ui/menu.js index 5589cd6..7560a63 100644 --- a/ui/webui/resources/js/cr/ui/menu.js +++ b/ui/webui/resources/js/cr/ui/menu.js
@@ -202,26 +202,18 @@ }, /** - * Returns whether the menu has any visible items. Hides any separators - * where all items below it until the next separator are hidden. + * Returns whether the menu has any visible items. * @return {boolean} True if the menu has visible item. Otherwise, false. */ hasVisibleItems: function() { - var menuItems = this.menuItems; // Cache. - var result = false; - var separatorRequired = false; // Inspect items in reverse order to determine if the separator above each // set of items is required. - for (var i = menuItems.length - 1; i >= 0; i--) { - var menuItem = menuItems[i]; - if (menuItem.isSeparator()) { - menuItem.hidden = !separatorRequired; - separatorRequired = false; + for (let menuItem of this.menuItems) { + if (this.isItemVisible_(menuItem)) { + return true; } - if (this.isItemVisible_(menuItem)) - result = separatorRequired = true; } - return result; + return false; }, /** @@ -320,6 +312,27 @@ if (!menuItem.isSeparator()) menuItem.updateCommand(node); } + + let separatorRequired = false; + let lastSeparator = null; + // Hide any separators without a visible item between them and the next + // separator or the end of the menu. + for (let menuItem of menuItems) { + if (menuItem.isSeparator()) { + if (separatorRequired) { + lastSeparator = menuItem; + } + menuItem.hidden = true; + separatorRequired = false; + continue; + } + if (this.isItemVisible_(menuItem)) { + if (lastSeparator) { + lastSeparator.hidden = false; + } + separatorRequired = true; + } + } } };
diff --git a/ui/webui/resources/js/cr/ui/menu_test.html b/ui/webui/resources/js/cr/ui/menu_test.html deleted file mode 100644 index 05b601ed..0000000 --- a/ui/webui/resources/js/cr/ui/menu_test.html +++ /dev/null
@@ -1,67 +0,0 @@ -<!doctype html> -<html> -<head> -<script src="https://cdn.rawgit.com/google/closure-library/master/closure/goog/base.js"></script> -<script src="../../cr.js"></script> -<script src="../event_target.js"></script> -<script src="../ui.js"></script> -<script src="command.js"></script> -<script src="menu.js"></script> -<script src="menu_item.js"></script> -<script> - -goog.require('goog.testing.jsunit'); - -</script> - -</head> -<body> - -<script> - -/** - * Tests that if the command attributes are spacified, they are copied to the - * corresponding menuitem. - */ -function testCommandMenuItem() { - // Test 1: The case that the command label is set and other attributes copied. - var command = new cr.ui.Command(); - command.id = 'the-command'; - command.label = 'CommandLabel'; - command.disabled = true; - command.hidden = true; - command.checked = true; - document.body.appendChild(command); - - var menuItem = new cr.ui.MenuItem(); - menuItem.command = '#the-command'; - - // Confirms the label is copied from the command. - assertEquals('CommandLabel', menuItem.label); - // Confirms the attributes are copied from the command. - assertEquals(true, menuItem.disabled); - assertEquals(true, menuItem.hidden); - assertEquals(true, menuItem.checked); - - // Test 2: The case that the command label is not set, and other attributes - // have default values. - var command2 = new cr.ui.Command(); - command2.id = 'the-command2'; - document.body.appendChild(command2); - - var menuItem2 = new cr.ui.MenuItem(); - menuItem2.label = 'MenuLabel'; - menuItem2.command = '#the-command2'; - - // Confirms the label is not copied, keeping the original label. - assertEquals('MenuLabel', menuItem2.label); - // Confirms the attributes are copied from the command. - assertEquals(false, menuItem2.disabled); - assertEquals(false, menuItem2.hidden); - assertEquals(false, menuItem2.checked); -} - -</script> - -</body> -</html>
diff --git a/webrunner/browser/frame_impl.cc b/webrunner/browser/frame_impl.cc index 17768b1a..ab8cae4 100644 --- a/webrunner/browser/frame_impl.cc +++ b/webrunner/browser/frame_impl.cc
@@ -172,6 +172,7 @@ if (window_tree_host_) { aura::client::SetFocusClient(root_window(), nullptr); wm::SetActivationClient(root_window(), nullptr); + root_window()->RemovePreTargetHandler(focus_controller_.get()); web_contents_->ClosePage(); window_tree_host_->Hide(); window_tree_host_->compositor()->SetVisible(false);