diff --git a/AUTHORS b/AUTHORS index 0c5f126..17cdbe2 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -433,6 +433,7 @@ Jesse Miller <jesse@jmiller.biz> Jesus Sanchez-Palencia <jesus.sanchez-palencia.fernandez.fil@intel.com> Jiadong Zhu <jiadong.zhu@linaro.org> +Jiahe Zhang <jiahe.zhang@intel.com> Jiajia Qin <jiajia.qin@intel.com> Jiajie Hu <jiajie.hu@intel.com> Jianjun Zhu <jianjun.zhu@intel.com>
diff --git a/DEPS b/DEPS index 809c6a1..556e76d 100644 --- a/DEPS +++ b/DEPS
@@ -175,7 +175,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '11efa18eca9f1368f2dab75717e334dbc3ab546e', + 'skia_revision': '0e29459cda65aea76f8f8bad891cbe948adc95d9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -187,7 +187,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '4d2040a6f9737e27e65e17343abb337ac292777d', + 'angle_revision': '78da538aed5268be4bab9f230f101bf57b93d462', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -195,7 +195,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '4745a47b272fe1eeae0c5159cc479c541f744fc5', + 'pdfium_revision': '57b83355c5155c2f8f9093b1e13ec12dd1bfe2f7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -222,7 +222,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling NaCl # and whatever else without interference from each other. - 'nacl_revision': 'cd2eb2e2d632e9815415268970e793076a65cdcf', + 'nacl_revision': '35bcc9f6d5e81c3c39ad57de97ef9cd22301ee9e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -238,7 +238,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': '9db20bb3437ebe132a533f083b266f8de82d84cb', + 'catapult_revision': '21c99c4478fbbef105af9ed7ee0fcec7816b3fc7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -246,7 +246,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '4665866ae8dbf9652552e26595027cea85c518fd', + 'devtools_frontend_revision': '29c52f9cafce2d99df8dff730d56ada8db1b6e2b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -523,7 +523,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '1dc20d1399a0cac7bd5656acc0d5ed5c03f4ac50', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'e96b7efd28d7284eb090dab1408e0083dc06353e', 'condition': 'checkout_ios', }, @@ -879,7 +879,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'a4f9aa037585a99a5c5e1b029991c040f5a29e7c', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '1e247059f49b0aae00a650c6714719dd091dd77c', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1213,7 +1213,7 @@ Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '6f26bce0b1c4e8ce0e13332f7c0083788def5fdf', 'src/third_party/openscreen/src': - Var('chromium_git') + '/openscreen' + '@' + '840d5db64e4d8790e22006b941a6efc56fa15ae9', + Var('chromium_git') + '/openscreen' + '@' + '211ec3001099f4a8e9a1f408691f5e67328eb5fc', 'src/third_party/openxr/src': { 'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + '9e97b73e7dd2bfc07745489d728f6a36665c648f', @@ -1230,7 +1230,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '2f0b41d4e7f842674d6af96f9b65c338145aa322', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '66759fd962320e7d6399c4e43e39856c4eca8ce2', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1431,7 +1431,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'ec18cc3262922e7dcdbe70243c6f40606f979144', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '729310aa18107f8b5a6de674daee76fa5a8d67a6', + Var('webrtc_git') + '/src.git' + '@' + 'b5eeba1bb3d7c7529ea085ea5240fa6f29a7e1b2', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1506,7 +1506,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@9b194b7a67c8d986737f5c7542d067f8ea9cc7a9', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@a090e226e224afeb376373d42c14bc7834ab48df', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java index 5ce271b7..157688d 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
@@ -354,7 +354,7 @@ initForReal(); if (privateBrowsing) { // Intentionally irreversibly disable the webview instance, so that private - // user data cannot leak through misuse of a non-privateBrowing WebView + // user data cannot leak through misuse of a non-private-browsing WebView // instance. Can't just null out mAwContents as we never null-check it // before use. destroy(); @@ -671,7 +671,7 @@ public void loadUrl(final String url, final Map<String, String> additionalHttpHeaders) { mFactory.startYourEngines(true); if (checkNeedsPost()) { - // Disallowed in WebView API for apps targetting a new SDK + // Disallowed in WebView API for apps targeting a new SDK assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2; mFactory.addTask(new Runnable() { @Override @@ -688,7 +688,7 @@ public void loadUrl(final String url) { mFactory.startYourEngines(true); if (checkNeedsPost()) { - // Disallowed in WebView API for apps targetting a new SDK + // Disallowed in WebView API for apps targeting a new SDK assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2; mFactory.addTask(new Runnable() { @Override @@ -705,7 +705,7 @@ public void postUrl(final String url, final byte[] postData) { mFactory.startYourEngines(true); if (checkNeedsPost()) { - // Disallowed in WebView API for apps targetting a new SDK + // Disallowed in WebView API for apps targeting a new SDK assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2; mFactory.addTask(new Runnable() { @Override @@ -724,7 +724,7 @@ public void loadData(final String data, final String mimeType, final String encoding) { mFactory.startYourEngines(true); if (checkNeedsPost()) { - // Disallowed in WebView API for apps targetting a new SDK + // Disallowed in WebView API for apps targeting a new SDK assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2; mFactory.addTask(new Runnable() { @Override @@ -744,7 +744,7 @@ final String encoding, final String historyUrl) { mFactory.startYourEngines(true); if (checkNeedsPost()) { - // Disallowed in WebView API for apps targetting a new SDK + // Disallowed in WebView API for apps targeting a new SDK assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2; mFactory.addTask(new Runnable() { @Override
diff --git a/android_webview/lib/aw_main_delegate.cc b/android_webview/lib/aw_main_delegate.cc index 12bb7a9a..ca32128 100644 --- a/android_webview/lib/aw_main_delegate.cc +++ b/android_webview/lib/aw_main_delegate.cc
@@ -182,11 +182,7 @@ // so we can't use FeatureList::IsEnabled. This is necessary if someone // enabled feature through command line. Finch experiments will need to set // all flags in trial config. - if (features.IsEnabled(::features::kVizForWebView)) { - features.EnableIfNotSet(::features::kEnableSharedImageForWebview); - features.EnableIfNotSet(::features::kUseSkiaForGLReadback); - features.EnableIfNotSet(::features::kUseSkiaRenderer); - } else { + if (!features.IsEnabled(::features::kVizForWebView)) { // Viz for WebView is required to support embedding CompositorFrameSinks // which is needed for UseSurfaceLayerForVideo feature. // https://crbug.com/853832
diff --git a/ash/accelerometer/accelerometer_reader.cc b/ash/accelerometer/accelerometer_reader.cc index b784ea33..62835a0 100644 --- a/ash/accelerometer/accelerometer_reader.cc +++ b/ash/accelerometer/accelerometer_reader.cc
@@ -189,10 +189,7 @@ void StopListenToTabletModeController(); // TabletModeObserver: - // OnTabletModeStarted() triggers accelerometer read. - // OnTabletModeEnding() disables accelerometer read. - void OnTabletModeStarted() override; - void OnTabletModeEnding() override; + void OnTabletPhysicalStateChanged() override; private: friend class base::RefCountedThreadSafe<AccelerometerFileReader>; @@ -544,31 +541,30 @@ Shell::Get()->tablet_mode_controller()->RemoveObserver(this); } -void AccelerometerFileReader::OnTabletModeStarted() { +void AccelerometerFileReader::OnTabletPhysicalStateChanged() { // When CrOS EC lid angle driver is not present, accelerometer read is always // ON and can't be tuned. Thus AccelerometerFileReader no longer listens to // tablet mode event. + auto* tablet_mode_controller = Shell::Get()->tablet_mode_controller(); if (ec_lid_angle_driver_ == NOT_SUPPORTED) { - Shell::Get()->tablet_mode_controller()->RemoveObserver(this); + tablet_mode_controller->RemoveObserver(this); return; } - task_runner_->PostNonNestableTask( - FROM_HERE, base::BindOnce(&AccelerometerFileReader::TriggerRead, this)); -} - -void AccelerometerFileReader::OnTabletModeEnding() { - if (ec_lid_angle_driver_ == NOT_SUPPORTED) { - Shell::Get()->tablet_mode_controller()->RemoveObserver(this); - return; - } + // Auto rotation is turned on when the device is physically used as a tablet + // (i.e. flipped or detached), regardless of the UI state (i.e. whether tablet + // mode is turned on or off). + const bool is_auto_rotation_on = + tablet_mode_controller->is_in_tablet_physical_state(); task_runner_->PostNonNestableTask( FROM_HERE, - base::BindOnce(&AccelerometerFileReader::CancelRead, this)); + is_auto_rotation_on + ? base::BindOnce(&AccelerometerFileReader::TriggerRead, this) + : base::BindOnce(&AccelerometerFileReader::CancelRead, this)); } -AccelerometerFileReader::~AccelerometerFileReader() {} +AccelerometerFileReader::~AccelerometerFileReader() = default; bool AccelerometerFileReader::InitializeAccelerometer( const base::FilePath& iio_path,
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 9ed4108..aef1552 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -1293,7 +1293,7 @@ Resolution changed </message> <message name="IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED" desc="The label used in the tray to notify that the display resolution settings has changed."> - <ph name="DISPLAY_NAME">$1<ex>Internal Display</ex></ph>: <ph name="RESOLUTION">$2<ex>2560x1600</ex></ph> + <ph name="DISPLAY_NAME">$1<ex>Built-in display</ex></ph>: <ph name="RESOLUTION">$2<ex>2560x1600</ex></ph> </message> <message name="IDS_ASH_RESOLUTION_CHANGE_DIALOG_TITLE" desc="The title used in the dialog to notify that the display resolution settings has changed and asks the user to confirm the new resolution."> Confirm Resolution
diff --git a/ash/public/cpp/app_list/app_list_features.cc b/ash/public/cpp/app_list/app_list_features.cc index 8b0cce56..11f16f10 100644 --- a/ash/public/cpp/app_list/app_list_features.cc +++ b/ash/public/cpp/app_list/app_list_features.cc
@@ -54,6 +54,8 @@ base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kEnableFuzzyAppSearch{"EnableFuzzyAppSearch", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kEnableExactMatchForNonLatinLocale{ + "EnableExactMatchForNonLatinLocale", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kEnableAggregatedMlSearchRanking{ "EnableAggregatedMlSearchRanking", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -133,6 +135,10 @@ return base::FeatureList::IsEnabled(kEnableFuzzyAppSearch); } +bool IsExactMatchForNonLatinLocaleEnabled() { + return base::FeatureList::IsEnabled(kEnableExactMatchForNonLatinLocale); +} + bool IsAggregatedMlSearchRankingEnabled() { return base::FeatureList::IsEnabled(kEnableAggregatedMlSearchRanking); }
diff --git a/ash/public/cpp/app_list/app_list_features.h b/ash/public/cpp/app_list/app_list_features.h index eb950c7..dd7a5ce 100644 --- a/ash/public/cpp/app_list/app_list_features.h +++ b/ash/public/cpp/app_list/app_list_features.h
@@ -75,6 +75,9 @@ // Enables using the fuzzy search algorithm for app search provider. ASH_PUBLIC_EXPORT extern const base::Feature kEnableFuzzyAppSearch; +// Enables using exact string search for non latin locales. +ASH_PUBLIC_EXPORT extern const base::Feature kEnableExactMatchForNonLatinLocale; + // If enabled, app list will support separate configurations (for app list items // sizing and spacing) for smaller screens (instead of a single configuration // that optionally gets scaled down). @@ -103,6 +106,7 @@ bool ASH_PUBLIC_EXPORT IsAggregatedMlAppRankingEnabled(); bool ASH_PUBLIC_EXPORT IsScalableAppListEnabled(); bool ASH_PUBLIC_EXPORT IsFuzzyAppSearchEnabled(); +bool ASH_PUBLIC_EXPORT IsExactMatchForNonLatinLocaleEnabled(); bool ASH_PUBLIC_EXPORT IsAggregatedMlSearchRankingEnabled(); std::string ASH_PUBLIC_EXPORT AnswerServerUrl();
diff --git a/ash/wm/gestures/back_gesture/back_gesture_contextual_nudge.cc b/ash/wm/gestures/back_gesture/back_gesture_contextual_nudge.cc index b2965011..8993ffc 100644 --- a/ash/wm/gestures/back_gesture/back_gesture_contextual_nudge.cc +++ b/ash/wm/gestures/back_gesture/back_gesture_contextual_nudge.cc
@@ -79,7 +79,7 @@ params.name = "BackGestureContextualNudge"; params.layer_type = ui::LAYER_NOT_DRAWN; params.parent = Shell::GetPrimaryRootWindow()->GetChildById( - kShellWindowId_AlwaysOnTopContainer); + kShellWindowId_OverlayContainer); widget->Init(std::move(params)); // TODO(crbug.com/1009005): Get the bounds of the display that should show the
diff --git a/ash/wm/gestures/back_gesture/back_gesture_contextual_nudge_controller_impl_unittest.cc b/ash/wm/gestures/back_gesture/back_gesture_contextual_nudge_controller_impl_unittest.cc index 490fd00..5223c97 100644 --- a/ash/wm/gestures/back_gesture/back_gesture_contextual_nudge_controller_impl_unittest.cc +++ b/ash/wm/gestures/back_gesture/back_gesture_contextual_nudge_controller_impl_unittest.cc
@@ -130,8 +130,8 @@ user1_perf_service(), contextual_tooltip::TooltipType::kBackGesture)); std::unique_ptr<aura::Window> window1 = CreateTestWindow(); + // If nudge() is true, it indicates that it's currently in animation. EXPECT_TRUE(nudge()); - EXPECT_TRUE(nudge()->widget()->GetLayer()->GetAnimator()->is_animating()); // At this moment, change window activation should cancel the previous nudge // showup animation on |window1|, and start show nudge on |window2|. @@ -139,7 +139,6 @@ EXPECT_FALSE(nudge()->ShouldNudgeCountAsShown()); EXPECT_TRUE(contextual_tooltip::ShouldShowNudge( user1_perf_service(), contextual_tooltip::TooltipType::kBackGesture)); - EXPECT_TRUE(nudge()->widget()->GetLayer()->GetAnimator()->is_animating()); // Wait until nudge animation is finished. WaitNudgeAnimationDone(); @@ -160,7 +159,6 @@ std::unique_ptr<aura::Window> window = CreateTestWindow(); EXPECT_TRUE(nudge()); - EXPECT_TRUE(nudge()->widget()->GetLayer()->GetAnimator()->is_animating()); TabletModeControllerTestApi().LeaveTabletMode(); WaitNudgeAnimationDone();
diff --git a/build/config/ios/ios_test_runner_config.gni b/build/config/ios/ios_test_runner_config.gni deleted file mode 100644 index f28533b..0000000 --- a/build/config/ios/ios_test_runner_config.gni +++ /dev/null
@@ -1,10 +0,0 @@ -# Copyright 2020 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -declare_args() { - # Controls what version of xcode to use for iOS testers. Note that this - # version should be in alignment with the swarming named caches used by tests, - # defined under src/testing/buildbot/ to avoid performance issues. - test_runner_xcode_build_version = "11c29" -}
diff --git a/build/config/ios/ios_test_runner_wrapper.gni b/build/config/ios/ios_test_runner_wrapper.gni deleted file mode 100644 index 572818a..0000000 --- a/build/config/ios/ios_test_runner_wrapper.gni +++ /dev/null
@@ -1,124 +0,0 @@ -# Copyright 2020 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/ios/ios_sdk.gni") -import("//build/config/ios/ios_test_runner_config.gni") -import("//build/util/generate_wrapper.gni") - -# Invokes generate_wrapper to create an executable script wrapping iOS' -# run.py with baked in arguments. Only takes effect when test entry in -# gn_isolate_map.pyl is updated to type="generated_script" with script -# set to the wrapper output path. -# -# Arguments: -# -# data -# (optional, default [ "//ios/build/bots/scripts/" ]) list of files or -# directories required to run target -# -# data_deps -# (optional) list of target non-linked labels -# -# deps -# (optional) list of files or directories required to run target -# -# executable_args -# (optional) a list of string arguments to pass to run.py -# -# retries -# (optional, default 3) number of retry attempts -# -# shards -# (optional, default 1) number of shards to execute tests in parallel. not -# the same as swamring shards. -# -# wrapper_output_name -# (optional, default "run_${target_name}") name of the wrapper script -# -template("ios_test_runner_wrapper") { - generate_wrapper(target_name) { - forward_variables_from(invoker, - [ - "data", - "data_deps", - "deps", - "executable_args", - "retries", - "shards", - "wrapper_output_name", - ]) - testonly = true - - # iOS main test runner - executable = "//ios/build/bots/scripts/run.py" - - # arguments passed to run.py - if (!defined(executable_args)) { - executable_args = [] - } - - _rebased_mac_toolchain = rebase_path("//mac_toolchain", root_build_dir) - _rebased_xcode_path = rebase_path("//Xcode.app", root_build_dir) - - # --out-dir argument is specified in gn_isolate_map.pyl because - # ${ISOLATED_OUTDIR} doesn't get resolved through this wrapper. - executable_args += [ - "--xcode-path", - "@WrappedPath(${_rebased_xcode_path})", - "--mac-toolchain-cmd", - "@WrappedPath(${_rebased_mac_toolchain})", - ] - - executable_args += [ - "--xcode-build-version", - test_runner_xcode_build_version, - ] - - # Default retries to 3 - if (!defined(retries)) { - retries = 3 - } - executable_args += [ - "--retries", - "${retries}", - ] - - # Default shards to 1 - if (!defined(shards)) { - shards = 1 - } - executable_args += [ - "--shards", - "${shards}", - ] - - # test runner relies on iossim if use_ios_simulator (defined in ios_sdk.gni) - if (use_ios_simulator) { - _rebased_root_build_dir = rebase_path("${root_build_dir}", root_build_dir) - if (!defined(data_deps)) { - data_deps = [] - } - data_deps += [ "//testing/iossim" ] - - executable_args += [ - "--iossim", - "@WrappedPath(${_rebased_root_build_dir}/iossim)", - ] - } - - # wrapper script output name and path - if (!defined(wrapper_output_name)) { - _wrapper_output_name = "run_${target_name}" - } else { - _wrapper_output_name = wrapper_output_name - } - wrapper_script = "${root_build_dir}/bin/${_wrapper_output_name}" - - # ios/build/bot/scripts/*.py needs to be present for test runner - if (!defined(data)) { - data = [] - } - data += [ "//ios/build/bots/scripts/" ] - } -}
diff --git a/build/config/ios/rules.gni b/build/config/ios/rules.gni index 8d2fb48dfb..a1d62f8d 100644 --- a/build/config/ios/rules.gni +++ b/build/config/ios/rules.gni
@@ -1971,14 +1971,10 @@ "xcode_test_application_name must be defined for $target_name") _xcuitest_target = target_name - if (defined(invoker.output_name)) { - _xcuitest_target = invoker.output_name - } - _xcuitest_runner_target = _xcuitest_target + "_runner" _xcuitest_module_target = _xcuitest_target + "_module" - group(target_name) { + group(_xcuitest_target) { testonly = true deps = [ ":$_xcuitest_runner_target" ]
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index a8297d5..a57b0cb 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20200227.2.1 \ No newline at end of file +0.20200227.3.1 \ No newline at end of file
diff --git a/cc/layers/viewport.cc b/cc/layers/viewport.cc index 9725130..3a6a85c 100644 --- a/cc/layers/viewport.cc +++ b/cc/layers/viewport.cc
@@ -52,13 +52,13 @@ // Attempt to scroll inner viewport first. pending_scroll_node_delta -= host_impl_->ScrollSingleNode( - InnerScrollNode(), pending_scroll_node_delta, viewport_point, + *InnerScrollNode(), pending_scroll_node_delta, viewport_point, is_direct_manipulation, &scroll_tree()); // Now attempt to scroll the outer viewport. if (scroll_outer_viewport) { pending_scroll_node_delta -= host_impl_->ScrollSingleNode( - OuterScrollNode(), pending_scroll_node_delta, viewport_point, + *OuterScrollNode(), pending_scroll_node_delta, viewport_point, is_direct_manipulation, &scroll_tree()); }
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 2cbd02e..a49da2c 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -154,6 +154,20 @@ return has_fixed_page_scale || has_mobile_viewport; } +// This helper returns an adjusted version of |delta| where the scroll delta is +// cleared in any axis in which user scrolling is disabled (e.g. by +// |overflow-x: hidden|). +gfx::Vector2dF UserScrollableDelta(const ScrollNode& node, + const gfx::Vector2dF& delta) { + gfx::Vector2dF adjusted_delta = delta; + if (!node.user_scrollable_horizontal) + adjusted_delta.set_x(0); + if (!node.user_scrollable_vertical) + adjusted_delta.set_y(0); + + return adjusted_delta; +} + viz::ResourceFormat TileRasterBufferFormat( const LayerTreeSettings& settings, viz::ContextProvider* context_provider, @@ -4105,10 +4119,7 @@ gfx::Vector2dF adjusted_scroll(delta); adjusted_scroll.Scale(1.f / scale_factor); - if (!scroll_node.user_scrollable_horizontal) - adjusted_scroll.set_x(0); - if (!scroll_node.user_scrollable_vertical) - adjusted_scroll.set_y(0); + adjusted_scroll = UserScrollableDelta(scroll_node, adjusted_scroll); gfx::ScrollOffset old_offset = scroll_tree.current_scroll_offset(scroll_node.element_id); @@ -4225,28 +4236,28 @@ } gfx::Vector2dF LayerTreeHostImpl::ScrollNodeWithViewportSpaceDelta( - ScrollNode* scroll_node, + ScrollNode& scroll_node, const gfx::PointF& viewport_point, const gfx::Vector2dF& viewport_delta, ScrollTree* scroll_tree) { gfx::PointF local_start_point; gfx::Vector2dF local_scroll_delta; if (!CalculateLocalScrollDeltaAndStartPoint( - *scroll_node, viewport_point, viewport_delta, *scroll_tree, + scroll_node, viewport_point, viewport_delta, *scroll_tree, &local_scroll_delta, &local_start_point)) { return gfx::Vector2dF(); } - bool scrolls_outer_viewport = scroll_node->scrolls_outer_viewport; + bool scrolls_outer_viewport = scroll_node.scrolls_outer_viewport; TRACE_EVENT2("cc", "ScrollNodeWithViewportSpaceDelta", "delta_y", local_scroll_delta.y(), "is_outer", scrolls_outer_viewport); // Apply the scroll delta. gfx::ScrollOffset previous_offset = - scroll_tree->current_scroll_offset(scroll_node->element_id); - scroll_tree->ScrollBy(scroll_node, local_scroll_delta, active_tree()); + scroll_tree->current_scroll_offset(scroll_node.element_id); + scroll_tree->ScrollBy(&scroll_node, local_scroll_delta, active_tree()); gfx::ScrollOffset scrolled = - scroll_tree->current_scroll_offset(scroll_node->element_id) - + scroll_tree->current_scroll_offset(scroll_node.element_id) - previous_offset; TRACE_EVENT_INSTANT1("cc", "ConsumedDelta", TRACE_EVENT_SCOPE_THREAD, "y", @@ -4260,7 +4271,7 @@ // Calculate the applied scroll delta in viewport space coordinates. bool end_clipped; const gfx::Transform screen_space_transform = - scroll_tree->ScreenSpaceTransform(scroll_node->id); + scroll_tree->ScreenSpaceTransform(scroll_node.id); gfx::PointF actual_screen_space_end_point = MathUtil::MapPoint( screen_space_transform, actual_local_end_point, &end_clipped); DCHECK(!end_clipped); @@ -4275,22 +4286,22 @@ } static gfx::Vector2dF ScrollNodeWithLocalDelta( - ScrollNode* scroll_node, + ScrollNode& scroll_node, const gfx::Vector2dF& local_delta, float page_scale_factor, LayerTreeImpl* layer_tree_impl) { - bool scrolls_outer_viewport = scroll_node->scrolls_outer_viewport; + bool scrolls_outer_viewport = scroll_node.scrolls_outer_viewport; TRACE_EVENT2("cc", "ScrollNodeWithLocalDelta", "delta_y", local_delta.y(), "is_outer", scrolls_outer_viewport); ScrollTree& scroll_tree = layer_tree_impl->property_trees()->scroll_tree; gfx::ScrollOffset previous_offset = - scroll_tree.current_scroll_offset(scroll_node->element_id); + scroll_tree.current_scroll_offset(scroll_node.element_id); gfx::Vector2dF delta = local_delta; delta.Scale(1.f / page_scale_factor); - scroll_tree.ScrollBy(scroll_node, delta, layer_tree_impl); + scroll_tree.ScrollBy(&scroll_node, delta, layer_tree_impl); gfx::ScrollOffset scrolled = - scroll_tree.current_scroll_offset(scroll_node->element_id) - + scroll_tree.current_scroll_offset(scroll_node.element_id) - previous_offset; gfx::Vector2dF consumed_scroll(scrolled.x(), scrolled.y()); consumed_scroll.Scale(page_scale_factor); @@ -4303,11 +4314,13 @@ // TODO(danakj): Make this into two functions, one with delta, one with // viewport_point, no bool required. gfx::Vector2dF LayerTreeHostImpl::ScrollSingleNode( - ScrollNode* scroll_node, + ScrollNode& scroll_node, const gfx::Vector2dF& delta, const gfx::Point& viewport_point, bool is_direct_manipulation, ScrollTree* scroll_tree) { + gfx::Vector2dF adjusted_delta = UserScrollableDelta(scroll_node, delta); + // Events representing direct manipulation of the screen (such as gesture // events) need to be transformed from viewport coordinates to local layer // coordinates so that the scrolling contents exactly follow the user's @@ -4318,13 +4331,13 @@ if (is_direct_manipulation) { // For touch-scroll we need to scale the delta here, as the transform tree // won't know anything about the external page scale factors used by OOPIFs. - gfx::Vector2dF scaled_delta(delta); + gfx::Vector2dF scaled_delta(adjusted_delta); scaled_delta.Scale(1 / active_tree()->external_page_scale_factor()); return ScrollNodeWithViewportSpaceDelta( scroll_node, gfx::PointF(viewport_point), scaled_delta, scroll_tree); } float scale_factor = active_tree()->page_scale_factor_for_scroll(); - return ScrollNodeWithLocalDelta(scroll_node, delta, scale_factor, + return ScrollNodeWithLocalDelta(scroll_node, adjusted_delta, scale_factor, active_tree()); } @@ -4335,8 +4348,6 @@ DCHECK(latched_scroll_type_.has_value()); ScrollNode& scroll_node = *CurrentlyScrollingNode(); - gfx::Point viewport_point(scroll_state->position_x(), - scroll_state->position_y()); const gfx::Vector2dF delta(scroll_state->delta_x(), scroll_state->delta_y()); TRACE_EVENT2("cc", "LayerTreeHostImpl::ScrollLatchedScroller", "delta_x", delta.x(), "delta_y", delta.y()); @@ -4353,7 +4364,7 @@ TRACE_EVENT_INSTANT0("cc", "UpdateExistingAnimation", TRACE_EVENT_SCOPE_THREAD); bool animation_updated = - ScrollAnimationUpdateTarget(&scroll_node, delta, delayed_by); + ScrollAnimationUpdateTarget(scroll_node, delta, delayed_by); if (animation_updated) { // Because we updated the animation target, consume delta so we notify @@ -4383,6 +4394,8 @@ // browser controls). delta_applied_to_content = delta; } else { + gfx::Point viewport_point(scroll_state->position_x(), + scroll_state->position_y()); if (viewport().ShouldScroll(scroll_node)) { // |scrolls_outer_viewport| will only ever be false if the scroll chains // up to the viewport without going through the outer viewport scroll @@ -4401,7 +4414,7 @@ delta_applied_to_content = result.content_scrolled_delta; } else { applied_delta = - ScrollSingleNode(&scroll_node, delta, viewport_point, + ScrollSingleNode(scroll_node, delta, viewport_point, scroll_state->is_direct_manipulation(), &active_tree_->property_trees()->scroll_tree); } @@ -4594,8 +4607,6 @@ if (!CurrentlyScrollingNode()) return InputHandlerScrollResult(); - ScrollNode& scroll_node = *CurrentlyScrollingNode(); - last_scroll_state_ = *scroll_state; bool is_delta_percent_units = scroll_state->delta_granularity() == @@ -4614,11 +4625,6 @@ scroll_accumulated_this_frame_ += gfx::Vector2dF(scroll_state->delta_x(), scroll_state->delta_y()); - if (!scroll_node.user_scrollable_horizontal) - scroll_state->data()->delta_x = 0; - if (!scroll_node.user_scrollable_vertical) - scroll_state->data()->delta_y = 0; - // Flash the overlay scrollbar even if the scroll delta is 0. if (settings_.scrollbar_flash_after_any_scroll_update) { FlashAllScrollbars(false); @@ -4671,11 +4677,9 @@ } // When inner viewport is unscrollable, disable overscrolls. - if (const auto* inner_viewport_scroll_node = InnerViewportScrollNode()) { - if (!inner_viewport_scroll_node->user_scrollable_horizontal) - unused_root_delta.set_x(0); - if (!inner_viewport_scroll_node->user_scrollable_vertical) - unused_root_delta.set_y(0); + if (auto* inner_viewport_scroll_node = InnerViewportScrollNode()) { + unused_root_delta = + UserScrollableDelta(*inner_viewport_scroll_node, unused_root_delta); } accumulated_root_overscroll_ += unused_root_delta; @@ -5835,16 +5839,18 @@ } bool LayerTreeHostImpl::ScrollAnimationUpdateTarget( - ScrollNode* scroll_node, + const ScrollNode& scroll_node, const gfx::Vector2dF& scroll_delta, base::TimeDelta delayed_by) { float scale_factor = active_tree()->page_scale_factor_for_scroll(); - gfx::Vector2dF scaled_delta = + gfx::Vector2dF adjusted_delta = gfx::ScaleVector2d(scroll_delta, 1.f / scale_factor); + adjusted_delta = UserScrollableDelta(scroll_node, adjusted_delta); + bool animation_updated = mutator_host_->ImplOnlyScrollAnimationUpdateTarget( - scaled_delta, + adjusted_delta, active_tree_->property_trees()->scroll_tree.MaxScrollOffset( - scroll_node->id), + scroll_node.id), CurrentBeginFrameArgs().frame_time, delayed_by); if (animation_updated) { // Because we updated the animation target, notify the SwapPromiseMonitor
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 94057d1..6b7938e 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -736,7 +736,8 @@ bool prepare_tiles_needed() const { return tile_priorities_dirty_; } - gfx::Vector2dF ScrollSingleNode(ScrollNode* scroll_node, + // TODO(bokan): Make |scroll_node| a const ref. + gfx::Vector2dF ScrollSingleNode(ScrollNode& scroll_node, const gfx::Vector2dF& delta, const gfx::Point& viewport_point, bool is_direct_manipulation, @@ -877,7 +878,7 @@ gfx::Vector2dF* out_local_scroll_delta, gfx::PointF* out_local_start_point = nullptr); gfx::Vector2dF ScrollNodeWithViewportSpaceDelta( - ScrollNode* scroll_node, + ScrollNode& scroll_node, const gfx::PointF& viewport_point, const gfx::Vector2dF& viewport_delta, ScrollTree* scroll_tree); @@ -995,7 +996,7 @@ void UpdateRootLayerStateForSynchronousInputHandler(); - bool ScrollAnimationUpdateTarget(ScrollNode* scroll_node, + bool ScrollAnimationUpdateTarget(const ScrollNode& scroll_node, const gfx::Vector2dF& scroll_delta, base::TimeDelta delayed_by);
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 64cba8a9..3498a93 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -8007,6 +8007,170 @@ gfx::ScrollOffsetToVector2dF(scroll_offset)); } +// Ensure the viewport correctly handles the user_scrollable bits. That is, if +// the outer viewport disables user scrolling, we should still be able to +// scroll the inner viewport. +TEST_F(LayerTreeHostImplTest, ViewportUserScrollable) { + gfx::Size viewport_size(100, 100); + gfx::Size content_size(200, 200); + SetupViewportLayersOuterScrolls(viewport_size, content_size); + + auto* outer_scroll = OuterViewportScrollLayer(); + auto* inner_scroll = InnerViewportScrollLayer(); + + ScrollTree& scroll_tree = + host_impl_->active_tree()->property_trees()->scroll_tree; + ElementId inner_element_id = inner_scroll->element_id(); + ElementId outer_element_id = outer_scroll->element_id(); + + DrawFrame(); + + // "Zoom in" so that the inner viewport is scrollable. + float page_scale_factor = 2; + host_impl_->active_tree()->PushPageScaleFromMainThread( + page_scale_factor, page_scale_factor, page_scale_factor); + + // Disable scrolling the outer viewport horizontally. The inner viewport + // should still be allowed to scroll. + GetScrollNode(outer_scroll)->user_scrollable_vertical = true; + GetScrollNode(outer_scroll)->user_scrollable_horizontal = false; + + gfx::Vector2dF scroll_delta(30 * page_scale_factor, 0); + { + auto begin_state = + BeginState(gfx::Point(), scroll_delta, InputHandler::TOUCHSCREEN); + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->ScrollBegin(begin_state.get(), InputHandler::TOUCHSCREEN) + .thread); + + // Try scrolling right, the inner viewport should be allowed to scroll. + auto update_state = + UpdateState(gfx::Point(), scroll_delta, InputHandler::TOUCHSCREEN); + host_impl_->ScrollUpdate(update_state.get()); + + EXPECT_VECTOR_EQ(gfx::ScrollOffset(30, 0), + scroll_tree.current_scroll_offset(inner_element_id)); + EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 0), + scroll_tree.current_scroll_offset(outer_element_id)); + + // Continue scrolling. The inner viewport should scroll until its extent, + // however, the outer viewport should not accept any scroll. + update_state = + UpdateState(gfx::Point(), scroll_delta, InputHandler::TOUCHSCREEN); + host_impl_->ScrollUpdate(update_state.get()); + update_state = + UpdateState(gfx::Point(), scroll_delta, InputHandler::TOUCHSCREEN); + host_impl_->ScrollUpdate(update_state.get()); + update_state = + UpdateState(gfx::Point(), scroll_delta, InputHandler::TOUCHSCREEN); + host_impl_->ScrollUpdate(update_state.get()); + + EXPECT_VECTOR_EQ(gfx::ScrollOffset(50, 0), + scroll_tree.current_scroll_offset(inner_element_id)); + EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 0), + scroll_tree.current_scroll_offset(outer_element_id)); + + host_impl_->ScrollEnd(); + } + + // Reset. Try the same test above but using animated scrolls. + SetScrollOffset(outer_scroll, gfx::ScrollOffset(0, 0)); + SetScrollOffset(inner_scroll, gfx::ScrollOffset(0, 0)); + + { + auto begin_state = + BeginState(gfx::Point(), scroll_delta, InputHandler::WHEEL); + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_->ScrollBegin(begin_state.get(), InputHandler::WHEEL).thread); + + // Try scrolling right, the inner viewport should be allowed to scroll. + auto update_state = AnimatedUpdateState(gfx::Point(), scroll_delta); + host_impl_->ScrollUpdate(update_state.get()); + + base::TimeTicks cur_time = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(100); + viz::BeginFrameArgs begin_frame_args = + viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1); + +#define ANIMATE(time_ms) \ + cur_time += base::TimeDelta::FromMilliseconds(time_ms); \ + begin_frame_args.frame_time = (cur_time); \ + begin_frame_args.frame_id.sequence_number++; \ + host_impl_->WillBeginImplFrame(begin_frame_args); \ + host_impl_->Animate(); \ + host_impl_->UpdateAnimationState(true); \ + host_impl_->DidFinishImplFrame(begin_frame_args); + + // The animation is setup in the first frame so tick twice to actually + // animate it. + ANIMATE(0); + ANIMATE(200); + + EXPECT_VECTOR_EQ(gfx::ScrollOffset(30, 0), + scroll_tree.current_scroll_offset(inner_element_id)); + EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 0), + scroll_tree.current_scroll_offset(outer_element_id)); + + // Continue scrolling. The inner viewport should scroll until its extent, + // however, the outer viewport should not accept any scroll. + update_state = AnimatedUpdateState(gfx::Point(), scroll_delta); + host_impl_->ScrollUpdate(update_state.get()); + ANIMATE(10); + ANIMATE(200); + + EXPECT_VECTOR_EQ(gfx::ScrollOffset(50, 0), + scroll_tree.current_scroll_offset(inner_element_id)); + EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 0), + scroll_tree.current_scroll_offset(outer_element_id)); + + // Continue scrolling. the outer viewport should still not scroll. + update_state = AnimatedUpdateState(gfx::Point(), scroll_delta); + host_impl_->ScrollUpdate(update_state.get()); + ANIMATE(10); + ANIMATE(200); + + EXPECT_VECTOR_EQ(gfx::ScrollOffset(50, 0), + scroll_tree.current_scroll_offset(inner_element_id)); + EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 0), + scroll_tree.current_scroll_offset(outer_element_id)); + + // Fully scroll the inner viewport. We'll now try to start an animation on + // the outer viewport in the vertical direction, which is scrollable. We'll + // then try to update the curve to scroll horizontally. Ensure that doesn't + // allow any horizontal scroll. + SetScrollOffset(inner_scroll, gfx::ScrollOffset(50, 50)); + update_state = AnimatedUpdateState(gfx::Point(), gfx::Vector2dF(0, 100)); + host_impl_->ScrollUpdate(update_state.get()); + ANIMATE(16); + ANIMATE(64); + + // We don't care about the exact offset, we just want to make sure the + // scroll is in progress but not finished. + ASSERT_LT(0, scroll_tree.current_scroll_offset(outer_element_id).y()); + ASSERT_GT(50, scroll_tree.current_scroll_offset(outer_element_id).y()); + ASSERT_EQ(0, scroll_tree.current_scroll_offset(outer_element_id).x()); + EXPECT_VECTOR_EQ(gfx::ScrollOffset(50, 50), + scroll_tree.current_scroll_offset(inner_element_id)); + + // Now when we scroll we should do so by updating the ongoing animation + // curve. Ensure this doesn't allow any horizontal scrolling. + update_state = AnimatedUpdateState(gfx::Point(), gfx::Vector2dF(100, 100)); + host_impl_->ScrollUpdate(update_state.get()); + ANIMATE(200); + + EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100), + scroll_tree.current_scroll_offset(outer_element_id)); + EXPECT_VECTOR_EQ(gfx::ScrollOffset(50, 50), + scroll_tree.current_scroll_offset(inner_element_id)); + +#undef ANIMATE + + host_impl_->ScrollEnd(); + } +} + // Ensure that the SetSynchronousInputHandlerRootScrollOffset method used by // the WebView API correctly respects the user_scrollable bits on both of the // inner and outer viewport scroll nodes.
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h index 02e956d..499d5f1 100644 --- a/cc/trees/layer_tree_settings.h +++ b/cc/trees/layer_tree_settings.h
@@ -140,7 +140,7 @@ // Determines whether mouse interactions on composited scrollbars are handled // on the compositor thread. - bool compositor_threaded_scrollbar_scrolling = false; + bool compositor_threaded_scrollbar_scrolling = true; // Determines whether animated scrolling is supported. If true, and the // incoming gesture scroll is of a type that would normally be animated (e.g.
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 7cd1775..f0b98114 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -735,7 +735,6 @@ "java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java", "java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java", "java/src/org/chromium/chrome/browser/flags/ChromeSessionState.java", - "java/src/org/chromium/chrome/browser/flags/LegacyFeatureUtilities.java", "java/src/org/chromium/chrome/browser/fullscreen/BrowserStateBrowserControlsVisibilityDelegate.java", "java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java", "java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java", @@ -1579,6 +1578,7 @@ "java/src/org/chromium/chrome/browser/tab/TabBuilder.java", "java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java", "java/src/org/chromium/chrome/browser/tab/TabContextMenuPopulator.java", + "java/src/org/chromium/chrome/browser/tab/TabCreationState.java", "java/src/org/chromium/chrome/browser/tab/TabDelegateFactory.java", "java/src/org/chromium/chrome/browser/tab/TabFavicon.java", "java/src/org/chromium/chrome/browser/tab/TabFeatureUtilities.java",
diff --git a/chrome/android/features/autofill_assistant/java/res/drawable-night/autofill_assistant_details_bg.xml b/chrome/android/features/autofill_assistant/java/res/drawable-night/autofill_assistant_details_bg.xml deleted file mode 100644 index 769f51c6b..0000000 --- a/chrome/android/features/autofill_assistant/java/res/drawable-night/autofill_assistant_details_bg.xml +++ /dev/null
@@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2019 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. --> -<shape - xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle"> - <corners android:radius="8dp" /> - <!-- TODO(b/146413939): Move to @color/default_chip_outline_color once available. --> - <stroke - android:color="@color/modern_grey_700" - android:width="1dp" /> -</shape> \ No newline at end of file
diff --git a/chrome/android/features/autofill_assistant/java/res/drawable/autofill_assistant_details_bg.xml b/chrome/android/features/autofill_assistant/java/res/drawable/autofill_assistant_details_bg.xml index d0a7b640..aff6ec185 100644 --- a/chrome/android/features/autofill_assistant/java/res/drawable/autofill_assistant_details_bg.xml +++ b/chrome/android/features/autofill_assistant/java/res/drawable/autofill_assistant_details_bg.xml
@@ -6,8 +6,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="8dp" /> - <!-- TODO(b/146413939): Move to @color/default_chip_outline_color once available. --> <stroke - android:color="@color/modern_grey_300" + android:color="@color/default_chip_outline_color" android:width="1dp" /> -</shape> \ No newline at end of file +</shape>
diff --git a/chrome/android/features/autofill_assistant/java/res/values-v17/colors.xml b/chrome/android/features/autofill_assistant/java/res/values-v17/colors.xml index c42e679..69940d5d 100644 --- a/chrome/android/features/autofill_assistant/java/res/values-v17/colors.xml +++ b/chrome/android/features/autofill_assistant/java/res/values-v17/colors.xml
@@ -9,6 +9,6 @@ Please see src/ui/android/java/res/values/colors.xml for the shared common colors. --> - <color name="autofill_assistant_light_blue">#E9F0FD</color> - <color name="autofill_assistant_actions_shadow_color">#40CCCCCC</color> + <color name="autofill_assistant_light_blue">@color/modern_blue_600_alpha_10</color> + <color name="autofill_assistant_actions_shadow_color">@color/modern_grey_100</color> </resources>
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java index 3e73f1c..5429f78e 100644 --- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java +++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java
@@ -73,6 +73,7 @@ import org.chromium.chrome.browser.keyboard_accessory.sheet_component.AccessorySheetCoordinator; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabCoordinator; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabHidingType; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController; @@ -1070,7 +1071,8 @@ when(tab.getContentView()).thenReturn(mMockContentView); when(mMockTabModelSelector.getCurrentTab()).thenReturn(tab); mActivityTabProvider.set(tab); - mediator.getTabModelObserverForTesting().didAddTab(tab, FROM_BROWSER_ACTIONS); + mediator.getTabModelObserverForTesting().didAddTab( + tab, FROM_BROWSER_ACTIONS, TabCreationState.LIVE_IN_FOREGROUND); mediator.getTabObserverForTesting().onShown(tab, FROM_NEW); mediator.getTabModelObserverForTesting().didSelectTab(tab, FROM_NEW, lastId); setContentAreaDimensions(2.f, 300, 128);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java index fb9b24f..69cd396 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.share.ShareParams; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; @@ -132,7 +133,8 @@ // Register for tab model. mTabModelObserver = new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { hideDialog(false); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediator.java index 2a5e197..d05ab593 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediator.java
@@ -12,6 +12,7 @@ import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelObserver; @@ -109,7 +110,7 @@ } @Override - public void didAddTab(Tab tab, int type) { + public void didAddTab(Tab tab, int type, @TabCreationState int creationState) { // TODO(crbug.com/1050846): The popup tab strip doesn't update accordingly when tab // is opened in background. This might require us to specify how the view measures // in this case. Skip it for now to avoid crash crbug.com/1045944.
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java index 6f998fec..4a23418 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java
@@ -15,6 +15,7 @@ import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; @@ -135,7 +136,7 @@ } @Override - public void didAddTab(Tab tab, int type) { + public void didAddTab(Tab tab, int type, @TabCreationState int creationState) { if (type == TabLaunchType.FROM_CHROME_UI || type == TabLaunchType.FROM_RESTORE || type == TabLaunchType.FROM_STARTUP) { return;
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index 0f043269..145311aa 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -46,6 +46,7 @@ import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabFeatureUtilities; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; @@ -532,7 +533,8 @@ } @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { boolean isTabModelRestoreCompleted = mTabModelSelector.getTabModelFilterProvider() .getCurrentTabModelFilter() .isTabModelRestored();
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java index a6e13cc4..11a7ae3 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorMediator.java
@@ -16,6 +16,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -116,7 +117,7 @@ mTabModelObserver = new TabModelSelectorTabModelObserver(mTabModelSelector) { @Override - public void didAddTab(Tab tab, int type) { + public void didAddTab(Tab tab, int type, @TabCreationState int creationState) { // When tab is added due to multi-window close or moving between multiple windows, // force hiding the selection editor. if (type == TabLaunchType.FROM_RESTORE || type == TabLaunchType.FROM_REPARENTING) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java index 41e01ab4..2b0d0885 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java
@@ -36,6 +36,7 @@ import org.chromium.chrome.browser.fullscreen.FullscreenManager; import org.chromium.chrome.browser.init.FirstDrawDetector; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabFeatureUtilities; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; @@ -212,7 +213,7 @@ mTabModelObserver = new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, int type) { + public void didAddTab(Tab tab, int type, @TabCreationState int creationState) { mShouldIgnoreNextSelect = false; }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContext.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContext.java index c443c76..897e99c 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContext.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContext.java
@@ -90,7 +90,7 @@ public static TabInfo createFromTab(Tab tab) { String referrerUrl = getReferrerUrlFromTab(tab); return new TabInfo(tab.getId(), tab.getTitle(), tab.getUrlString(), - ((TabImpl) tab).getOriginalUrl(), referrerUrl != null ? referrerUrl : "", + tab.getOriginalUrl(), referrerUrl != null ? referrerUrl : "", tab.getTimestampMillis(), ((TabImpl) tab).getProfile(), tab.getUrlString()); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContextObserver.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContextObserver.java index d32de86..5286796 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContextObserver.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContextObserver.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.tasks.tab_management.suggestions; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -33,7 +34,7 @@ mTabModelObserver = new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, int type) { + public void didAddTab(Tab tab, int type, @TabCreationState int creationState) { onTabContextChanged(TabContextChangeReason.TAB_ADDED); }
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilterUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilterUnitTest.java index 1a382760..c893223 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilterUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilterUnitTest.java
@@ -38,6 +38,7 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -143,7 +144,7 @@ } }) .when(mTabModel) - .addTab(any(Tab.class), anyInt(), anyInt()); + .addTab(any(Tab.class), anyInt(), anyInt(), anyInt()); doAnswer(new Answer() { @Override @@ -204,8 +205,10 @@ private TabImpl addTabToTabModel(int index, @Nullable TabImpl tab) { if (tab == null) tab = prepareTab(NEW_TAB_ID, NEW_TAB_ID, Tab.INVALID_TAB_ID); - mTabModel.addTab(tab, index, TabLaunchType.FROM_CHROME_UI); - mTabModelObserverCaptor.getValue().didAddTab(tab, TabLaunchType.FROM_CHROME_UI); + mTabModel.addTab( + tab, index, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); + mTabModelObserverCaptor.getValue().didAddTab( + tab, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); return tab; } @@ -216,28 +219,40 @@ mTabGroupModelFilter.addTabGroupObserver(mTabGroupModelFilterObserver); doReturn(isIncognito).when(mTab1).isIncognito(); - mTabModel.addTab(mTab1, -1, TabLaunchType.FROM_CHROME_UI); - mTabModelObserverCaptor.getValue().didAddTab(mTab1, TabLaunchType.FROM_CHROME_UI); + mTabModel.addTab( + mTab1, -1, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); + mTabModelObserverCaptor.getValue().didAddTab( + mTab1, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); doReturn(isIncognito).when(mTab2).isIncognito(); - mTabModel.addTab(mTab2, -1, TabLaunchType.FROM_CHROME_UI); - mTabModelObserverCaptor.getValue().didAddTab(mTab2, TabLaunchType.FROM_CHROME_UI); + mTabModel.addTab( + mTab2, -1, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); + mTabModelObserverCaptor.getValue().didAddTab( + mTab2, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); doReturn(isIncognito).when(mTab3).isIncognito(); - mTabModel.addTab(mTab3, -1, TabLaunchType.FROM_CHROME_UI); - mTabModelObserverCaptor.getValue().didAddTab(mTab3, TabLaunchType.FROM_CHROME_UI); + mTabModel.addTab( + mTab3, -1, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); + mTabModelObserverCaptor.getValue().didAddTab( + mTab3, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); doReturn(isIncognito).when(mTab4).isIncognito(); - mTabModel.addTab(mTab4, -1, TabLaunchType.FROM_CHROME_UI); - mTabModelObserverCaptor.getValue().didAddTab(mTab4, TabLaunchType.FROM_CHROME_UI); + mTabModel.addTab( + mTab4, -1, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); + mTabModelObserverCaptor.getValue().didAddTab( + mTab4, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); doReturn(isIncognito).when(mTab5).isIncognito(); - mTabModel.addTab(mTab5, -1, TabLaunchType.FROM_CHROME_UI); - mTabModelObserverCaptor.getValue().didAddTab(mTab5, TabLaunchType.FROM_CHROME_UI); + mTabModel.addTab( + mTab5, -1, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); + mTabModelObserverCaptor.getValue().didAddTab( + mTab5, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); doReturn(isIncognito).when(mTab6).isIncognito(); - mTabModel.addTab(mTab6, -1, TabLaunchType.FROM_CHROME_UI); - mTabModelObserverCaptor.getValue().didAddTab(mTab6, TabLaunchType.FROM_CHROME_UI); + mTabModel.addTab( + mTab6, -1, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); + mTabModelObserverCaptor.getValue().didAddTab( + mTab6, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); if (isTabRestoreCompleted) { mTabGroupModelFilter.restoreCompleted();
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediatorUnitTest.java index 80fc628..443e79e2 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediatorUnitTest.java
@@ -51,6 +51,7 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; @@ -436,7 +437,8 @@ // Mock that the animation source view is not null. mModel.set(TabGridPanelProperties.ANIMATION_SOURCE_VIEW, mView); - mTabModelObserverCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab( + newTab, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); assertThat(mModel.get(TabGridPanelProperties.ANIMATION_SOURCE_VIEW), equalTo(null)); verify(mDialogController).resetWithListOfTabs(null);
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediatorUnitTest.java index 0c118c1..5ec1522 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiMediatorUnitTest.java
@@ -34,6 +34,7 @@ import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tabmodel.TabModelFilterProvider; @@ -273,7 +274,8 @@ List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2)); createTabGroup(tabGroup, TAB1_ID); - mTabModelObserverCaptor.getValue().didAddTab(mTab2, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab( + mTab2, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true)); verify(mUpdater, never()).updateTabGroupPopUi(); @@ -287,7 +289,8 @@ List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2, mTab3)); createTabGroup(tabGroup, TAB1_ID); - mTabModelObserverCaptor.getValue().didAddTab(mTab3, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab( + mTab3, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true)); verify(mUpdater).updateTabGroupPopUi(); @@ -301,7 +304,8 @@ List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2)); createTabGroup(tabGroup, TAB1_ID); - mTabModelObserverCaptor.getValue().didAddTab(mTab2, TabLaunchType.FROM_RESTORE); + mTabModelObserverCaptor.getValue().didAddTab( + mTab2, TabLaunchType.FROM_RESTORE, TabCreationState.FROZEN_ON_RESTORE); assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(false)); verify(mUpdater, never()).updateTabGroupPopUi(); @@ -316,8 +320,8 @@ List<Tab> tabGroup = new ArrayList<>(Arrays.asList(mTab1, mTab2, mTab3)); createTabGroup(tabGroup, TAB1_ID); - mTabModelObserverCaptor.getValue().didAddTab( - mTab3, TabLaunchType.FROM_LONGPRESS_BACKGROUND); + mTabModelObserverCaptor.getValue().didAddTab(mTab3, TabLaunchType.FROM_LONGPRESS_BACKGROUND, + TabCreationState.LIVE_IN_BACKGROUND); assertThat(mModel.get(TabGroupPopupUiProperties.IS_VISIBLE), equalTo(true)); verify(mUpdater, never()).updateTabGroupPopUi();
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java index 762361a..6d10575c 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java
@@ -45,6 +45,7 @@ import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; @@ -463,8 +464,10 @@ List<Tab> tabs = new ArrayList<>(Arrays.asList(newTab)); doReturn(tabs).when(mTabGroupModelFilter).getRelatedTabList(TAB4_ID); - mTabModelObserverArgumentCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_CHROME_UI); - mTabModelObserverArgumentCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_RESTORE); + mTabModelObserverArgumentCaptor.getValue().didAddTab( + newTab, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); + mTabModelObserverArgumentCaptor.getValue().didAddTab( + newTab, TabLaunchType.FROM_RESTORE, TabCreationState.FROZEN_ON_RESTORE); // Strip should be not be reset when adding a single new tab. verifyNeverReset(); @@ -478,8 +481,10 @@ mTabGroup2.add(newTab); doReturn(mTabGroup1).when(mTabGroupModelFilter).getRelatedTabList(TAB4_ID); - mTabModelObserverArgumentCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_CHROME_UI); - mTabModelObserverArgumentCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_RESTORE); + mTabModelObserverArgumentCaptor.getValue().didAddTab( + newTab, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); + mTabModelObserverArgumentCaptor.getValue().didAddTab( + newTab, TabLaunchType.FROM_RESTORE, TabCreationState.FROZEN_ON_RESTORE); // Strip should be not be reset through these two types of launching. verifyNeverReset(); @@ -493,8 +498,8 @@ mTabGroup2.add(newTab); doReturn(mTabGroup2).when(mTabGroupModelFilter).getRelatedTabList(TAB4_ID); - mTabModelObserverArgumentCaptor.getValue().didAddTab( - newTab, TabLaunchType.FROM_LONGPRESS_BACKGROUND); + mTabModelObserverArgumentCaptor.getValue().didAddTab(newTab, + TabLaunchType.FROM_LONGPRESS_BACKGROUND, TabCreationState.LIVE_IN_FOREGROUND); // Strip should be be reset when long pressing a link and add a tab into group. verifyResetStrip(true, mTabGroup2);
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java index 4fb09fd..6af5a38 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
@@ -87,6 +87,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabObserver; @@ -649,7 +650,8 @@ doReturn(Arrays.asList(newTab)).when(mTabModelFilter).getRelatedTabList(eq(TAB3_ID)); assertThat(mModel.size(), equalTo(2)); - mTabModelObserverCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_RESTORE); + mTabModelObserverCaptor.getValue().didAddTab( + newTab, TabLaunchType.FROM_RESTORE, TabCreationState.LIVE_IN_FOREGROUND); // When tab restoring stage is not yet finished, this tab info should not be added to // property model. @@ -676,7 +678,8 @@ doReturn(tabs).when(mTabModelFilter).getRelatedTabList(eq(TAB2_ID)); assertThat(mModel.size(), equalTo(2)); - mTabModelObserverCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_RESTORE); + mTabModelObserverCaptor.getValue().didAddTab( + newTab, TabLaunchType.FROM_RESTORE, TabCreationState.LIVE_IN_FOREGROUND); TabListMediator.TabActionListener actionListenerAfterUpdate = mModel.get(1).model.get(TabProperties.TAB_SELECTED_LISTENER); @@ -706,10 +709,12 @@ doReturn(1).when(mTabGroupModelFilter).getCount(); mModel.clear(); - mMediatorTabModelObserver.didAddTab(mTab2, TabLaunchType.FROM_RESTORE); + mMediatorTabModelObserver.didAddTab( + mTab2, TabLaunchType.FROM_RESTORE, TabCreationState.LIVE_IN_FOREGROUND); assertThat(mModel.size(), equalTo(0)); - mMediatorTabModelObserver.didAddTab(mTab1, TabLaunchType.FROM_RESTORE); + mMediatorTabModelObserver.didAddTab( + mTab1, TabLaunchType.FROM_RESTORE, TabCreationState.LIVE_IN_FOREGROUND); assertThat(mModel.size(), equalTo(1)); } @@ -729,7 +734,8 @@ .getRelatedTabList(eq(TAB3_ID)); assertThat(mModel.size(), equalTo(2)); - mTabModelObserverCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab( + newTab, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); assertThat(mModel.size(), equalTo(3)); assertThat(mModel.get(2).model.get(TabProperties.TAB_ID), equalTo(TAB3_ID)); @@ -752,7 +758,8 @@ .getRelatedTabList(eq(TAB3_ID)); assertThat(mModel.size(), equalTo(2)); - mTabModelObserverCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab( + newTab, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); assertThat(mModel.size(), equalTo(2)); } @@ -773,7 +780,8 @@ .getRelatedTabList(eq(TAB3_ID)); assertThat(mModel.size(), equalTo(2)); - mTabModelObserverCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab( + newTab, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); assertThat(mModel.size(), equalTo(3)); assertThat(mModel.get(1).model.get(TabProperties.TAB_ID), equalTo(TAB3_ID)); @@ -792,7 +800,8 @@ .getRelatedTabList(eq(TAB1_ID)); assertThat(mModel.size(), equalTo(2)); - mTabModelObserverCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab( + newTab, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); assertThat(mModel.size(), equalTo(3)); assertThat(mModel.get(2).model.get(TabProperties.TAB_ID), equalTo(TAB3_ID)); @@ -811,7 +820,8 @@ .getRelatedTabList(eq(TAB1_ID)); assertThat(mModel.size(), equalTo(2)); - mTabModelObserverCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab( + newTab, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); assertThat(mModel.size(), equalTo(3)); assertThat(mModel.get(1).model.get(TabProperties.TAB_ID), equalTo(TAB3_ID)); @@ -828,7 +838,8 @@ doReturn(Arrays.asList(mTab1, mTab2)).when(mTabModelFilter).getRelatedTabList(eq(TAB1_ID)); assertThat(mModel.size(), equalTo(2)); - mTabModelObserverCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_CHROME_UI); + mTabModelObserverCaptor.getValue().didAddTab( + newTab, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND); assertThat(mModel.size(), equalTo(2)); }
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediatorUnitTest.java index c1b5faf1..892ee9d 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediatorUnitTest.java
@@ -195,7 +195,7 @@ public void tearDown() { RecordUserAction.setDisabledForTests(false); RecordHistogram.setDisabledForTests(false); - CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, false); + CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, null); } @Test
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContextObserverTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContextObserverTest.java index 2c34fc6..e6beea7 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContextObserverTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabContextObserverTest.java
@@ -20,6 +20,7 @@ import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tabmodel.TabModelFilterProvider; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -76,7 +77,8 @@ public void testAddTab() { TabContextObserverTestHelper tabContextObserverTestHelper = new TabContextObserverTestHelper(mTabModelSelector); - tabContextObserverTestHelper.mTabModelObserver.didAddTab(null, 0); + tabContextObserverTestHelper.mTabModelObserver.didAddTab( + null, 0, TabCreationState.LIVE_IN_FOREGROUND); Assert.assertEquals(TabContextObserver.TabContextChangeReason.TAB_ADDED, tabContextObserverTestHelper.getChangeReason()); }
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsOrchestratorTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsOrchestratorTest.java index ac54843..3184508 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsOrchestratorTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/suggestions/TabSuggestionsOrchestratorTest.java
@@ -29,6 +29,7 @@ import org.chromium.base.test.util.InMemorySharedPreferences; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tabmodel.TabModelFilter; import org.chromium.chrome.browser.tabmodel.TabModelFilterProvider; @@ -125,7 +126,8 @@ public void onTabSuggestionInvalidated() {} }; tabSuggestionsOrchestrator.addObserver(tabSuggestionsObserver); - tabSuggestionsOrchestrator.mTabContextObserver.mTabModelObserver.didAddTab(null, 0); + tabSuggestionsOrchestrator.mTabContextObserver.mTabModelObserver.didAddTab( + null, 0, TabCreationState.LIVE_IN_FOREGROUND); Assert.assertEquals(1, suggestions.size()); Assert.assertEquals(TAB_IDS.length, suggestions.get(0).getTabsInfo().size()); for (int idx = 0; idx < TAB_IDS.length; idx++) { @@ -161,7 +163,8 @@ @Override public void onTabSuggestionInvalidated() {} }; - tabSuggestionsOrchestrator.mTabContextObserver.mTabModelObserver.didAddTab(null, 0); + tabSuggestionsOrchestrator.mTabContextObserver.mTabModelObserver.didAddTab( + null, 0, TabCreationState.LIVE_IN_FOREGROUND); Assert.assertEquals(0, suggestions.size()); } @@ -187,7 +190,8 @@ }; tabSuggestionsOrchestrator.addObserver(tabSuggestionsObserver); - tabSuggestionsOrchestrator.mTabContextObserver.mTabModelObserver.didAddTab(null, 0); + tabSuggestionsOrchestrator.mTabContextObserver.mTabModelObserver.didAddTab( + null, 0, TabCreationState.LIVE_IN_FOREGROUND); Assert.assertNotNull(tabSuggestionsOrchestrator.mTabSuggestionFeedback); Assert.assertEquals(tabSuggestionsOrchestrator.mTabSuggestionFeedback.tabSuggestionResponse, TabSuggestionFeedback.TabSuggestionResponse.ACCEPTED);
diff --git a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java index f9ca247..de16d31b 100644 --- a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java +++ b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java
@@ -45,6 +45,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabAssociatedApp; import org.chromium.chrome.browser.tab.TabBrowserControlsConstraintsHelper; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tab.TabRedirectHandler; @@ -302,7 +303,7 @@ } @Override - public void onNewTabCreated(Tab tab) { + public void onNewTabCreated(Tab tab, @TabCreationState int creationState) { if (mNativeVrShell == 0) return; VrShellJni.get().onTabUpdated(mNativeVrShell, VrShell.this, tab.isIncognito(), tab.getId(), tab.getTitle());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java index 34b6012..2cb3f90 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
@@ -42,6 +42,7 @@ import org.chromium.chrome.browser.dependency_injection.DaggerChromeAppComponent; import org.chromium.chrome.browser.dependency_injection.ModuleFactoryOverrides; import org.chromium.chrome.browser.flags.CachedFeatureFlags; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.metrics.UmaUtils; import org.chromium.chrome.browser.night_mode.SystemNightModeMonitor; import org.chromium.chrome.browser.vr.OnExitVrRequestListener; @@ -177,7 +178,7 @@ } private static Boolean shouldUseDebugFlags() { - return CachedFeatureFlags.isCommandLineOnNonRootedEnabled(); + return CachedFeatureFlags.isEnabled(ChromeFeatureList.COMMAND_LINE_ON_NON_ROOTED); } protected static boolean isBrowserProcess() {
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 111d2a55..17fbe02 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -114,6 +114,7 @@ import org.chromium.chrome.browser.survey.ChromeSurveyController; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabAssociatedApp; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabDelegateFactory; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; @@ -588,7 +589,8 @@ } @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { if (type == TabLaunchType.FROM_LONGPRESS_BACKGROUND && !DeviceClassManager.enableAnimations()) { Toast.makeText(ChromeTabbedActivity.this,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelWrapper.java b/chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelWrapper.java index ec55f11..a28d760 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelWrapper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelWrapper.java
@@ -20,6 +20,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.accessibility_tab_switcher.AccessibilityTabModelAdapter.AccessibilityTabModelAdapterListener; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; @@ -55,7 +56,7 @@ } @Override - public void onNewTabCreated(Tab tab) { + public void onNewTabCreated(Tab tab, @TabCreationState int creationState) { getAdapter().notifyDataSetChanged(); } };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegateImpl.java index edd1c6f3..e2eee45 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegateImpl.java
@@ -35,6 +35,7 @@ import org.chromium.chrome.browser.device.DeviceClassManager; import org.chromium.chrome.browser.download.DownloadUtils; import org.chromium.chrome.browser.flags.CachedFeatureFlags; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.incognito.IncognitoUtils; import org.chromium.chrome.browser.multiwindow.MultiWindowModeStateDispatcher; import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; @@ -264,7 +265,7 @@ isChromeScheme || ((TabImpl) currentTab).isShowingInterstitialPage(); menu.findItem(R.id.paint_preview_capture_id) - .setVisible(CachedFeatureFlags.isPaintPreviewTestEnabled() + .setVisible(CachedFeatureFlags.isEnabled(ChromeFeatureList.PAINT_PREVIEW_TEST) && !isChromeOrInterstitialPage && !isIncognito); // Disable find in page on the native NTP.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java index 86002992..3962132d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
@@ -29,7 +29,6 @@ import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager.SnackbarController; @@ -70,8 +69,8 @@ return bookmarkId; } - BookmarkId bookmarkId = addBookmarkInternal( - activity, bookmarkModel, tab.getTitle(), ((TabImpl) tab).getOriginalUrl()); + BookmarkId bookmarkId = + addBookmarkInternal(activity, bookmarkModel, tab.getTitle(), tab.getOriginalUrl()); Snackbar snackbar = null; if (bookmarkId == null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/sharing/TwaSharingController.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/sharing/TwaSharingController.java index e09c9f17..30221d7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/sharing/TwaSharingController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/sharing/TwaSharingController.java
@@ -118,20 +118,13 @@ } private boolean sendPost(ShareData shareData, WebApkInfo.ShareTarget target) { - WebApkInfo.ShareData webApkData = new WebApkInfo.ShareData(); - if (shareData.uris != null) { - webApkData.files = new ArrayList<>(shareData.uris); - } - webApkData.subject = shareData.title; - webApkData.text = shareData.text; - Tab tab = mTabProvider.getTab(); if (tab == null) { assert false : "Null tab when sharing"; return false; } - return mPostNavigator.navigateIfPostShareTarget(target.getAction(), target, webApkData, - tab.getWebContents()); + return mPostNavigator.navigateIfPostShareTarget( + target.getAction(), target, shareData, tab.getWebContents()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java index 6b15046..5273cdb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -51,6 +51,7 @@ import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; @@ -1115,7 +1116,7 @@ } @Override - public void onNewTabCreated(Tab tab) { + public void onNewTabCreated(Tab tab, @TabCreationState int creationState) { initializeTab(tab); } });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java index 920e3a8..56df00a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java
@@ -38,6 +38,7 @@ import org.chromium.chrome.browser.tab.SadTab; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabBrowserControlsConstraintsHelper; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabHidingType; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; @@ -163,7 +164,8 @@ } @Override - public void didAddTab(Tab tab, @TabLaunchType int launchType) { + public void didAddTab( + Tab tab, @TabLaunchType int launchType, @TabCreationState int creationState) { int tabId = tab.getId(); if (launchType == TabLaunchType.FROM_RESTORE) { getActiveLayout().onTabRestored(time(), tabId);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java index 571c3a2..cfb8d14 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
@@ -13,6 +13,7 @@ import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutHelperManager; import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagementDelegate; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -150,8 +151,9 @@ protected LayoutManagerTabModelObserver createTabModelObserver() { return new LayoutManagerTabModelObserver() { @Override - public void didAddTab(Tab tab, @TabLaunchType int launchType) { - super.didAddTab(tab, launchType); + public void didAddTab( + Tab tab, @TabLaunchType int launchType, @TabCreationState int creationState) { + super.didAddTab(tab, launchType, creationState); updateTitle(getTabById(tab.getId())); } };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java index 0240c87..a79597b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -46,6 +46,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.SadTab; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabRedirectHandler; @@ -552,7 +553,8 @@ } @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { // If we're in the process of promoting this tab, just return and don't mess with // this state. if (tab.getWebContents() == getSearchPanelWebContents()) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java index 7e154a1..65a696e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java
@@ -42,6 +42,7 @@ import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabAssociatedApp; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabRedirectHandler; import org.chromium.chrome.browser.tab_activity_glue.ReparentingDelegateFactory; @@ -307,7 +308,7 @@ assert tab != null; if (mode != TabCreationMode.RESTORED) { - tabModel.addTab(tab, 0, tab.getLaunchType()); + tabModel.addTab(tab, 0, tab.getLaunchType(), TabCreationState.LIVE_IN_FOREGROUND); } // This cannot be done before because we want to do the reparenting only @@ -318,7 +319,7 @@ mReparentingTaskProvider.get(tab).finish( ReparentingDelegateFactory.createReparentingTaskDelegate( mActivity.getCompositorViewHolder(), mActivity.getWindowAndroid(), - mActivity.getTabDelegateFactory()), + mCustomTabDelegateFactory.get()), (params == null ? null : params.getFinalizeCallback())); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrar.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrar.java index 74fc2f8..a1d9b22 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrar.java
@@ -13,6 +13,7 @@ import org.chromium.chrome.browser.metrics.PageLoadMetrics; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; @@ -118,7 +119,7 @@ } @Override - public void didAddTab(Tab tab, int type) { + public void didAddTab(Tab tab, int type, @TabCreationState int creationState) { addObserversForTab(tab); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java index 8c86fc2..5ae1415 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
@@ -14,7 +14,6 @@ import org.chromium.base.library_loader.LibraryLoader; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; -import org.chromium.chrome.browser.toolbar.bottom.BottomToolbarConfiguration; import java.util.HashMap; import java.util.List; @@ -243,10 +242,6 @@ parameter.getSharedPreferenceKey(), parameter.getDefaultValue()); } - public static boolean isCommandLineOnNonRootedEnabled() { - return isEnabled(ChromeFeatureList.COMMAND_LINE_ON_NON_ROOTED); - } - private static void cacheStartSurfaceVariation() { String feature = ChromeFeatureList.getFieldTrialParamByFeature( ChromeFeatureList.START_SURFACE_ANDROID, "start_surface_variation"); @@ -263,13 +258,6 @@ } /** - * @return Whether the Paint Preview capture test is enabled. - */ - public static boolean isPaintPreviewTestEnabled() { - return isEnabled(ChromeFeatureList.PAINT_PREVIEW_TEST); - } - - /** * @return Whether the Start Surface SinglePane is enabled. */ public static boolean isStartSurfaceSinglePaneEnabled() { @@ -297,14 +285,6 @@ } /** - * @return Whether or not bootstrap tasks should be prioritized (i.e. bootstrap task - * prioritization experiment is enabled). - */ - public static boolean shouldPrioritizeBootstrapTasks() { - return isEnabled(ChromeFeatureList.PRIORITIZE_BOOTSTRAP_TASKS); - } - - /** * Cache whether warming up network service process is enabled, so that the value * can be made available immediately on next start up. */ @@ -323,13 +303,6 @@ } /** - * @return Whether immersive ui mode is enabled. - */ - public static boolean isImmersiveUiModeEnabled() { - return isEnabled(ChromeFeatureList.IMMERSIVE_UI_MODE); - } - - /** * Returns whether to use {@link Window#setFormat()} to undo opacity change caused by * {@link Activity#convertFromTranslucent()}. */ @@ -423,12 +396,6 @@ return swapped; } - @Deprecated - public static boolean isBottomToolbarEnabled() { - // TODO(crbug.com/1012975): Remove this when downstream calls BottomToolbarConfiguration. - return BottomToolbarConfiguration.isBottomToolbarEnabled(); - } - @NativeMethods interface Natives { boolean isNetworkServiceWarmUpEnabled();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/flags/LegacyFeatureUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/flags/LegacyFeatureUtilities.java deleted file mode 100644 index c5b5b6c..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/flags/LegacyFeatureUtilities.java +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.flags; - -/** - * Temporary class, identical to {@link CachedFeatureFlags}, for migration. - * - * This class will be referenced temporarily while FeatureUtilities is renamed. - * - * TODO(crbug.com/1012975): Remove this class after downstream references FeatureUtilities by the - * new name. - */ -public class LegacyFeatureUtilities extends CachedFeatureFlags {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java index 98658d79..9970f86 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
@@ -158,7 +158,7 @@ protected void handlePreNativeInitialization() { BrowserTaskExecutor.register(); BrowserTaskExecutor.setShouldPrioritizeBootstrapTasks( - CachedFeatureFlags.shouldPrioritizeBootstrapTasks()); + CachedFeatureFlags.isEnabled(ChromeFeatureList.PRIORITIZE_BOOTSTRAP_TASKS)); Context application = ContextUtils.getApplicationContext();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetrics.java index 49ed214..da0d620 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetrics.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetrics.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; @@ -128,7 +129,8 @@ mTabModelObserver = new TabModelSelectorTabModelObserver(mActivity.getTabModelSelector()) { @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { if (type == TabLaunchType.FROM_RESTORE) return; if (NewTabPage.isNTPUrl(tab.getUrlString())) { recordUserBehavior(MainIntentActionType.NTP_CREATED);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeReparentingController.java b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeReparentingController.java index c7f87f4..0ecccbe 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeReparentingController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeReparentingController.java
@@ -10,6 +10,7 @@ import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab_activity_glue.ReparentingTask; import org.chromium.chrome.browser.tabmodel.AsyncTabParams; @@ -92,7 +93,8 @@ private void reattachTab(ReparentingTask task, TabReparentingParams params, TabModel tabModel) { final Tab tab = params.getTabToReparent(); task.finish(mReparentingDelegate, () -> { - tabModel.addTab(tab, params.getTabIndex(), TabLaunchType.FROM_REPARENTING); + tabModel.addTab(tab, params.getTabIndex(), TabLaunchType.FROM_REPARENTING, + TabCreationState.LIVE_IN_FOREGROUND); AsyncTabParamsManager.remove(tab.getId()); }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java index e59736a5..34b7d8a1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageUma.java
@@ -18,6 +18,7 @@ import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.components.embedder_support.util.UrlUtilitiesJni; @@ -326,7 +327,7 @@ */ private static class TabCreationRecorder extends EmptyTabModelSelectorObserver { @Override - public void onNewTabCreated(Tab tab) { + public void onNewTabCreated(Tab tab, @TabCreationState int creationState) { if (!NewTabPage.isNTPUrl(tab.getUrlString())) return; RecordUserAction.record("MobileNTPOpenedInNewTab"); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java index bc50ab2..8ae7773 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java
@@ -33,6 +33,7 @@ import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.SadTab; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -806,7 +807,8 @@ } @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { tab.addObserver(sTabRestoreTracker); }
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 bb79dcf..8671391 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
@@ -58,7 +58,7 @@ import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogProperties; -import org.chromium.ui.modelutil.MVCListAdapter.ListItem; +import org.chromium.ui.modelutil.MVCListAdapter; import org.chromium.ui.modelutil.MVCListAdapter.ModelList; import org.chromium.ui.modelutil.PropertyModel; @@ -73,21 +73,18 @@ class AutocompleteMediator implements OnSuggestionsReceivedListener, SuggestionHost, StartStopWithNativeObserver, SuggestionListObserver { /** A struct containing information about the suggestion and its view type. */ - private static class SuggestionViewInfo { + private static class SuggestionViewInfo extends MVCListAdapter.ListItem { /** Processor managing the suggestion. */ public final SuggestionProcessor processor; /** The suggestion this info represents. */ public final OmniboxSuggestion suggestion; - /** The model the view uses to render the suggestion. */ - public final PropertyModel model; - public SuggestionViewInfo(SuggestionProcessor suggestionProcessor, OmniboxSuggestion omniboxSuggestion, PropertyModel propertyModel) { + super(suggestionProcessor.getViewTypeId(), propertyModel); processor = suggestionProcessor; suggestion = omniboxSuggestion; - model = propertyModel; } } @@ -105,7 +102,6 @@ private final AutocompleteDelegate mDelegate; private final UrlBarEditingTextStateProvider mUrlBarEditingTextProvider; private final PropertyModel mListPropertyModel; - private final List<SuggestionViewInfo> mCurrentModels; private final List<Runnable> mDeferredNativeRunnables = new ArrayList<Runnable>(); private final Handler mHandler; private final BasicSuggestionProcessor mBasicSuggestionProcessor; @@ -154,7 +150,6 @@ private boolean mShowCachedZeroSuggestResults; private boolean mShouldPreventOmniboxAutocomplete; - private boolean mPreventSuggestionListPropertyChanges; private long mLastActionUpTimestamp; private boolean mIgnoreOmniboxItemSelection = true; private boolean mUseDarkColors = true; @@ -173,7 +168,6 @@ mDelegate = delegate; mUrlBarEditingTextProvider = textProvider; mListPropertyModel = listPropertyModel; - mCurrentModels = new ArrayList<>(); mAutocomplete = new AutocompleteController(this); mHandler = new Handler(); @@ -222,13 +216,8 @@ recordSuggestionsShown(); } - /** - * Clear all suggestions and update counter of whether AiS Answer was presented (and if so - of - * what type). Does not notify any property observers of the change. - */ - private void clearSuggestions() { - mCurrentModels.clear(); - notifyPropertyModelsChanged(); + private ModelList getSuggestionModelList() { + return mListPropertyModel.get(SuggestionListProperties.SUGGESTION_MODELS); } /** @@ -305,7 +294,9 @@ */ private void recordSuggestionsShown() { int richEntitiesCount = 0; - for (SuggestionViewInfo info : mCurrentModels) { + ModelList currentModels = getSuggestionModelList(); + for (int i = 0; i < currentModels.size(); i++) { + SuggestionViewInfo info = (SuggestionViewInfo) currentModels.get(i); info.processor.recordSuggestionPresented(info.suggestion, info.model); if (info.processor.getViewTypeId() == OmniboxSuggestionUiType.ENTITY_SUGGESTION) { @@ -324,7 +315,7 @@ * @return The number of current autocomplete suggestions. */ public int getSuggestionCount() { - return mCurrentModels.size(); + return getSuggestionModelList().size(); } /** @@ -336,17 +327,7 @@ * @return The suggestion at the given index. */ public OmniboxSuggestion getSuggestionAt(int index) { - return mCurrentModels.get(index).suggestion; - } - - private void notifyPropertyModelsChanged() { - if (mPreventSuggestionListPropertyChanges) return; - ModelList suggestions = mListPropertyModel.get(SuggestionListProperties.SUGGESTION_MODELS); - suggestions.clear(); - for (int i = 0; i < mCurrentModels.size(); i++) { - PropertyModel model = mCurrentModels.get(i).model; - suggestions.add(new ListItem(mCurrentModels.get(i).processor.getViewTypeId(), model)); - } + return ((SuggestionViewInfo) getSuggestionModelList().get(index)).suggestion; } /** @@ -393,8 +374,9 @@ void setLayoutDirection(int layoutDirection) { if (mLayoutDirection == layoutDirection) return; mLayoutDirection = layoutDirection; - for (int i = 0; i < mCurrentModels.size(); i++) { - PropertyModel model = mCurrentModels.get(i).model; + ModelList currentModels = getSuggestionModelList(); + for (int i = 0; i < currentModels.size(); i++) { + PropertyModel model = currentModels.get(i).model; model.set(SuggestionCommonProperties.LAYOUT_DIRECTION, layoutDirection); } } @@ -407,8 +389,9 @@ void updateVisualsForState(boolean useDarkColors, boolean isIncognito) { mUseDarkColors = useDarkColors; mListPropertyModel.set(SuggestionListProperties.IS_INCOGNITO, isIncognito); - for (int i = 0; i < mCurrentModels.size(); i++) { - PropertyModel model = mCurrentModels.get(i).model; + ModelList currentModels = getSuggestionModelList(); + for (int i = 0; i < currentModels.size(); i++) { + PropertyModel model = currentModels.get(i).model; model.set(SuggestionCommonProperties.USE_DARK_COLORS, useDarkColors); } } @@ -620,7 +603,8 @@ // In some situations this means the content of mCurrentModels may change meanwhile. int verifiedIndex = findSuggestionInModel(suggestion, position); if (verifiedIndex != SUGGESTION_NOT_FOUND) { - SuggestionViewInfo info = mCurrentModels.get(verifiedIndex); + SuggestionViewInfo info = + (SuggestionViewInfo) getSuggestionModelList().get(verifiedIndex); info.processor.recordSuggestionUsed(info.suggestion, info.model); } @@ -887,10 +871,13 @@ String userText = mUrlBarEditingTextProvider.getTextWithoutAutocomplete(); mUrlTextAfterSuggestionsReceived = userText + inlineAutocompleteText; - if (mCurrentModels.size() == newSuggestions.size()) { + ModelList modelList = getSuggestionModelList(); + if (modelList.size() == newSuggestions.size()) { boolean sameSuggestions = true; - for (int i = 0; i < mCurrentModels.size(); i++) { - if (!mCurrentModels.get(i).suggestion.equals(newSuggestions.get(i))) { + for (int i = 0; i < modelList.size(); i++) { + OmniboxSuggestion existingSuggestion = + ((SuggestionViewInfo) modelList.get(i)).suggestion; + if (!existingSuggestion.equals(newSuggestions.get(i))) { sameSuggestions = false; break; } @@ -900,27 +887,21 @@ // Show the suggestion list. mTailSuggestionProcessor.reset(); - // Ensure the list is fully replaced before broadcasting any change notifications. - mPreventSuggestionListPropertyChanges = true; - mCurrentModels.clear(); + List<MVCListAdapter.ListItem> newSuggestionViewInfos = + new ArrayList<>(newSuggestions.size()); for (int i = 0; i < newSuggestions.size(); i++) { OmniboxSuggestion suggestion = newSuggestions.get(i); SuggestionProcessor processor = getProcessorForSuggestion(suggestion, i == 0); PropertyModel model = processor.createModelForSuggestion(suggestion); model.set(SuggestionCommonProperties.LAYOUT_DIRECTION, mLayoutDirection); model.set(SuggestionCommonProperties.USE_DARK_COLORS, mUseDarkColors); - - // Before populating the model, add it to the list of current models. If the suggestion - // has an image and the image was already cached, it will be updated synchronously and - // the model will only have the image populated if it is tracked as a current model. - mCurrentModels.add(new SuggestionViewInfo(processor, suggestion, model)); - processor.populateModel(suggestion, model, i); + newSuggestionViewInfos.add(new SuggestionViewInfo(processor, suggestion, model)); } - mPreventSuggestionListPropertyChanges = false; - notifyPropertyModelsChanged(); + modelList.set(newSuggestionViewInfos); - if (mListPropertyModel.get(SuggestionListProperties.VISIBLE) && getSuggestionCount() == 0) { + if (mListPropertyModel.get(SuggestionListProperties.VISIBLE) + && newSuggestionViewInfos.size() == 0) { hideSuggestions(); } mDelegate.onSuggestionsChanged(inlineAutocompleteText); @@ -1085,7 +1066,7 @@ stopAutocomplete(true); - clearSuggestions(); + getSuggestionModelList().clear(); updateOmniboxSuggestionsVisibility(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/voice/AssistantVoiceSearchService.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/voice/AssistantVoiceSearchService.java index 7149dc5..1933af0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/voice/AssistantVoiceSearchService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/voice/AssistantVoiceSearchService.java
@@ -58,7 +58,7 @@ // TODO(crbug.com/1041576): Update this placeholder to a the real min version once the code has // landed. @VisibleForTesting - public static final String DEFAULT_ASSISTANT_AGSA_MIN_VERSION = "10.95"; + public static final String DEFAULT_ASSISTANT_AGSA_MIN_VERSION = "10.98"; @VisibleForTesting public static final int DEFAULT_ASSISTANT_MIN_ANDROID_SDK_VERSION = Build.VERSION_CODES.LOLLIPOP;
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 cb44ea2..3aa292a 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
@@ -113,6 +113,12 @@ GURL getUrl(); /** + * @return Original url of the tab without any Chrome feature modifications applied + * (e.g. reader mode). + */ + String getOriginalUrl(); + + /** * @return The tab title. */ String getTitle();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBuilder.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBuilder.java index 385a3000..69a8956 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBuilder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBuilder.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.browser.tab; -import org.chromium.chrome.browser.tab.TabUma.TabCreationState; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.WindowAndroid;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabCreationState.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabCreationState.java new file mode 100644 index 0000000..6a3fddd6 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabCreationState.java
@@ -0,0 +1,26 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.tab; + +import androidx.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * State in which the tab was created. This can be used in metric accounting - e.g. to + * distinguish reasons for a tab to be restored upon first display. + */ +@IntDef({TabCreationState.LIVE_IN_FOREGROUND, TabCreationState.LIVE_IN_BACKGROUND, + TabCreationState.FROZEN_ON_RESTORE, TabCreationState.FROZEN_FOR_LAZY_LOAD, + TabCreationState.FROZEN_ON_RESTORE_FAILED}) +@Retention(RetentionPolicy.SOURCE) +public @interface TabCreationState { + int LIVE_IN_FOREGROUND = 0; + int LIVE_IN_BACKGROUND = 1; + int FROZEN_ON_RESTORE = 2; + int FROZEN_FOR_LAZY_LOAD = 3; + int FROZEN_ON_RESTORE_FAILED = 4; +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabHelpers.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabHelpers.java index 3fd8ed6..070ebed 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabHelpers.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabHelpers.java
@@ -14,7 +14,6 @@ import org.chromium.chrome.browser.infobar.InfoBarContainer; import org.chromium.chrome.browser.media.ui.MediaSessionTabHelper; import org.chromium.chrome.browser.paint_preview.PaintPreviewTabHelper; -import org.chromium.chrome.browser.tab.TabUma.TabCreationState; import org.chromium.chrome.browser.tasks.TaskRecognizer; import org.chromium.content_public.browser.SelectionPopupController; import org.chromium.content_public.browser.WebContents;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java index 7c3f1bb..4284ce6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -38,7 +38,6 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.rlz.RevenueStats; import org.chromium.chrome.browser.tab.TabState.WebContentsState; -import org.chromium.chrome.browser.tab.TabUma.TabCreationState; import org.chromium.chrome.browser.ui.TabObscuringHandler; import org.chromium.chrome.browser.ui.native_page.FrozenNativePage; import org.chromium.chrome.browser.ui.native_page.NativePage; @@ -369,6 +368,11 @@ return mUrl != null ? mUrl : GURL.emptyGURL(); } + @Override + public String getOriginalUrl() { + return DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(getUrlString()); + } + @CalledByNative @Override public String getTitle() { @@ -726,13 +730,6 @@ } /** - * @return Original url of the tab, which is the original url from DOMDistiller. - */ - public String getOriginalUrl() { - return DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(getUrlString()); - } - - /** * @return Whether or not the {@link Tab} is currently showing an interstitial page, such as * a bad HTTPS page. */ @@ -771,14 +768,6 @@ mIsTabStateDirty = isDirty; } - /** - * @return Whether there are pending {@link LoadUrlParams} associated with the tab. This - * indicates the tab was created for lazy load. - */ - public boolean hasPendingLoadParams() { - return mPendingLoadParams != null; - } - // TabObscuringHandler.Observer @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUma.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUma.java index 920adccb..2759b3d5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUma.java
@@ -7,8 +7,6 @@ import android.os.SystemClock; import android.text.format.DateUtils; -import androidx.annotation.IntDef; - import org.chromium.base.UserData; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; @@ -17,9 +15,6 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.net.NetError; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - /** * Centralizes UMA data collection for Tab management. * This will drive our memory optimization efforts, specially tab restoring and @@ -65,22 +60,6 @@ // Counter of tab shows (as per onShow()) for all tabs. private static long sAllTabsShowCount; - /** - * State in which the tab was created. This can be used in metric accounting - e.g. to - * distinguish reasons for a tab to be restored upon first display. - */ - @IntDef({TabCreationState.LIVE_IN_FOREGROUND, TabCreationState.LIVE_IN_BACKGROUND, - TabCreationState.FROZEN_ON_RESTORE, TabCreationState.FROZEN_FOR_LAZY_LOAD, - TabCreationState.FROZEN_ON_RESTORE_FAILED}) - @Retention(RetentionPolicy.SOURCE) - public @interface TabCreationState { - int LIVE_IN_FOREGROUND = 0; - int LIVE_IN_BACKGROUND = 1; - int FROZEN_ON_RESTORE = 2; - int FROZEN_FOR_LAZY_LOAD = 3; - int FROZEN_ON_RESTORE_FAILED = 4; - } - private final @TabCreationState int mTabCreationState; // Timestamp when this tab was last shown. @@ -315,7 +294,7 @@ // where this is created too early and we start missing out on metrics suddenly. mNewTabObserver = new EmptyTabModelSelectorObserver() { @Override - public void onNewTabCreated(Tab newTab) { + public void onNewTabCreated(Tab newTab, @TabCreationState int creationState) { if (newTab.getParentId() == tab.getId() && newTab.getLaunchType() == TabLaunchType.FROM_LONGPRESS_BACKGROUND) { onBackgroundTabOpenedFromContextMenu(newTab);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java index 504f1c31..c05e5e0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabAssociatedApp; import org.chromium.chrome.browser.tab.TabBuilder; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabDelegateFactory; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabParentIntent; @@ -146,6 +147,8 @@ TabDelegateFactory delegateFactory = parent == null ? createDefaultTabDelegateFactory() : null; Tab tab; + @TabCreationState + int creationState = TabCreationState.LIVE_IN_FOREGROUND; if (asyncParams != null && asyncParams.getTabToReparent() != null) { type = TabLaunchType.FROM_REPARENTING; @@ -154,7 +157,7 @@ ReparentingTask.from(tab).finish( ReparentingDelegateFactory.createReparentingTaskDelegate( mActivity.getCompositorViewHolder(), mActivity.getWindowAndroid(), - mActivity.getTabDelegateFactory()), + createDefaultTabDelegateFactory()), params.getFinalizeCallback()); } else if (asyncParams != null && asyncParams.getWebContents() != null) { openInForeground = true; @@ -192,6 +195,7 @@ .setDelegateFactory(delegateFactory) .setInitiallyHidden(!openInForeground) .build(); + creationState = TabCreationState.FROZEN_FOR_LAZY_LOAD; } else { tab = (mStartupTabPreloader != null) ? mStartupTabPreloader.takeTabIfMatchingOrDestroy(loadUrlParams, type) @@ -218,7 +222,10 @@ tab.getWebContents()); } - mTabModel.addTab(tab, position, type); + if (creationState == TabCreationState.LIVE_IN_FOREGROUND && !openInForeground) { + creationState = TabCreationState.LIVE_IN_BACKGROUND; + } + mTabModel.addTab(tab, position, type, creationState); return tab; } finally { TraceEvent.end("ChromeTabCreator.createNewTab"); @@ -249,7 +256,10 @@ .setDelegateFactory(delegateFactory) .setInitiallyHidden(!openInForeground) .build(); - mTabModel.addTab(tab, position, type); + @TabCreationState + int creationState = openInForeground ? TabCreationState.LIVE_IN_FOREGROUND + : TabCreationState.LIVE_IN_BACKGROUND; + mTabModel.addTab(tab, position, type, creationState); return true; } @@ -358,7 +368,8 @@ .setTabState(state) .build(); assert state.isIncognito() == mIncognito; - mTabModel.addTab(tab, index, TabLaunchType.FROM_RESTORE); + mTabModel.addTab( + tab, index, TabLaunchType.FROM_RESTORE, TabCreationState.FROZEN_ON_RESTORE); return tab; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java index 14d1c02..9b5625a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java
@@ -8,6 +8,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; @@ -139,7 +140,8 @@ } @Override - public void addTab(Tab tab, int index, @TabLaunchType int type) { + public void addTab( + Tab tab, int index, @TabLaunchType int type, @TabCreationState int creationState) { assert false; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelObserver.java index 04cce22f0..fd30b5ed 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelObserver.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.tabmodel; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; @@ -27,7 +28,7 @@ public void willAddTab(Tab tab, @TabLaunchType int type) {} @Override - public void didAddTab(Tab tab, @TabLaunchType int type) {} + public void didAddTab(Tab tab, @TabLaunchType int type, @TabCreationState int creationState) {} @Override public void didMoveTab(Tab tab, int newIndex, int curIndex) {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelSelectorObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelSelectorObserver.java index 9b3f52b..08ed605b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelSelectorObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelSelectorObserver.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.tabmodel; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; /** * Empty implementation of the tab model selector observer. @@ -15,8 +16,7 @@ } @Override - public void onNewTabCreated(Tab tab) { - } + public void onNewTabCreated(Tab tab, @TabCreationState int creationState) {} @Override public void onTabModelSelected(TabModel newModel, TabModel oldModel) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java index 045dcfd..f2ff60a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java
@@ -9,6 +9,7 @@ import org.chromium.chrome.browser.incognito.IncognitoNotificationManager; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; @@ -241,10 +242,11 @@ } @Override - public void addTab(Tab tab, int index, @TabLaunchType int type) { + public void addTab( + Tab tab, int index, @TabLaunchType int type, @TabCreationState int creationState) { mIsAddingTab = true; ensureTabModelImpl(); - mDelegateModel.addTab(tab, index, type); + mDelegateModel.addTab(tab, index, type, creationState); mIsAddingTab = false; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java index 67d3dd8..0cefd102 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java
@@ -8,6 +8,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; @@ -169,8 +170,9 @@ * @param tab The tab to be added. * @param index The index where the tab should be inserted. The model may override the index. * @param type How the tab was opened. + * @param creationState How the tab was created. */ - void addTab(Tab tab, int index, @TabLaunchType int type); + void addTab(Tab tab, int index, @TabLaunchType int type, @TabCreationState int creationState); /** * Removes the given tab from the model without destroying it. The tab should be inserted into
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java index e15478f2..43ad577b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java
@@ -9,6 +9,7 @@ import org.chromium.base.ObserverList; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import java.util.ArrayList; @@ -215,10 +216,10 @@ } @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab(Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { addTab(tab); for (TabModelObserver observer : mFilteredObservers) { - observer.didAddTab(tab, type); + observer.didAddTab(tab, type, creationState); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java index cf13a9b..7b696e7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java
@@ -13,6 +13,7 @@ import org.chromium.chrome.browser.partnercustomizations.HomepageManager; import org.chromium.chrome.browser.tab.InterceptNavigationDelegateImpl; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tab.TabState; @@ -137,7 +138,8 @@ * step notifications. */ @Override - public void addTab(Tab tab, int index, @TabLaunchType int type) { + public void addTab( + Tab tab, int index, @TabLaunchType int type, @TabCreationState int creationState) { try { TraceEvent.begin("TabModelImpl.addTab"); @@ -176,7 +178,7 @@ int newIndex = indexOf(tab); tabAddedToModel(tab); - for (TabModelObserver obs : mObservers) obs.didAddTab(tab, type); + for (TabModelObserver obs : mObservers) obs.didAddTab(tab, type, creationState); // setIndex takes care of making sure the appropriate model is active. if (selectTab) setIndex(newIndex, TabSelectionType.FROM_NEW);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserver.java index e310350..c9275b47 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserver.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.tabmodel; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; @@ -53,8 +54,9 @@ * * @param tab The newly added tab. * @param type The type of tab launch. + * @param creationState How the tab was created. */ - void didAddTab(Tab tab, @TabLaunchType int type); + void didAddTab(Tab tab, @TabLaunchType int type, @TabCreationState int creationState); /** * Called after a tab has been moved from one position in the {@link TabModel} to another.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserverJniBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserverJniBridge.java index fb62159..3fb12c81 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserverJniBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserverJniBridge.java
@@ -7,6 +7,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; @@ -66,7 +67,8 @@ } @Override - public final void didAddTab(Tab tab, @TabLaunchType int type) { + public final void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { assert mNativeTabModelObserverJniBridge != 0; TabModelObserverJniBridgeJni.get().didAddTab( mNativeTabModelObserverJniBridge, TabModelObserverJniBridge.this, tab, type);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java index 52cf76c..e5a2d8c1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java
@@ -7,6 +7,7 @@ import org.chromium.base.ObserverList; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.content_public.browser.LoadUrlParams; @@ -55,9 +56,10 @@ TabModelObserver tabModelObserver = new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { notifyChanged(); - notifyNewTabCreated(tab); + notifyNewTabCreated(tab, creationState); } @Override @@ -278,10 +280,11 @@ /** * Notifies all the listeners that a new tab has been created. * @param tab The tab that has been created. + * @param creationSTate How the tab was created. */ - private void notifyNewTabCreated(Tab tab) { + private void notifyNewTabCreated(Tab tab, @TabCreationState int creationState) { for (TabModelSelectorObserver listener : mObservers) { - listener.onNewTabCreated(tab); + listener.onNewTabCreated(tab, creationState); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java index 7c87352..a5ca77d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java
@@ -13,6 +13,7 @@ import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.tab.SadTab; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabHidingType; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; @@ -138,13 +139,15 @@ addObserver(new EmptyTabModelSelectorObserver() { @Override - public void onNewTabCreated(Tab tab) { + public void onNewTabCreated(Tab tab, @TabCreationState int creationState) { // Only invalidate if the tab exists in the currently selected model. if (TabModelUtils.getTabById(getCurrentModel(), tab.getId()) != null) { mTabContentManager.invalidateIfChanged(tab.getId(), tab.getUrlString()); } - if (((TabImpl) tab).hasPendingLoadParams()) mTabSaver.addTabToSaveQueue(tab); + if (creationState == TabCreationState.FROZEN_FOR_LAZY_LOAD) { + mTabSaver.addTabToSaveQueue(tab); + } } });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorObserver.java index ebc6624f..75f7b47b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorObserver.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.tabmodel; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; /** * Observes changes to the tab model selector. @@ -17,8 +18,10 @@ /** * Called when a new tab is created. + * @param tab A new tab being created. + * @param creationState How the tab was created. */ - void onNewTabCreated(Tab tab); + void onNewTabCreated(Tab tab, @TabCreationState int creationState); /** * Called when a different tab model has been selected.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabModelObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabModelObserver.java index fcf9999..5a5eb04a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabModelObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabModelObserver.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.tabmodel; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import java.util.List; @@ -36,7 +37,7 @@ if (tabModels.isEmpty()) { mSelectorObserver = new EmptyTabModelSelectorObserver() { @Override - public void onNewTabCreated(Tab tab) { + public void onNewTabCreated(Tab tab, @TabCreationState int creationState) { throw new IllegalStateException( "onChange should have happened and unregistered this listener."); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserver.java index 263bfee..53cb7cf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserver.java
@@ -10,6 +10,7 @@ import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.content_public.browser.UiThreadTaskTraits; @@ -40,7 +41,8 @@ mTabModelObserver = new TabModelSelectorTabModelObserver(selector) { @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { // This observer is automatically removed by tab when it is destroyed. tab.addObserver(TabModelSelectorTabObserver.this); onTabRegistered(tab);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java index 9b90bc1..bfe8d4c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java
@@ -181,7 +181,7 @@ } if (isOfflinePage()) { - String originalUrl = ((TabImpl) mTab).getOriginalUrl(); + String originalUrl = mTab.getOriginalUrl(); formattedUrl = UrlUtilities.stripScheme( DomDistillerTabUtils.getFormattedUrlFromOriginalDistillerUrl(originalUrl));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabCountProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabCountProvider.java index fc91e18..8a4dbf3d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabCountProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabCountProvider.java
@@ -6,6 +6,7 @@ import org.chromium.base.ObserverList; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; @@ -106,7 +107,8 @@ mTabModelFilterObserver = new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { updateTabCount(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java index bdbbedf..7646910b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java
@@ -59,7 +59,6 @@ import org.chromium.chrome.browser.page_info.PageInfoController; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TrustedCdn; import org.chromium.chrome.browser.toolbar.ToolbarColors; import org.chromium.chrome.browser.toolbar.ToolbarDataProvider; @@ -535,7 +534,7 @@ if (v == mTitleUrlContainer) { Tab tab = getCurrentTab(); if (tab == null) return false; - Clipboard.getInstance().copyUrlToClipboard(((TabImpl) tab).getOriginalUrl()); + Clipboard.getInstance().copyUrlToClipboard(tab.getOriginalUrl()); return true; } return false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java index 7f79220..cef7b9d9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java
@@ -16,6 +16,7 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; @@ -236,7 +237,7 @@ if (isNewTabVariationEnabled()) { mTabModelObserver = new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, int type) { + public void didAddTab(Tab tab, int type, @TabCreationState int creationState) { assert tab.isIncognito(); updateIncognitoTabsCount(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/EmptyBackgroundViewWrapper.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/EmptyBackgroundViewWrapper.java index 8a7461e..6f3068f0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/EmptyBackgroundViewWrapper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/EmptyBackgroundViewWrapper.java
@@ -16,6 +16,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; @@ -76,7 +77,8 @@ mTabModelObserver = new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { updateEmptyContainerState(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/incognitotoggle/IncognitoToggleButtonTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/incognitotoggle/IncognitoToggleButtonTablet.java index 164d38e36..73a5156 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/incognitotoggle/IncognitoToggleButtonTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/tablet/emptybackground/incognitotoggle/IncognitoToggleButtonTablet.java
@@ -10,6 +10,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -70,7 +71,8 @@ mTabModelObserver = new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { updateButtonVisibility(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java index 57145db5..5110134 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java
@@ -15,6 +15,7 @@ import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.SadTab; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabHidingType; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabObserver; @@ -97,7 +98,8 @@ } @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { activeTabChanged(tab); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkActivity.java index 5fd8139..a72e4f8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkActivity.java
@@ -7,6 +7,8 @@ import android.content.Intent; import android.os.Bundle; +import androidx.browser.trusted.sharing.ShareData; + import org.chromium.base.IntentUtils; import org.chromium.chrome.browser.flags.ActivityType; import org.chromium.content_public.browser.WebContents; @@ -60,7 +62,7 @@ @Override protected boolean loadUrlIfPostShareTarget(WebappInfo webappInfo) { WebApkInfo webApkInfo = (WebApkInfo) webappInfo; - WebApkInfo.ShareData shareData = webApkInfo.shareData(); + ShareData shareData = webApkInfo.shareData(); if (shareData == null) { return false; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkExtras.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkExtras.java index 03ddfaf..30917de 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkExtras.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkExtras.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.browser.webapps; -import org.chromium.chrome.browser.webapps.WebApkInfo.ShareData; import org.chromium.chrome.browser.webapps.WebApkInfo.ShareTarget; import java.util.ArrayList; @@ -74,13 +73,6 @@ public final boolean isSplashProvidedByWebApk; /** - * Shared information from the share intent. - * TODO(pkotwicz): Remove this property in favor of - * {@link BrowserServicesIntentDataProvider#shareData()} - */ - public final ShareData shareData; - - /** * The list of the WebAPK's shortcuts. */ public final List<ShortcutItem> shortcutItems; @@ -113,15 +105,15 @@ false /* isSplashIconMaskable */, 0 /* shellApkVersion */, null /* manifestUrl */, null /* manifestStartUrl */, WebApkDistributor.OTHER, null /* iconUrlToMurmur2HashMap */, new ShareTarget(), - false /* isSplashProvidedByWebApk */, null /* shareData */, - new ArrayList<>() /* shortcutItems */, 0 /* webApkVersionCode */); + false /* isSplashProvidedByWebApk */, new ArrayList<>() /* shortcutItems */, + 0 /* webApkVersionCode */); } public WebApkExtras(String webApkPackageName, WebappIcon badgeIcon, WebappIcon splashIcon, boolean isSplashIconMaskable, int shellApkVersion, String manifestUrl, String manifestStartUrl, @WebApkDistributor int distributor, Map<String, String> iconUrlToMurmur2HashMap, ShareTarget shareTarget, - boolean isSplashProvidedByWebApk, ShareData shareData, List<ShortcutItem> shortcutItems, + boolean isSplashProvidedByWebApk, List<ShortcutItem> shortcutItems, int webApkVersionCode) { this.webApkPackageName = webApkPackageName; this.badgeIcon = badgeIcon; @@ -134,7 +126,6 @@ this.iconUrlToMurmur2HashMap = iconUrlToMurmur2HashMap; this.shareTarget = shareTarget; this.isSplashProvidedByWebApk = isSplashProvidedByWebApk; - this.shareData = shareData; this.shortcutItems = shortcutItems; this.webApkVersionCode = webApkVersionCode; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java index 68281fd..cea06b7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java
@@ -5,17 +5,16 @@ package org.chromium.chrome.browser.webapps; import android.content.Intent; -import android.net.Uri; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.browser.trusted.sharing.ShareData; import org.chromium.chrome.browser.ShortcutHelper; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.webapps.WebApkExtras.ShortcutItem; import org.chromium.webapk.lib.common.WebApkConstants; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -24,14 +23,6 @@ * Stores info for WebAPK. */ public class WebApkInfo extends WebappInfo { - /** A class that stores share information from share intent. */ - public static class ShareData { - public String subject; - public String text; - public ArrayList<Uri> files; - public String shareActivityClassName; - } - /** * Stores information about the WebAPK's share intent handlers. * TODO(crbug.com/912954): add share target V2 parameters once the server supports them. @@ -265,7 +256,7 @@ } public ShareData shareData() { - return getWebApkExtras().shareData; + return mProvider.getShareData(); } public List<ShortcutItem> shortcutItems() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIntentDataProviderFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIntentDataProviderFactory.java index 9324a8d..0c77faa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIntentDataProviderFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkIntentDataProviderFactory.java
@@ -18,6 +18,8 @@ import android.text.TextUtils; import android.util.Pair; +import androidx.browser.trusted.sharing.ShareData; + import org.xmlpull.v1.XmlPullParser; import org.chromium.base.ApiCompatibilityUtils; @@ -30,7 +32,6 @@ import org.chromium.chrome.browser.ShortcutSource; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.webapps.WebApkExtras.ShortcutItem; -import org.chromium.chrome.browser.webapps.WebApkInfo.ShareData; import org.chromium.chrome.browser.webapps.WebApkInfo.ShareTarget; import org.chromium.content_public.common.ScreenOrientationValues; import org.chromium.webapk.lib.common.WebApkCommonUtils; @@ -93,17 +94,17 @@ // Presence of {@link shareDataActivityClassName} indicates that this is a share. if (!TextUtils.isEmpty(shareDataActivityClassName)) { - shareData = new ShareData(); - shareData.subject = IntentUtils.safeGetStringExtra(intent, Intent.EXTRA_SUBJECT); - shareData.text = IntentUtils.safeGetStringExtra(intent, Intent.EXTRA_TEXT); - shareData.files = IntentUtils.getParcelableArrayListExtra(intent, Intent.EXTRA_STREAM); - if (shareData.files == null) { + String subject = IntentUtils.safeGetStringExtra(intent, Intent.EXTRA_SUBJECT); + String text = IntentUtils.safeGetStringExtra(intent, Intent.EXTRA_TEXT); + List<Uri> files = IntentUtils.getParcelableArrayListExtra(intent, Intent.EXTRA_STREAM); + if (files == null) { Uri file = IntentUtils.safeGetParcelableExtra(intent, Intent.EXTRA_STREAM); if (file != null) { - shareData.files = new ArrayList<>(); - shareData.files.add(file); + files = new ArrayList<>(); + files.add(file); } } + shareData = new ShareData(subject, text, files); } String url = IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_URL); @@ -415,14 +416,14 @@ false /* isIconGenerated */, isPrimaryIconMaskable, forceNavigation); WebApkExtras webApkExtras = new WebApkExtras(webApkPackageName, badgeIcon, splashIcon, isSplashIconMaskable, shellApkVersion, manifestUrl, manifestStartUrl, distributor, - iconUrlToMurmur2HashMap, shareTarget, isSplashProvidedByWebApk, shareData, - shortcutItems, webApkVersionCode); + iconUrlToMurmur2HashMap, shareTarget, isSplashProvidedByWebApk, shortcutItems, + webApkVersionCode); boolean hasCustomToolbarColor = WebappIntentUtils.isLongColorValid(themeColor); int toolbarColor = hasCustomToolbarColor ? (int) themeColor : WebappIntentDataProvider.getDefaultToolbarColor(); return new WebappIntentDataProvider( - toolbarColor, hasCustomToolbarColor, webappExtras, webApkExtras); + toolbarColor, hasCustomToolbarColor, shareData, webappExtras, webApkExtras); } private static int computeSource(Intent intent, ShareData shareData) { @@ -438,7 +439,7 @@ } if (source == ShortcutSource.WEBAPK_SHARE_TARGET && shareData != null - && shareData.files != null && shareData.files.size() > 0) { + && shareData.uris != null && shareData.uris.size() > 0) { return ShortcutSource.WEBAPK_SHARE_TARGET_FILE; } return source;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkPostShareTargetNavigator.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkPostShareTargetNavigator.java index b8704c2..75841c7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkPostShareTargetNavigator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkPostShareTargetNavigator.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.webapps; +import androidx.browser.trusted.sharing.ShareData; + import org.chromium.base.annotations.NativeMethods; import org.chromium.content_public.browser.WebContents; @@ -12,9 +14,7 @@ */ public class WebApkPostShareTargetNavigator { public boolean navigateIfPostShareTarget( - String url, - WebApkInfo.ShareTarget target, - WebApkInfo.ShareData data, WebContents webContents) { + String url, WebApkInfo.ShareTarget target, ShareData data, WebContents webContents) { WebApkShareTargetUtil.PostData postData = WebApkShareTargetUtil.computePostData(target, data); if (postData == null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtil.java index 103554df..83b71e51 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtil.java
@@ -9,6 +9,8 @@ import android.provider.OpenableColumns; import android.text.TextUtils; +import androidx.browser.trusted.sharing.ShareData; + import org.json.JSONArray; import org.json.JSONException; @@ -18,6 +20,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.List; /** * Computes data for Post Share Target. @@ -142,7 +145,7 @@ protected static void addFilesToMultipartPostData(PostData postData, String fallbackNameForPlainTextFile, String[] shareTargetParamsFileNames, - String[][] shareTargetParamsFileAccepts, ArrayList<Uri> shareFiles) { + String[][] shareTargetParamsFileAccepts, List<Uri> shareFiles) { if (shareFiles == null) { return; } @@ -195,7 +198,7 @@ } protected static PostData computePostData( - WebApkInfo.ShareTarget shareTarget, WebApkInfo.ShareData shareData) { + WebApkInfo.ShareTarget shareTarget, ShareData shareData) { if (shareTarget == null || !shareTarget.isShareMethodPost() || shareData == null) { return null; } @@ -203,8 +206,8 @@ PostData postData = new PostData(shareTarget.isShareEncTypeMultipart()); if (!TextUtils.isEmpty(shareTarget.getParamTitle()) - && !TextUtils.isEmpty(shareData.subject)) { - postData.addPlainText(shareTarget.getParamTitle(), shareData.subject); + && !TextUtils.isEmpty(shareData.title)) { + postData.addPlainText(shareTarget.getParamTitle(), shareData.title); } if (!TextUtils.isEmpty(shareTarget.getParamText()) && !TextUtils.isEmpty(shareData.text)) { @@ -230,7 +233,7 @@ // web page expects a single value (not an array) in the "param text" field. addFilesToMultipartPostData(postData, enableAddingFileAsFakePlainText ? shareTarget.getParamText() : null, - shareTarget.getFileNames(), shareTarget.getFileAccepts(), shareData.files); + shareTarget.getFileNames(), shareTarget.getFileAccepts(), shareData.uris); return postData; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java index e96728f..e8a928a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java
@@ -32,7 +32,6 @@ import org.chromium.chrome.browser.notifications.PendingIntentProvider; import org.chromium.chrome.browser.notifications.channels.ChannelDefinitions; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.ui.base.Clipboard; import java.lang.ref.WeakReference; @@ -177,7 +176,7 @@ } else if (ACTION_FOCUS.equals(intent.getAction())) { Tab tab = webappActivity.getActivityTab(); if (tab != null) { - Clipboard.getInstance().copyUrlToClipboard(((TabImpl) tab).getOriginalUrl()); + Clipboard.getInstance().copyUrlToClipboard(tab.getOriginalUrl()); } RecordUserAction.record("Webapp.NotificationFocused"); return true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java index f9b7067e..edf8af5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -47,7 +47,6 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabBrowserControlsConstraintsHelper; import org.chromium.chrome.browser.tab.TabDelegateFactory; -import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.ui.appmenu.AppMenuPropertiesDelegate; import org.chromium.chrome.browser.usage_stats.UsageStatsService; import org.chromium.chrome.browser.util.AndroidTaskUtils; @@ -520,7 +519,7 @@ Tab tab = getActivityTab(); if (tab == null) return false; - String url = ((TabImpl) tab).getOriginalUrl(); + String url = tab.getOriginalUrl(); if (TextUtils.isEmpty(url)) { url = IntentHandler.getUrlFromIntent(getIntent()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivityTabController.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivityTabController.java index 6194f7c..6f64528 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivityTabController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivityTabController.java
@@ -21,6 +21,7 @@ import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar; import org.chromium.chrome.browser.dependency_injection.ActivityScope; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl; @@ -124,7 +125,7 @@ assert tab != null; if (mode != TabCreationMode.RESTORED) { - tabModel.addTab(tab, 0, tab.getLaunchType()); + tabModel.addTab(tab, 0, tab.getLaunchType(), TabCreationState.LIVE_IN_FOREGROUND); } mTabProvider.setInitialTab(tab, mode);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java index 69576af..ffdd83d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java
@@ -20,7 +20,7 @@ protected static BrowserServicesIntentDataProvider createEmptyIntentDataProvider() { return new WebappIntentDataProvider(WebappIntentDataProvider.getDefaultToolbarColor(), - false /* hasCustomToolbarColor */, WebappExtras.createEmpty(), + false /* hasCustomToolbarColor */, null /* shareData */, WebappExtras.createEmpty(), WebApkExtras.createEmpty()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java index d37f2df..67f7819 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java
@@ -9,6 +9,7 @@ import androidx.annotation.Nullable; import androidx.browser.customtabs.CustomTabsIntent; +import androidx.browser.trusted.sharing.ShareData; import org.chromium.base.ContextUtils; import org.chromium.chrome.R; @@ -22,6 +23,7 @@ private int mToolbarColor; private boolean mHasCustomToolbarColor; private Drawable mCloseButtonIcon; + private ShareData mShareData; private WebappExtras mWebappExtras; private WebApkExtras mWebApkExtras; @@ -32,12 +34,13 @@ return Color.WHITE; } - WebappIntentDataProvider(int toolbarColor, boolean hasCustomToolbarColor, + WebappIntentDataProvider(int toolbarColor, boolean hasCustomToolbarColor, ShareData shareData, WebappExtras webappExtras, WebApkExtras webApkExtras) { mToolbarColor = toolbarColor; mHasCustomToolbarColor = hasCustomToolbarColor; mCloseButtonIcon = TintedDrawable.constructTintedDrawable( ContextUtils.getApplicationContext(), R.drawable.btn_close); + mShareData = shareData; mWebappExtras = webappExtras; mWebApkExtras = webApkExtras; } @@ -74,6 +77,12 @@ @Override @Nullable + public ShareData getShareData() { + return mShareData; + } + + @Override + @Nullable public WebappExtras getWebappExtras() { return mWebappExtras; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProviderFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProviderFactory.java index 1676b9f..e71bc65 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProviderFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProviderFactory.java
@@ -99,7 +99,7 @@ WebappExtras webappExtras = new WebappExtras(id, url, scope, new WebappIcon(icon), name, shortName, displayMode, orientation, source, backgroundColor, defaultBackgroundColor, isIconGenerated, isIconAdaptive, forceNavigation); - return new WebappIntentDataProvider( - toolbarColor, hasValidToolbarColor, webappExtras, null /* webApkExtras */); + return new WebappIntentDataProvider(toolbarColor, hasValidToolbarColor, + null /* shareData */, webappExtras, null /* webApkExtras */); } }
diff --git a/chrome/android/javatests/AndroidManifest.xml b/chrome/android/javatests/AndroidManifest.xml index b2ea070..640e9be 100644 --- a/chrome/android/javatests/AndroidManifest.xml +++ b/chrome/android/javatests/AndroidManifest.xml
@@ -58,6 +58,14 @@ android:exported="true"/> {% endblock %} +{% block extra_application_attributes %} +{{ super() }} +## Test listing breaks because of scoped storage in Android 10 - see +## https://developer.android.com/training/data-storage#scoped-storage and +## https://developer.android.com/training/data-storage/compatibility. +android:requestLegacyExternalStorage="true" +{% endblock %} + {% block extra_root_definitions %} <instrumentation android:name="org.chromium.base.test.BaseChromiumAndroidJUnitRunner" android:targetPackage="{{manifest_package}}"
diff --git a/chrome/android/javatests/AndroidManifest_monochrome.xml b/chrome/android/javatests/AndroidManifest_monochrome.xml index 6e75e790..a457138 100644 --- a/chrome/android/javatests/AndroidManifest_monochrome.xml +++ b/chrome/android/javatests/AndroidManifest_monochrome.xml
@@ -20,6 +20,9 @@ {% block extra_application_attributes %} {{ super() }} +## Test listing breaks because of scoped storage in Android 10 - see +## https://developer.android.com/training/data-storage#scoped-storage and +## https://developer.android.com/training/data-storage/compatibility. android:requestLegacyExternalStorage="true" {% endblock %}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java index 256b6e2..97e24df9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
@@ -40,6 +40,7 @@ import org.chromium.chrome.browser.share.LensUtils; import org.chromium.chrome.browser.share.ShareHelper; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -215,8 +216,8 @@ mDownloadTestRule.getActivity().getTabModelSelector().addObserver( new EmptyTabModelSelectorObserver() { @Override - public void onNewTabCreated(Tab tab) { - super.onNewTabCreated(tab); + public void onNewTabCreated(Tab tab, @TabCreationState int creationState) { + super.onNewTabCreated(tab, creationState); if (tab.getParentId() != activityTab.getId()) return; newTab.set(tab);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java index 181b8f9..855a794 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java
@@ -29,6 +29,7 @@ import org.chromium.chrome.browser.firstrun.FirstRunStatus; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -117,8 +118,8 @@ mDownloadTestRule.getActivity().getTabModelSelector().addObserver( new EmptyTabModelSelectorObserver() { @Override - public void onNewTabCreated(Tab tab) { - super.onNewTabCreated(tab); + public void onNewTabCreated(Tab tab, @TabCreationState int creationState) { + super.onNewTabCreated(tab, creationState); if (tab.getParentId() != activityTab.getId()) return; newTab.set(tab);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index 4d75fd5..a271e2b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -75,6 +75,7 @@ import org.chromium.chrome.browser.omnibox.UrlBar; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModelUtils; @@ -1656,7 +1657,7 @@ int tabCreatedHelperCallCount = tabCreatedHelper.getCallCount(); TabModelSelectorObserver observer = new EmptyTabModelSelectorObserver() { @Override - public void onNewTabCreated(Tab tab) { + public void onNewTabCreated(Tab tab, @TabCreationState int creationState) { tabCreatedHelper.notifyCalled(); } };
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 663d3c4..d6b0374 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
@@ -102,6 +102,7 @@ import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabHidingType; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabObserver; @@ -1203,7 +1204,8 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { tabSelector.getModel(false).addObserver(new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { openTabHelper.notifyCalled(); } });
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabDeferredStartupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabDeferredStartupTest.java index cc614f7..b077bfb 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabDeferredStartupTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabDeferredStartupTest.java
@@ -34,6 +34,7 @@ import org.chromium.chrome.browser.lifecycle.InflationObserver; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelectorBase; @@ -89,7 +90,7 @@ } @Override - public void onNewTabCreated(Tab tab) { + public void onNewTabCreated(Tab tab, @TabCreationState int creationState) { tab.addObserver(mObserver); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java index 35ded7ea..28e688e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java
@@ -35,6 +35,7 @@ import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.InterceptNavigationDelegateImpl; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -173,7 +174,8 @@ mActivityTestRule.getActivity().getTabModelSelector().addObserver( new EmptyTabModelSelectorObserver() { @Override - public void onNewTabCreated(Tab newTab) { + public void onNewTabCreated( + Tab newTab, @TabCreationState int creationState) { newTabCallback.notifyCalled(); newTab.addObserver(new TestTabObserver( finishCallback, failCallback, destroyedCallback));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/subresource_filter/SubresourceFilterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/subresource_filter/SubresourceFilterTest.java index d25ea85..76f86056 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/subresource_filter/SubresourceFilterTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/subresource_filter/SubresourceFilterTest.java
@@ -24,6 +24,7 @@ import org.chromium.chrome.browser.infobar.InfoBar; import org.chromium.chrome.browser.infobar.InfoBarContainer; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -151,7 +152,8 @@ TestThreadUtils.runOnUiThreadBlocking( () -> tabModel.addObserver(new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { if (tab.getUrlString().equals(LEARN_MORE_PAGE)) { tabCreatedCallback.notifyCalled(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserverTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserverTest.java index e4850136..4695257 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserverTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserverTest.java
@@ -18,6 +18,7 @@ import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.chrome.browser.tab.MockTab; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tab.TabTestUtils; @@ -140,7 +141,10 @@ } private static void addTab(TabModel tabModel, Tab tab) { - ThreadUtils.runOnUiThreadBlocking(() -> tabModel.addTab(tab, 0, TabLaunchType.FROM_LINK)); + ThreadUtils.runOnUiThreadBlocking( + () + -> tabModel.addTab(tab, 0, TabLaunchType.FROM_LINK, + TabCreationState.LIVE_IN_FOREGROUND)); } private static void closeTab(TabModel tabModel, Tab tab) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java index 5583bc2..91987c8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java
@@ -36,6 +36,7 @@ import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.tab.MockTab; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tab.TabState; @@ -106,7 +107,9 @@ @Override public Tab createNewTab(LoadUrlParams loadUrlParams, @TabLaunchType int type, Tab parent) { Tab tab = new MockTab(0, mIsIncognito, TabLaunchType.FROM_LINK); - mSelector.getModel(mIsIncognito).addTab(tab, TabModel.INVALID_TAB_INDEX, type); + mSelector.getModel(mIsIncognito) + .addTab(tab, TabModel.INVALID_TAB_INDEX, type, + TabCreationState.LIVE_IN_FOREGROUND); storeTabInfo(null, tab.getId()); return tab; } @@ -115,7 +118,9 @@ public Tab createFrozenTab(TabState state, int id, int index) { Tab tab = new MockTab(id, state.isIncognito(), TabLaunchType.FROM_RESTORE); TabTestUtils.restoreFieldsFromState(tab, state); - mSelector.getModel(mIsIncognito).addTab(tab, index, TabLaunchType.FROM_RESTORE); + mSelector.getModel(mIsIncognito) + .addTab(tab, index, TabLaunchType.FROM_RESTORE, + TabCreationState.FROZEN_ON_RESTORE); storeTabInfo(state, id); return tab; }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerTest.java index b91752d..d9591fc 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerTest.java
@@ -105,13 +105,13 @@ public void addsEarlyCreatedTab_ToTabModel() { env.warmUp(); env.reachNativeInit(mTabController); - verify(env.tabModel).addTab(eq(env.tabFromFactory), anyInt(), anyInt()); + verify(env.tabModel).addTab(eq(env.tabFromFactory), anyInt(), anyInt(), anyInt()); } @Test public void addsTabCreatedOnNativeInit_ToTabModel() { env.reachNativeInit(mTabController); - verify(env.tabModel).addTab(eq(env.tabFromFactory), anyInt(), anyInt()); + verify(env.tabModel).addTab(eq(env.tabFromFactory), anyInt(), anyInt(), anyInt()); } @Test
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/NightModeReparentingControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/NightModeReparentingControllerTest.java index 27e5aba..7d9e5f0 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/NightModeReparentingControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/NightModeReparentingControllerTest.java
@@ -25,6 +25,7 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab_activity_glue.ReparentingTask; import org.chromium.chrome.browser.tabmodel.AsyncTabParams; @@ -292,10 +293,12 @@ int index; if (incognito) { - mIncognitoTabModel.addTab(tab, -1, TabLaunchType.FROM_BROWSER_ACTIONS); + mIncognitoTabModel.addTab(tab, -1, TabLaunchType.FROM_BROWSER_ACTIONS, + TabCreationState.LIVE_IN_FOREGROUND); index = mIncognitoTabModel.indexOf(tab); } else { - mTabModel.addTab(tab, -1, TabLaunchType.FROM_BROWSER_ACTIONS); + mTabModel.addTab(tab, -1, TabLaunchType.FROM_BROWSER_ACTIONS, + TabCreationState.LIVE_IN_FOREGROUND); index = mTabModel.indexOf(tab); } mTabIndexMapping.put(tab, index);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java index 6f68bcad..a7bd585 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java
@@ -33,6 +33,7 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabHidingType; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; @@ -482,7 +483,7 @@ } private void didAddTab(TabImpl tab, @TabLaunchType int launchType) { - getTabModelObserver().didAddTab(tab, launchType); + getTabModelObserver().didAddTab(tab, launchType, TabCreationState.LIVE_IN_FOREGROUND); } private TabObserver getTabObserver() {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInfoTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInfoTest.java index 32217a84e..c1682764 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInfoTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInfoTest.java
@@ -13,6 +13,8 @@ import android.os.Bundle; import android.provider.Browser; +import androidx.browser.trusted.sharing.ShareData; + import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; @@ -578,7 +580,7 @@ } /** - * Tests building {@link WebApkInfo.ShareData} when {@link Intent.EXTRA_STREAM} has a Uri value. + * Tests building {@link ShareData} when {@link Intent.EXTRA_STREAM} has a Uri value. */ @Test public void testShareDataUriString() { @@ -598,14 +600,14 @@ intent.putExtra(Intent.EXTRA_STREAM, sharedFileUri); WebApkInfo info = WebApkInfo.create(intent); - WebApkInfo.ShareData shareData = info.shareData(); + ShareData shareData = info.shareData(); Assert.assertNotNull(shareData); - Assert.assertNotNull(shareData.files); - Assert.assertThat(shareData.files, Matchers.contains(sharedFileUri)); + Assert.assertNotNull(shareData.uris); + Assert.assertThat(shareData.uris, Matchers.contains(sharedFileUri)); } /** - * Tests building {@link WebApkInfo.ShareData} when {@link Intent.EXTRA_STREAM} has an ArrayList + * Tests building {@link ShareData} when {@link Intent.EXTRA_STREAM} has an ArrayList * value. */ @Test @@ -628,10 +630,10 @@ intent.putExtra(Intent.EXTRA_STREAM, uris); WebApkInfo info = WebApkInfo.create(intent); - WebApkInfo.ShareData shareData = info.shareData(); + ShareData shareData = info.shareData(); Assert.assertNotNull(shareData); - Assert.assertNotNull(shareData.files); - Assert.assertThat(shareData.files, Matchers.contains(sharedFileUri)); + Assert.assertNotNull(shareData.uris); + Assert.assertThat(shareData.uris, Matchers.contains(sharedFileUri)); } /**
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtilTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtilTest.java index 849d8fb..90f02c1 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtilTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkShareTargetUtilTest.java
@@ -508,13 +508,6 @@ private WebApkShareTargetUtil.PostData computePostData( WebApkInfo.ShareTarget shareTarget, ShareData shareData) { - WebApkInfo.ShareData webApkShareData = new WebApkInfo.ShareData(); - webApkShareData.subject = shareData.title; - webApkShareData.text = shareData.text; - if (shareData.uris != null) { - webApkShareData.files = new ArrayList(shareData.uris); - } - - return WebApkShareTargetUtil.computePostData(shareTarget, webApkShareData); + return WebApkShareTargetUtil.computePostData(shareTarget, shareData); } }
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 1667e7ef..5c1ea8796 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -143,6 +143,42 @@ <message name="IDS_OS_SETTINGS_FILES" desc="Name of the settings page which displays file preferences."> Files </message> + <message name="IDS_SETTINGS_DISCONNECT_GOOGLE_DRIVE" desc="Label for the checkbox which enables disconnecting from Google Drive account."> + Disconnect Google Drive account + </message> + <message name="IDS_SETTINGS_DOWNLOADS_SMB_SHARES" desc="In Downloads Settings, the title of the SMB shares setting section."> + Network file shares + </message> + <message name="IDS_SETTINGS_DOWNLOADS_SMB_SHARES_LEARN_MORE_LABEL" desc="Label for the link that teaches users how to setup SMB shares."> + Set up or manage network file shares. <ph name="LINK_BEGIN"><a></ph>Learn more<ph name="LINK_END"></a></ph> + </message> + <message name="IDS_SETTINGS_DOWNLOADS_SMB_SHARES_ADD_SHARE" desc="In SMB shares settings subpage, text for the link to add a new SMB share."> + Add file share + </message> + <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_ERROR_MESSAGE" desc="The message shown when mounting a new SMB share fails."> + Error mounting share. Check the file share URL and try again. + </message> + <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_AUTH_FAILED_MESSAGE" desc="The message shown when mounting a new SMB share fails due to an authentication failure."> + Error mounting share. Please check your credentials and try again. + </message> + <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_NOT_FOUND_MESSAGE" desc="The message shown when mounting a new SMB share fails because the share cannot be found."> + Error mounting share. The specified share was not found on the network. + </message> + <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_UNSUPPORTED_DEVICE_MESSAGE" desc="The message shown when mounting a new SMB share fails because the specified device is not supported."> + Error mounting share. Please check that the file server you are connecting to supports SMBv2 or later. + </message> + <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_EXISTS_MESSAGE" desc="The message shown when mounting a new SMB share fails because the share is already mounted."> + Error mounting share. The specified share is already mounted. + </message> + <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_URL_MESSAGE" desc="The message shown when mounting a new SMB share fails because the URL is an invalid format."> + Invalid URL format. Supported formats are \\server\share and smb://server/share. + </message> + <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_SSO_URL_MESSAGE" desc="The message shown when mounting a new SMB share fails because the URL is an invalid format when SSO authentication is used."> + Invalid URL format. Server must be specified as a host name when SSO authentication is used. + </message> + <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_SUCCESS_MESSAGE" desc="The message shown when a new SMB share is successfully mounted."> + Share mounted successfully. + </message> <!-- Accessibility --> <message name="IDS_SETTINGS_A11Y_TABLET_MODE_SHELF_BUTTONS_LABEL" desc="The name of a setting within accessibility settings that controls whether Chrome OS system shelf navigation buttons (for going back, home, or to overview) should be shown when the device is in tablet mode."> @@ -1721,5 +1757,58 @@ <message name="IDS_SETTINGS_KERBEROS_ACCOUNTS_PAGE_TITLE" desc="Title of 'Kerberos tickets' Settings page."> Kerberos tickets </message> + + <!-- Power --> + <message name="IDS_SETTINGS_POWER_TITLE" desc="In Device Settings, the title for power management."> + Power + </message> + <message name="IDS_SETTINGS_POWER_SOURCE_LABEL" desc="In Device Settings > Power, the label for the power source dropdown."> + Power source + </message> + <message name="IDS_SETTINGS_POWER_SOURCE_BATTERY" desc="In Device Settings > Power, the text referring to the battery as the power source."> + Battery + </message> + <message name="IDS_SETTINGS_POWER_SOURCE_AC_ADAPTER" desc="In Device Settings > Power, the text referring to a dedicated charger like an AC adapter as the power source."> + AC adapter + </message> + <message name="IDS_SETTINGS_POWER_SOURCE_LOW_POWER_CHARGER" desc="In Device Settings > Power, the text referring to a low-power charger like a USB charger as the power source."> + Low-power charger + </message> + <message name="IDS_SETTINGS_POWER_SOURCE_CALCULATING" desc="In Device Settings > Power, the power source description when the power status is being determined."> + Checking power sources... + </message> + <message name="IDS_SETTINGS_POWER_IDLE_LABEL" desc="In Device Settings > Power, label for behavior when device is idle."> + When idle + </message> + <message name="IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF_SLEEP" desc="In Device Settings > Power, menu item for idle behavior that turns the screen off and later puts the device to sleep. String must be short enough to fit in a drop-down menu."> + Sleep + </message> + <message name="IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF" desc="In Device Settings > Power, menu item for idle behavior that turns the screen off but prevents the device from sleeping. String must be short enough to fit in a drop-down menu."> + Turn off display + </message> + <message name="IDS_SETTINGS_POWER_IDLE_DISPLAY_ON" desc="In Device Settings > Power, menu item for idle behavior that prevents the screen from turning off and prevents the device from sleeping. String must be short enough to fit in a drop-down menu."> + Keep display on + </message> + <message name="IDS_SETTINGS_POWER_IDLE_OTHER" desc="In Device Settings > Power, menu item for custom idle behavior."> + Other + </message> + <message name="IDS_SETTINGS_POWER_LID_CLOSED_SLEEP_LABEL" desc="In Device Settings > Power, label for suspending when cover is closed."> + Sleep when cover is closed + </message> + <message name="IDS_SETTINGS_POWER_LID_CLOSED_SIGN_OUT_LABEL" desc="In Device Settings > Power, label for signing out when cover is closed."> + Sign out when cover is closed + </message> + <message name="IDS_SETTINGS_POWER_LID_CLOSED_SHUT_DOWN_LABEL" desc="In Device Settings > Power, label for shutting down when cover is closed."> + Shut down when cover is closed + </message> + <message name="IDS_SETTINGS_BATTERY_STATUS" desc="In Device Settings > Power, the battery status while the battery is discharging, showing the battery power as a percentage and the time left until the battery is empty."> + <ph name="percentage">$1<ex>56</ex></ph>% - <ph name="time">$2<ex>2 hours and 20 minutes</ex></ph> left + </message> + <message name="IDS_SETTINGS_BATTERY_STATUS_CHARGING" desc="In Device Settings > Power, the battery status while the battery is charging, showing the battery power as a percentage and the time left until the battery is full."> + <ph name="percentage">$1<ex>56</ex></ph>% - <ph name="time">$2<ex>2 hours and 20 minutes</ex></ph> until full + </message> + <message name="IDS_SETTINGS_BATTERY_STATUS_SHORT" desc="In Device Settings > Power, the battery status when the time left cannot be shown."> + <ph name="percentage">$1<ex>56</ex></ph>% + </message> </if> </grit-part> \ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 3d87cf0..74ab580 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -887,24 +887,12 @@ <message name="IDS_SETTINGS_PROMPT_FOR_DOWNLOAD" desc="Label for the checkbox which enables a prompt for the user to choose a download location for each download instead of using the default."> Ask where to save each file before downloading </message> - <message name="IDS_SETTINGS_DISCONNECT_GOOGLE_DRIVE" desc="Label for the checkbox which enables disconnecting from Google Drive account."> - Disconnect Google Drive account - </message> <message name="IDS_SETTINGS_OPEN_FILE_TYPES_AUTOMATICALLY" desc="The information label for the 'Clear auto-opening settings' button"> Open certain file types automatically after downloading </message> <!-- SMB File Shares --> <if expr="chromeos"> - <message name="IDS_SETTINGS_DOWNLOADS_SMB_SHARES" desc="In Downloads Settings, the title of the SMB shares setting section."> - Network file shares - </message> - <message name="IDS_SETTINGS_DOWNLOADS_SMB_SHARES_LEARN_MORE_LABEL" desc="Label for the link that teaches users how to setup SMB shares."> - Set up or manage network file shares. <ph name="LINK_BEGIN"><a></ph>Learn more<ph name="LINK_END"></a></ph> - </message> - <message name="IDS_SETTINGS_DOWNLOADS_SMB_SHARES_ADD_SHARE" desc="In SMB shares settings subpage, text for the link to add a new SMB share."> - Add file share - </message> <message name="IDS_SETTINGS_DOWNLOADS_ADD_SHARE_URL" desc="Title for the input that lets users specify the name of an SMB URL."> File share URL </message> @@ -920,30 +908,6 @@ <message name="IDS_SETTINGS_DOWNLOADS_ADD_SHARE_SAVE_CREDENTIALS" desc="Label for the checkbox input that lets users have the username/password for an SMB share saved for the next login."> Remember sign-in info </message> - <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_SUCCESS_MESSAGE" desc="The message shown when a new SMB share is successfully mounted."> - Share mounted successfully. - </message> - <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_ERROR_MESSAGE" desc="The message shown when mounting a new SMB share fails."> - Error mounting share. Check the file share URL and try again. - </message> - <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_AUTH_FAILED_MESSAGE" desc="The message shown when mounting a new SMB share fails due to an authentication failure."> - Error mounting share. Please check your credentials and try again. - </message> - <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_NOT_FOUND_MESSAGE" desc="The message shown when mounting a new SMB share fails because the share cannot be found."> - Error mounting share. The specified share was not found on the network. - </message> - <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_UNSUPPORTED_DEVICE_MESSAGE" desc="The message shown when mounting a new SMB share fails because the specified device is not supported."> - Error mounting share. Please check that the file server you are connecting to supports SMBv2 or later. - </message> - <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_EXISTS_MESSAGE" desc="The message shown when mounting a new SMB share fails because the share is already mounted."> - Error mounting share. The specified share is already mounted. - </message> - <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_URL_MESSAGE" desc="The message shown when mounting a new SMB share fails because the URL is an invalid format."> - Invalid URL format. Supported formats are \\server\share and smb://server/share. - </message> - <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_SSO_URL_MESSAGE" desc="The message shown when mounting a new SMB share fails because the URL is an invalid format when SSO authentication is used."> - Invalid URL format. Server must be specified as a host name when SSO authentication is used. - </message> <message name="IDS_SETTINGS_DOWNLOADS_ADD_SHARE_AUTHENTICATION_METHOD" desc="Title for the input that lets users specify their authentication method for an SMB Share."> Authentication method </message> @@ -3546,59 +3510,6 @@ <message name="IDS_SETTINGS_STORAGE_OVERVIEW_ARIA_LABEL" desc="The label to be read aloud by ChromeVox to describe the storage usage progress bar on the Storage page"> Storage Usage Overview </message> - - <!-- Power --> - <message name="IDS_SETTINGS_POWER_TITLE" desc="In Device Settings, the title for power management."> - Power - </message> - <message name="IDS_SETTINGS_POWER_SOURCE_LABEL" desc="In Device Settings > Power, the label for the power source dropdown."> - Power source - </message> - <message name="IDS_SETTINGS_POWER_SOURCE_BATTERY" desc="In Device Settings > Power, the text referring to the battery as the power source."> - Battery - </message> - <message name="IDS_SETTINGS_POWER_SOURCE_AC_ADAPTER" desc="In Device Settings > Power, the text referring to a dedicated charger like an AC adapter as the power source."> - AC adapter - </message> - <message name="IDS_SETTINGS_POWER_SOURCE_LOW_POWER_CHARGER" desc="In Device Settings > Power, the text referring to a low-power charger like a USB charger as the power source."> - Low-power charger - </message> - <message name="IDS_SETTINGS_POWER_SOURCE_CALCULATING" desc="In Device Settings > Power, the power source description when the power status is being determined."> - Checking power sources... - </message> - <message name="IDS_SETTINGS_POWER_IDLE_LABEL" desc="In Device Settings > Power, label for behavior when device is idle."> - When idle - </message> - <message name="IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF_SLEEP" desc="In Device Settings > Power, menu item for idle behavior that turns the screen off and later puts the device to sleep. String must be short enough to fit in a drop-down menu."> - Sleep - </message> - <message name="IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF" desc="In Device Settings > Power, menu item for idle behavior that turns the screen off but prevents the device from sleeping. String must be short enough to fit in a drop-down menu."> - Turn off display - </message> - <message name="IDS_SETTINGS_POWER_IDLE_DISPLAY_ON" desc="In Device Settings > Power, menu item for idle behavior that prevents the screen from turning off and prevents the device from sleeping. String must be short enough to fit in a drop-down menu."> - Keep display on - </message> - <message name="IDS_SETTINGS_POWER_IDLE_OTHER" desc="In Device Settings > Power, menu item for custom idle behavior."> - Other - </message> - <message name="IDS_SETTINGS_POWER_LID_CLOSED_SLEEP_LABEL" desc="In Device Settings > Power, label for suspending when cover is closed."> - Sleep when cover is closed - </message> - <message name="IDS_SETTINGS_POWER_LID_CLOSED_SIGN_OUT_LABEL" desc="In Device Settings > Power, label for signing out when cover is closed."> - Sign out when cover is closed - </message> - <message name="IDS_SETTINGS_POWER_LID_CLOSED_SHUT_DOWN_LABEL" desc="In Device Settings > Power, label for shutting down when cover is closed."> - Shut down when cover is closed - </message> - <message name="IDS_SETTINGS_BATTERY_STATUS" desc="In Device Settings > Power, the battery status while the battery is discharging, showing the battery power as a percentage and the time left until the battery is empty."> - <ph name="percentage">$1<ex>56</ex></ph>% - <ph name="time">$2<ex>2 hours and 20 minutes</ex></ph> left - </message> - <message name="IDS_SETTINGS_BATTERY_STATUS_CHARGING" desc="In Device Settings > Power, the battery status while the battery is charging, showing the battery power as a percentage and the time left until the battery is full."> - <ph name="percentage">$1<ex>56</ex></ph>% - <ph name="time">$2<ex>2 hours and 20 minutes</ex></ph> until full - </message> - <message name="IDS_SETTINGS_BATTERY_STATUS_SHORT" desc="In Device Settings > Power, the battery status when the time left cannot be shown."> - <ph name="percentage">$1<ex>56</ex></ph>% - </message> </if> <!-- System Page --> @@ -3620,14 +3531,6 @@ </message> </if> - <!-- Password protection --> - <message name="IDS_SETTINGS_CHANGE_PASSWORD_TITLE" desc="Title of the reset password warning."> - Your password may be compromised - </message> - <message name="IDS_SETTINGS_CHANGE_PASSWORD_BUTTON" desc="Label on button that takes user to change password page."> - Change Password - </message> - <!-- Chrome Cleanup Page --> <if expr="is_win and _google_chrome"> <message name="IDS_SETTINGS_RESET_CLEAN_UP_COMPUTER_PAGE_TITLE" desc="Title for an item in the 'Reset and clean up' section of Chrome Settings. 'Clean up' refers to cleaning up harmful software on the user's computer. Imperative.">
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 37b299c14..be21f09 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -558,6 +558,8 @@ "google/google_search_domain_mixing_metrics_emitter.h", "google/google_search_domain_mixing_metrics_emitter_factory.cc", "google/google_search_domain_mixing_metrics_emitter_factory.h", + "gpu/chrome_browser_main_extra_parts_gpu.cc", + "gpu/chrome_browser_main_extra_parts_gpu.h", "gpu/gpu_mode_manager.cc", "gpu/gpu_mode_manager.h", "hang_monitor/hang_crash_dump.h",
diff --git a/chrome/browser/chrome_browser_interface_binders.h b/chrome/browser/chrome_browser_interface_binders.h index 3d742783..16d1685 100644 --- a/chrome/browser/chrome_browser_interface_binders.h +++ b/chrome/browser/chrome_browser_interface_binders.h
@@ -8,6 +8,7 @@ #include "chrome/browser/bad_message.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_controller.h" #include "services/service_manager/public/cpp/binder_map.h"
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index c2fec413..95765dc 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -62,6 +62,7 @@ #include "chrome/browser/extensions/chrome_extension_cookies.h" #include "chrome/browser/external_protocol/external_protocol_handler.h" #include "chrome/browser/font_family_cache.h" +#include "chrome/browser/gpu/chrome_browser_main_extra_parts_gpu.h" #include "chrome/browser/hid/chrome_hid_delegate.h" #include "chrome/browser/interstitials/enterprise_util.h" #include "chrome/browser/lifetime/browser_shutdown.h" @@ -1279,6 +1280,8 @@ main_parts->AddParts(new ChromeBrowserMainExtraPartsMemory); + main_parts->AddParts(new ChromeBrowserMainExtraPartsGpu); + chrome::AddMetricsExtraParts(main_parts.get()); return main_parts;
diff --git a/chrome/browser/chrome_navigation_browsertest.cc b/chrome/browser/chrome_navigation_browsertest.cc index f220f266..59840d5 100644 --- a/chrome/browser/chrome_navigation_browsertest.cc +++ b/chrome/browser/chrome_navigation_browsertest.cc
@@ -43,6 +43,7 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/site_isolation_policy.h" +#include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" @@ -676,6 +677,265 @@ } } +// This test covers a navigation that: +// 1. is initiated by a cross-site initiator, +// 2. gets redirected via webRequest API to about:blank. +// This is a regression test for https://crbug.com/1026738. +IN_PROC_BROWSER_TEST_F( + ChromeNavigationBrowserTest, + NavigationInitiatedByCrossSiteSubframeRedirectedToAboutBlank) { + const GURL kOpenerUrl( + embedded_test_server()->GetURL("opener.com", "/title1.html")); + const GURL kInitialPopupUrl(embedded_test_server()->GetURL( + "initial-site.com", + "/frame_tree/page_with_two_frames_remote_and_local.html")); + const GURL kRedirectedUrl("https://redirected.com/no-such-path"); + + // 1. Install an extension, which will redirect all navigations to + // redirected.com URLs to about:blank. In general, web servers cannot + // redirect to about:blank, but extensions with declarativeWebRequest API + // permissions can. + const char kManifest[] = R"( + { + "name": "Test for Bug1026738 - about:blank flavour", + "version": "0.1", + "manifest_version": 2, + "background": { + "scripts": ["background.js"] + }, + "permissions": [ + "declarativeWebRequest", "<all_urls>" + ] + } + )"; + const char kRulesScript[] = R"( + var condition = new chrome.declarativeWebRequest.RequestMatcher({ + url: { + hostSuffix: 'redirected.com' + } + }); + var action = new chrome.declarativeWebRequest.RedirectRequest({ + redirectUrl: 'about:blank' + }); + var rule = { conditions: [ condition ], actions: [ action ]} + chrome.declarativeWebRequest.onRequest.addRules([rule]); + )"; + extensions::TestExtensionDir ext_dir; + ext_dir.WriteManifest(kManifest); + ext_dir.WriteFile(FILE_PATH_LITERAL("background.js"), kRulesScript); + extensions::ChromeTestExtensionLoader extension_loader(browser()->profile()); + scoped_refptr<const extensions::Extension> extension = + extension_loader.LoadExtension(ext_dir.UnpackedPath()); + ASSERT_TRUE(extension); + content::BrowserContext::GetDefaultStoragePartition(browser()->profile()) + ->FlushNetworkInterfaceForTesting(); + + // 2. Open a popup containing a cross-site subframe. + ui_test_utils::NavigateToURL(browser(), kOpenerUrl); + content::RenderFrameHost* opener = + browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(); + EXPECT_EQ(kOpenerUrl, opener->GetLastCommittedURL()); + EXPECT_EQ(url::Origin::Create(kOpenerUrl), opener->GetLastCommittedOrigin()); + content::WebContents* popup = nullptr; + { + content::WebContentsAddedObserver popup_observer; + ASSERT_TRUE(content::ExecJs( + opener, + content::JsReplace("window.open($1, 'my-popup')", kInitialPopupUrl))); + popup = popup_observer.GetWebContents(); + EXPECT_TRUE(WaitForLoadStop(popup)); + } + + // 3. Find the cross-site subframes in the popup. + content::RenderFrameHost* popup_root = popup->GetMainFrame(); + content::RenderFrameHost* cross_site_subframe = + content::ChildFrameAt(popup_root, 0); + ASSERT_TRUE(cross_site_subframe); + EXPECT_NE(cross_site_subframe->GetLastCommittedOrigin(), + popup_root->GetLastCommittedOrigin()); + EXPECT_NE(cross_site_subframe->GetLastCommittedOrigin(), + opener->GetLastCommittedOrigin()); + if (content::AreAllSitesIsolatedForTesting()) { + EXPECT_NE(cross_site_subframe->GetSiteInstance(), + popup_root->GetSiteInstance()); + EXPECT_NE(cross_site_subframe->GetSiteInstance(), + opener->GetSiteInstance()); + } + scoped_refptr<content::SiteInstance> old_popup_site_instance = + popup_root->GetSiteInstance(); + scoped_refptr<content::SiteInstance> old_subframe_site_instance = + cross_site_subframe->GetSiteInstance(); + + // 4. Initiate popup navigation from the cross-site subframe. + // Note that the extension from step 1 above will redirect + // this navigation to an about:blank URL. + // + // This step would have hit the CHECK from https://crbug.com/1026738. + content::TestNavigationObserver nav_observer(popup, 1); + ASSERT_TRUE(ExecJs(cross_site_subframe, + content::JsReplace("top.location = $1", kRedirectedUrl))); + nav_observer.Wait(); + EXPECT_EQ(url::kAboutBlankURL, popup->GetLastCommittedURL()); + + // 5. Verify that the about:blank URL is hosted in the same process + // as the navigation initiator (and separate from the opener and the old + // popup process). + if (content::AreAllSitesIsolatedForTesting()) { + EXPECT_NE(opener->GetSiteInstance(), popup->GetSiteInstance()); + EXPECT_NE(old_popup_site_instance.get(), popup->GetSiteInstance()); + EXPECT_EQ(old_subframe_site_instance.get(), popup->GetSiteInstance()); + EXPECT_NE(url::kAboutBlankURL, + popup->GetSiteInstance()->GetSiteURL().scheme()); + EXPECT_NE(url::kDataScheme, + popup->GetSiteInstance()->GetSiteURL().scheme()); + } else { + EXPECT_EQ(opener->GetSiteInstance(), popup->GetSiteInstance()); + EXPECT_EQ(old_popup_site_instance.get(), popup->GetSiteInstance()); + EXPECT_EQ(old_subframe_site_instance.get(), popup->GetSiteInstance()); + EXPECT_NE(url::kAboutBlankURL, + popup->GetSiteInstance()->GetSiteURL().scheme()); + EXPECT_NE(url::kDataScheme, + popup->GetSiteInstance()->GetSiteURL().scheme()); + } + + // 6. Verify the origin of the about:blank URL in the popup. + // + // Blink calculates the origin of an about:blank frame based on the + // opener-or-parent (rather than based on the navigation initiator's origin + // as required by the spec). + // TODO(lukasza): https://crbug.com/585649: Once Blink is fixed, adjust test + // expectations below to make sure the initiator's origin has been committed. + // Consider also adding verification that the about:blank page can be scripted + // by other frames with the initiator's origin. + if (content::AreAllSitesIsolatedForTesting()) { + // If the opener is a blink::RemoteFrame, then Blink uses an opaque origin. + EXPECT_TRUE(popup->GetMainFrame()->GetLastCommittedOrigin().opaque()); + } else { + EXPECT_EQ(url::Origin::Create(kOpenerUrl), + popup->GetMainFrame()->GetLastCommittedOrigin()); + } +} + +// This test covers a navigation that: +// 1. is initiated by a cross-site initiator, +// 2. gets redirected via webRequest API to a data: URL +// This covers a scenario similar to the one that led to crashes in +// https://crbug.com/1026738. +IN_PROC_BROWSER_TEST_F( + ChromeNavigationBrowserTest, + NavigationInitiatedByCrossSiteSubframeRedirectedToDataUrl) { + const GURL kOpenerUrl( + embedded_test_server()->GetURL("opener.com", "/title1.html")); + const GURL kInitialPopupUrl(embedded_test_server()->GetURL( + "initial-site.com", + "/frame_tree/page_with_two_frames_remote_and_local.html")); + const GURL kRedirectedUrl("https://redirected.com/no-such-path"); + const GURL kRedirectTargetUrl( + "data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E"); + + // 1. Install an extension, which will redirect all navigations to + // redirected.com URLs to a data: URL. In general, web servers cannot + // redirect to data: URLs, but extensions with declarativeWebRequest API + // permissions can. + const char kManifest[] = R"( + { + "name": "Test for Bug1026738 - data: URL flavour", + "version": "0.1", + "manifest_version": 2, + "background": { + "scripts": ["background.js"] + }, + "permissions": [ + "declarativeWebRequest", "<all_urls>" + ] + } + )"; + const char kRulesScriptTemplate[] = R"( + var condition = new chrome.declarativeWebRequest.RequestMatcher({ + url: { + hostSuffix: 'redirected.com' + } + }); + var action = new chrome.declarativeWebRequest.RedirectRequest({ + redirectUrl: $1 + }); + var rule = { conditions: [ condition ], actions: [ action ]} + chrome.declarativeWebRequest.onRequest.addRules([rule]); + )"; + extensions::TestExtensionDir ext_dir; + ext_dir.WriteManifest(kManifest); + ext_dir.WriteFile( + FILE_PATH_LITERAL("background.js"), + content::JsReplace(kRulesScriptTemplate, kRedirectTargetUrl)); + extensions::ChromeTestExtensionLoader extension_loader(browser()->profile()); + scoped_refptr<const extensions::Extension> extension = + extension_loader.LoadExtension(ext_dir.UnpackedPath()); + ASSERT_TRUE(extension); + content::BrowserContext::GetDefaultStoragePartition(browser()->profile()) + ->FlushNetworkInterfaceForTesting(); + + // 2. Open a popup containing a cross-site subframe. + ui_test_utils::NavigateToURL(browser(), kOpenerUrl); + content::RenderFrameHost* opener = + browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(); + EXPECT_EQ(kOpenerUrl, opener->GetLastCommittedURL()); + EXPECT_EQ(url::Origin::Create(kOpenerUrl), opener->GetLastCommittedOrigin()); + content::WebContents* popup = nullptr; + { + content::WebContentsAddedObserver popup_observer; + ASSERT_TRUE(content::ExecJs( + opener, + content::JsReplace("window.open($1, 'my-popup')", kInitialPopupUrl))); + popup = popup_observer.GetWebContents(); + EXPECT_TRUE(WaitForLoadStop(popup)); + } + + // 3. Find the cross-site subframes in the popup. + EXPECT_EQ(3u, popup->GetAllFrames().size()); + content::RenderFrameHost* popup_root = popup->GetMainFrame(); + content::RenderFrameHost* cross_site_subframe = popup->GetAllFrames()[1]; + EXPECT_NE(cross_site_subframe->GetLastCommittedOrigin(), + popup_root->GetLastCommittedOrigin()); + EXPECT_NE(cross_site_subframe->GetLastCommittedOrigin(), + opener->GetLastCommittedOrigin()); + if (content::AreAllSitesIsolatedForTesting()) { + EXPECT_NE(cross_site_subframe->GetSiteInstance(), + popup_root->GetSiteInstance()); + EXPECT_NE(cross_site_subframe->GetSiteInstance(), + opener->GetSiteInstance()); + } + scoped_refptr<content::SiteInstance> old_popup_site_instance = + popup_root->GetSiteInstance(); + + // 4. Initiate popup navigation from the cross-site subframe. + // Note that the extension from step 1 above will redirect + // this navigation to a data: URL. + // + // This step might hit the CHECK in GetOriginForURLLoaderFactory once we start + // enforcing opaque origins with no precursor in CanAccessDataForOrigin. + content::TestNavigationObserver nav_observer(popup, 1); + ASSERT_TRUE(ExecJs(cross_site_subframe, + content::JsReplace("top.location = $1", kRedirectedUrl))); + nav_observer.Wait(); + EXPECT_EQ(kRedirectTargetUrl, popup->GetLastCommittedURL()); + EXPECT_TRUE(popup->GetMainFrame()->GetLastCommittedOrigin().opaque()); + + // 5. Verify that with site-per-process the data: URL is hosted in a brand + // new, separate process (separate from the opener and the previous popup + // process). + if (content::AreAllSitesIsolatedForTesting()) { + EXPECT_NE(opener->GetSiteInstance(), popup->GetSiteInstance()); + EXPECT_NE(old_popup_site_instance.get(), popup->GetSiteInstance()); + EXPECT_EQ(url::kDataScheme, + popup->GetSiteInstance()->GetSiteURL().scheme()); + } else { + EXPECT_EQ(opener->GetSiteInstance(), popup->GetSiteInstance()); + EXPECT_EQ(old_popup_site_instance.get(), popup->GetSiteInstance()); + EXPECT_NE(url::kDataScheme, + popup->GetSiteInstance()->GetSiteURL().scheme()); + } +} + class SignInIsolationBrowserTest : public ChromeNavigationBrowserTest { public: SignInIsolationBrowserTest()
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index c3482e41b..f799062 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -2212,6 +2212,8 @@ "smb_client/smb_file_system_id.h", "smb_client/smb_kerberos_credentials_updater.cc", "smb_client/smb_kerberos_credentials_updater.h", + "smb_client/smb_persisted_share_registry.cc", + "smb_client/smb_persisted_share_registry.h", "smb_client/smb_provider.cc", "smb_client/smb_provider.h", "smb_client/smb_service.cc", @@ -3077,6 +3079,7 @@ "smb_client/smb_file_system_id_test.cc", "smb_client/smb_file_system_unittest.cc", "smb_client/smb_kerberos_credentials_updater_unittest.cc", + "smb_client/smb_persisted_share_registry_unittest.cc", "smb_client/smb_service_helper_unittest.cc", "smb_client/smb_service_unittest.cc", "smb_client/smb_share_finder_unittest.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 2502aca..46fc2803 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
@@ -466,6 +466,14 @@ case AXActionType::SCROLL_FORWARD: out_data->AddAction(ax::mojom::Action::kScrollForward); break; + case AXActionType::EXPAND: + out_data->AddAction(ax::mojom::Action::kExpand); + out_data->AddState(ax::mojom::State::kCollapsed); + break; + case AXActionType::COLLAPSE: + out_data->AddAction(ax::mojom::Action::kCollapse); + out_data->AddState(ax::mojom::State::kExpanded); + break; default: // unmapped break;
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.cc index 9664026..f53bf05 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.cc +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.cc
@@ -112,6 +112,10 @@ return arc::mojom::AccessibilityActionType::SHOW_TOOLTIP; case ax::mojom::Action::kHideTooltip: return arc::mojom::AccessibilityActionType::HIDE_TOOLTIP; + case ax::mojom::Action::kCollapse: + return arc::mojom::AccessibilityActionType::COLLAPSE; + case ax::mojom::Action::kExpand: + return arc::mojom::AccessibilityActionType::EXPAND; default: return base::nullopt; }
diff --git a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc index 6909558..83ac4204 100644 --- a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc +++ b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc_unittest.cc
@@ -748,6 +748,59 @@ ASSERT_EQ("tooltip text", prop); } +TEST_F(AXTreeSourceArcTest, StateComputations) { + auto event = AXEventData::New(); + event->source_id = 1; + event->task_id = 1; + event->event_type = AXEventType::VIEW_FOCUSED; + + // Window. + event->window_data = std::vector<mojom::AccessibilityWindowInfoDataPtr>(); + event->window_data->push_back(AXWindowInfoData::New()); + AXWindowInfoData* root_window = event->window_data->back().get(); + root_window->window_id = 100; + root_window->root_node_id = 1; + + // Node. + event->node_data.push_back(AXNodeInfoData::New()); + AXNodeInfoData* node = event->node_data.back().get(); + node->id = 1; + + // Node is checkable, but not checked. + SetProperty(node, AXBooleanProperty::CHECKABLE, true); + SetProperty(node, AXBooleanProperty::CHECKED, false); + CallNotifyAccessibilityEvent(event.get()); + + std::unique_ptr<ui::AXNodeData> data; + CallSerializeNode(node, &data); + EXPECT_EQ(ax::mojom::CheckedState::kFalse, data->GetCheckedState()); + + // Make the node checked. + SetProperty(node, AXBooleanProperty::CHECKED, true); + + CallNotifyAccessibilityEvent(event.get()); + CallSerializeNode(node, &data); + EXPECT_EQ(ax::mojom::CheckedState::kTrue, data->GetCheckedState()); + + // Make the node expandable (i.e. collapsed). + SetProperty(node, AXIntListProperty::STANDARD_ACTION_IDS, + std::vector<int>({static_cast<int>(AXActionType::EXPAND)})); + + CallNotifyAccessibilityEvent(event.get()); + CallSerializeNode(node, &data); + EXPECT_TRUE(data->HasState(ax::mojom::State::kCollapsed)); + EXPECT_FALSE(data->HasState(ax::mojom::State::kExpanded)); + + // Make the node collapsible (i.e. expanded). + SetProperty(node, AXIntListProperty::STANDARD_ACTION_IDS, + std::vector<int>({static_cast<int>(AXActionType::COLLAPSE)})); + + CallNotifyAccessibilityEvent(event.get()); + CallSerializeNode(node, &data); + EXPECT_FALSE(data->HasState(ax::mojom::State::kCollapsed)); + EXPECT_TRUE(data->HasState(ax::mojom::State::kExpanded)); +} + TEST_F(AXTreeSourceArcTest, ComplexTreeStructure) { int tree_size = 4; int num_trees = 3;
diff --git a/chrome/browser/chromeos/attestation/platform_verification_dialog.cc b/chrome/browser/chromeos/attestation/platform_verification_dialog.cc index 4cd356d1..85e9173 100644 --- a/chrome/browser/chromeos/attestation/platform_verification_dialog.cc +++ b/chrome/browser/chromeos/attestation/platform_verification_dialog.cc
@@ -38,9 +38,8 @@ std::unique_ptr<views::ImageButton> CreateLearnMoreButton( views::ButtonListener* listener) { - auto learn_more_button = views::CreateVectorImageButton(listener); - views::SetImageFromVectorIcon(learn_more_button.get(), - vector_icons::kHelpOutlineIcon); + auto learn_more_button = views::CreateVectorImageButtonWithNativeTheme( + listener, vector_icons::kHelpOutlineIcon); learn_more_button->SetAccessibleName( l10n_util::GetStringUTF16(IDS_CHROMEOS_ACC_LEARN_MORE)); learn_more_button->SetFocusForPlatform(); @@ -93,8 +92,7 @@ ConsentCallback callback) : content::WebContentsObserver(web_contents), domain_(domain), - callback_(std::move(callback)), - learn_more_button_(nullptr) { + callback_(std::move(callback)) { DialogDelegate::set_button_label( ui::DIALOG_BUTTON_OK, l10n_util::GetStringUTF16(IDS_PERMISSION_ALLOW)); DialogDelegate::set_button_label( @@ -119,11 +117,11 @@ run_callback, base::Unretained(this), CONSENT_RESPONSE_NONE)); // Explanation string. - views::Label* label = new views::Label(l10n_util::GetStringFUTF16( + auto label = std::make_unique<views::Label>(l10n_util::GetStringFUTF16( IDS_PLATFORM_VERIFICATION_DIALOG_HEADLINE, domain_)); label->SetMultiLine(true); label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - AddChildView(label); + AddChildView(std::move(label)); chrome::RecordDialogCreation(chrome::DialogIdentifier::PLATFORM_VERIFICATION); }
diff --git a/chrome/browser/chromeos/attestation/platform_verification_dialog.h b/chrome/browser/chromeos/attestation/platform_verification_dialog.h index 41005ef4..cc7fb99 100644 --- a/chrome/browser/chromeos/attestation/platform_verification_dialog.h +++ b/chrome/browser/chromeos/attestation/platform_verification_dialog.h
@@ -50,10 +50,8 @@ const base::string16& domain, ConsentCallback callback); - // views::WidgetDelegate: + // views::DialogDelegateView: ui::ModalType GetModalType() const override; - - // views::View: gfx::Size CalculatePreferredSize() const override; // views::ButtonListener: @@ -65,7 +63,7 @@ base::string16 domain_; ConsentCallback callback_; - views::ImageButton* learn_more_button_; + views::ImageButton* learn_more_button_ = nullptr; DISALLOW_COPY_AND_ASSIGN(PlatformVerificationDialog); };
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc index 0552227..e8af99f1 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -2389,6 +2389,7 @@ void OnOpenAppResponse(chromeos::assistant::mojom::AndroidAppInfoPtr app_info, OnOpenAppResponseCallback callback) override { result_.SetKey("openAppResponse", base::Value(app_info->package_name)); + std::move(callback).Run(true); } void OnSuggestionsResponse( @@ -2463,6 +2464,8 @@ void AutotestPrivateSendAssistantTextQueryFunction:: OnInteractionFinishedCallback(bool success) { + // |timeout_timer_| need to be hold until |Respond(.)| is called to avoid + // |this| being destructed. if (!success) { Respond(Error("Interaction ends abnormally.")); timeout_timer_.AbandonAndStop(); @@ -2519,6 +2522,8 @@ void AutotestPrivateWaitForAssistantQueryStatusFunction:: OnInteractionFinishedCallback(bool success) { + // |timeout_timer_| need to be hold until |Respond(.)| is called to avoid + // |this| being destructed. if (!success) { Respond(Error("Interaction ends abnormally.")); timeout_timer_.AbandonAndStop();
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index afbd79e..f2ce0f3a 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -502,6 +502,10 @@ TestCase("openQuickViewDeleteEntireCheckSelection"), TestCase("openQuickViewClickDeleteButton"), TestCase("openQuickViewDeleteButtonNotShown"), + TestCase("openQuickViewUmaViaContextMenu"), + TestCase("openQuickViewUmaForCheckSelectViaContextMenu"), + TestCase("openQuickViewUmaViaSelectionMenu"), + TestCase("openQuickViewUmaViaSelectionMenuKeyboard"), TestCase("closeQuickView"))); WRAPPED_INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/chromeos/first_run/first_run_view.cc b/chrome/browser/chromeos/first_run/first_run_view.cc index 67cd572..ffea9c1 100644 --- a/chrome/browser/chromeos/first_run/first_run_view.cc +++ b/chrome/browser/chromeos/first_run/first_run_view.cc
@@ -15,6 +15,7 @@ #include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/views/controls/webview/webview.h"
diff --git a/chrome/browser/chromeos/login/ui/login_web_dialog.cc b/chrome/browser/chromeos/login/ui/login_web_dialog.cc index cf91edc..57b0046 100644 --- a/chrome/browser/chromeos/login/ui/login_web_dialog.cc +++ b/chrome/browser/chromeos/login/ui/login_web_dialog.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui.h" #include "ui/aura/window.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/native_widget_types.h"
diff --git a/chrome/browser/chromeos/smb_client/smb_persisted_share_registry.cc b/chrome/browser/chromeos/smb_client/smb_persisted_share_registry.cc new file mode 100644 index 0000000..d790842 --- /dev/null +++ b/chrome/browser/chromeos/smb_client/smb_persisted_share_registry.cc
@@ -0,0 +1,141 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/smb_client/smb_persisted_share_registry.h" + +#include <utility> + +#include "base/logging.h" +#include "base/values.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/pref_names.h" +#include "components/pref_registry/pref_registry_syncable.h" +#include "components/prefs/scoped_user_pref_update.h" + +namespace chromeos { +namespace smb_client { +namespace { + +constexpr char kShareUrlKey[] = "share_url"; +constexpr char kDisplayNameKey[] = "display_name"; +constexpr char kUsernameKey[] = "username"; +constexpr char kWorkgroupKey[] = "workgroup"; +constexpr char kUseKerberosKey[] = "use_kerberos"; + +base::Value ShareToDict(const SmbShareInfo& share) { + base::Value dict(base::Value::Type::DICTIONARY); + dict.SetStringKey(kShareUrlKey, share.share_url().ToString()); + dict.SetStringKey(kDisplayNameKey, share.display_name()); + dict.SetBoolKey(kUseKerberosKey, share.use_kerberos()); + if (!share.username().empty()) { + dict.SetStringKey(kUsernameKey, share.username()); + } + if (!share.workgroup().empty()) { + dict.SetStringKey(kWorkgroupKey, share.workgroup()); + } + return dict; +} + +std::string GetStringValue(const base::Value& dict, const std::string& key) { + const std::string* value = dict.FindStringKey(key); + if (!value) { + return {}; + } + return *value; +} + +base::Optional<SmbShareInfo> DictToShare(const base::Value& dict) { + std::string share_url = GetStringValue(dict, kShareUrlKey); + if (share_url.empty()) { + return {}; + } + + SmbUrl url(share_url); + DCHECK(url.IsValid()); + SmbShareInfo info(url, GetStringValue(dict, kDisplayNameKey), + GetStringValue(dict, kUsernameKey), + GetStringValue(dict, kWorkgroupKey), + dict.FindBoolKey(kUseKerberosKey).value_or(false)); + return base::make_optional(std::move(info)); +} + +} // namespace + +// static +void SmbPersistedShareRegistry::RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* registry) { + registry->RegisterListPref(prefs::kNetworkFileSharesSavedShares); +} + +SmbPersistedShareRegistry::SmbPersistedShareRegistry(Profile* profile) + : profile_(profile) {} + +void SmbPersistedShareRegistry::Save(const SmbShareInfo& share) { + ListPrefUpdate pref(profile_->GetPrefs(), + prefs::kNetworkFileSharesSavedShares); + + base::Value::ListView share_list = pref->GetList(); + for (auto it = share_list.begin(); it != share_list.end(); ++it) { + if (GetStringValue(*it, kShareUrlKey) == share.share_url().ToString()) { + *it = ShareToDict(share); + return; + } + } + + pref->Append(ShareToDict(share)); + return; +} + +void SmbPersistedShareRegistry::Delete(const SmbUrl& share_url) { + ListPrefUpdate pref(profile_->GetPrefs(), + prefs::kNetworkFileSharesSavedShares); + + base::Value::ListView share_list = pref->GetList(); + for (auto it = share_list.begin(); it != share_list.end(); ++it) { + if (GetStringValue(*it, kShareUrlKey) == share_url.ToString()) { + bool result = pref->EraseListIter(it); + DCHECK(result); + return; + } + } +} + +base::Optional<SmbShareInfo> SmbPersistedShareRegistry::Get( + const SmbUrl& share_url) const { + const base::Value* pref = + profile_->GetPrefs()->Get(prefs::kNetworkFileSharesSavedShares); + if (!pref) { + return {}; + } + + base::Value::ConstListView share_list = pref->GetList(); + for (auto it = share_list.begin(); it != share_list.end(); ++it) { + if (GetStringValue(*it, kShareUrlKey) == share_url.ToString()) { + return DictToShare(*it); + } + } + return {}; +} + +std::vector<SmbShareInfo> SmbPersistedShareRegistry::GetAll() const { + const base::Value* pref = + profile_->GetPrefs()->Get(prefs::kNetworkFileSharesSavedShares); + if (!pref) { + return {}; + } + + std::vector<SmbShareInfo> shares; + base::Value::ConstListView share_list = pref->GetList(); + for (auto it = share_list.begin(); it != share_list.end(); ++it) { + base::Optional<SmbShareInfo> info = DictToShare(*it); + if (!info) { + continue; + } + shares.push_back(std::move(*info)); + } + return shares; +} + +} // namespace smb_client +} // namespace chromeos
diff --git a/chrome/browser/chromeos/smb_client/smb_persisted_share_registry.h b/chrome/browser/chromeos/smb_client/smb_persisted_share_registry.h new file mode 100644 index 0000000..932ad8b1b --- /dev/null +++ b/chrome/browser/chromeos/smb_client/smb_persisted_share_registry.h
@@ -0,0 +1,59 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_SMB_CLIENT_SMB_PERSISTED_SHARE_REGISTRY_H_ +#define CHROME_BROWSER_CHROMEOS_SMB_CLIENT_SMB_PERSISTED_SHARE_REGISTRY_H_ + +#include <string> +#include <vector> + +#include "base/optional.h" +#include "chrome/browser/chromeos/smb_client/smb_share_info.h" + +class Profile; + +namespace user_prefs { +class PrefRegistrySyncable; +} + +namespace chromeos { +namespace smb_client { + +class SmbUrl; + +// Handles saving of SMB shares in the user's Profile. +class SmbPersistedShareRegistry { + public: + static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); + + explicit SmbPersistedShareRegistry(Profile* profile); + + // Disallow copy/assign. + SmbPersistedShareRegistry() = delete; + SmbPersistedShareRegistry(const SmbPersistedShareRegistry&) = delete; + SmbPersistedShareRegistry& operator=(const SmbPersistedShareRegistry&) = + delete; + + // Save |share| in the user's profile. If a saved share already exists with + // the url share.share_url(), that saved share will be overwritten. + void Save(const SmbShareInfo& share); + + // Delete the saved share with the URL |share_url|. + void Delete(const SmbUrl& share_url); + + // Return the saved share with URL |share_url|, or the empty Optional<> if no + // share is found. + base::Optional<SmbShareInfo> Get(const SmbUrl& share_url) const; + + // Return a list of all saved shares. + std::vector<SmbShareInfo> GetAll() const; + + private: + Profile* const profile_; +}; + +} // namespace smb_client +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_SMB_CLIENT_SMB_PERSISTED_SHARE_REGISTRY_H_
diff --git a/chrome/browser/chromeos/smb_client/smb_persisted_share_registry_unittest.cc b/chrome/browser/chromeos/smb_client/smb_persisted_share_registry_unittest.cc new file mode 100644 index 0000000..7718db8 --- /dev/null +++ b/chrome/browser/chromeos/smb_client/smb_persisted_share_registry_unittest.cc
@@ -0,0 +1,155 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/smb_client/smb_persisted_share_registry.h" + +#include "chrome/browser/chromeos/smb_client/smb_url.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { +namespace smb_client { +namespace { + +const char kShareUrl[] = "smb://server/share1"; +const char kShareUrl2[] = "smb://server/share2"; +const char kDisplayName[] = "My File Share"; +const char kUsername[] = "test-user"; +const char kUsername2[] = "test-user2"; +const char kWorkgroup[] = "test-workgroup.com"; + +class SmbPersistedShareRegistryTest : public testing::Test { + protected: + content::BrowserTaskEnvironment task_environment_; + TestingProfile profile_; +}; + +TEST_F(SmbPersistedShareRegistryTest, Empty) { + SmbPersistedShareRegistry registry(&profile_); + base::Optional<SmbShareInfo> info = registry.Get(SmbUrl(kShareUrl)); + EXPECT_FALSE(info); + + std::vector<SmbShareInfo> all_info = registry.GetAll(); + EXPECT_TRUE(all_info.empty()); + + // Should do nothing, not crash. + registry.Delete(SmbUrl(kShareUrl)); +} + +TEST_F(SmbPersistedShareRegistryTest, SaveGet) { + { + SmbPersistedShareRegistry registry(&profile_); + SmbShareInfo info1(SmbUrl(kShareUrl), kDisplayName, kUsername, kWorkgroup, + false /* use_kerberos */); + registry.Save(info1); + + SmbShareInfo info2(SmbUrl(kShareUrl2), kDisplayName, kUsername2, kWorkgroup, + true /* use_kerberos */); + registry.Save(info2); + } + // Use scopes to simulate a logout/login so that the instances of + // SmbPersistedShareRegistry are not the same (and have no hidden state). + { + SmbPersistedShareRegistry registry(&profile_); + base::Optional<SmbShareInfo> info = registry.Get(SmbUrl(kShareUrl)); + ASSERT_TRUE(info); + EXPECT_EQ(info->share_url().ToString(), kShareUrl); + EXPECT_EQ(info->display_name(), kDisplayName); + EXPECT_EQ(info->username(), kUsername); + EXPECT_EQ(info->workgroup(), kWorkgroup); + EXPECT_FALSE(info->use_kerberos()); + + base::Optional<SmbShareInfo> info2 = registry.Get(SmbUrl(kShareUrl2)); + ASSERT_TRUE(info2); + EXPECT_EQ(info2->share_url().ToString(), kShareUrl2); + EXPECT_EQ(info2->display_name(), kDisplayName); + EXPECT_EQ(info2->username(), kUsername2); + EXPECT_EQ(info2->workgroup(), kWorkgroup); + EXPECT_TRUE(info2->use_kerberos()); + + std::vector<SmbShareInfo> all_info = registry.GetAll(); + EXPECT_EQ(all_info.size(), 2u); + EXPECT_EQ(all_info[0].share_url().ToString(), kShareUrl); + EXPECT_EQ(all_info[1].share_url().ToString(), kShareUrl2); + } +} + +TEST_F(SmbPersistedShareRegistryTest, Replace) { + { + SmbPersistedShareRegistry registry(&profile_); + SmbShareInfo info(SmbUrl(kShareUrl), kDisplayName, kUsername, kWorkgroup, + false /* use_kerberos */); + registry.Save(info); + } + // Use scopes to simulate a logout/login so that the instances of + // SmbPersistedShareRegistry are not the same (and have no hidden state). + { + SmbPersistedShareRegistry registry(&profile_); + base::Optional<SmbShareInfo> info = registry.Get(SmbUrl(kShareUrl)); + ASSERT_TRUE(info); + EXPECT_EQ(info->share_url().ToString(), kShareUrl); + EXPECT_EQ(info->display_name(), kDisplayName); + EXPECT_EQ(info->username(), kUsername); + EXPECT_EQ(info->workgroup(), kWorkgroup); + EXPECT_FALSE(info->use_kerberos()); + + std::vector<SmbShareInfo> all_info = registry.GetAll(); + EXPECT_EQ(all_info.size(), 1u); + + SmbShareInfo replace_info(SmbUrl(kShareUrl), kDisplayName, kUsername2, + kWorkgroup, true /* use_kerberos */); + registry.Save(replace_info); + } + { + SmbPersistedShareRegistry registry(&profile_); + base::Optional<SmbShareInfo> info = registry.Get(SmbUrl(kShareUrl)); + ASSERT_TRUE(info); + EXPECT_EQ(info->share_url().ToString(), kShareUrl); + EXPECT_EQ(info->display_name(), kDisplayName); + EXPECT_EQ(info->username(), kUsername2); + EXPECT_EQ(info->workgroup(), kWorkgroup); + EXPECT_TRUE(info->use_kerberos()); + + std::vector<SmbShareInfo> all_info = registry.GetAll(); + EXPECT_EQ(all_info.size(), 1u); + } +} + +TEST_F(SmbPersistedShareRegistryTest, Delete) { + { + SmbPersistedShareRegistry registry(&profile_); + SmbShareInfo info1(SmbUrl(kShareUrl), kDisplayName, kUsername, kWorkgroup, + false /* use_kerberos */); + registry.Save(info1); + + SmbShareInfo info2(SmbUrl(kShareUrl2), kDisplayName, kUsername2, kWorkgroup, + true /* use_kerberos */); + registry.Save(info2); + } + // Use scopes to simulate a logout/login so that the instances of + // SmbPersistedShareRegistry are not the same (and have no hidden state). + { + SmbPersistedShareRegistry registry(&profile_); + registry.Delete(SmbUrl(kShareUrl2)); + + base::Optional<SmbShareInfo> info = registry.Get(SmbUrl(kShareUrl)); + ASSERT_TRUE(info); + EXPECT_EQ(info->share_url().ToString(), kShareUrl); + EXPECT_EQ(info->display_name(), kDisplayName); + EXPECT_EQ(info->username(), kUsername); + EXPECT_EQ(info->workgroup(), kWorkgroup); + EXPECT_FALSE(info->use_kerberos()); + + base::Optional<SmbShareInfo> info2 = registry.Get(SmbUrl(kShareUrl2)); + ASSERT_FALSE(info2); + + std::vector<SmbShareInfo> all_info = registry.GetAll(); + EXPECT_EQ(all_info.size(), 1u); + } +} + +} // namespace +} // namespace smb_client +} // namespace chromeos
diff --git a/chrome/browser/chromeos/smb_client/smb_service.cc b/chrome/browser/chromeos/smb_client/smb_service.cc index 7375829..0728d99 100644 --- a/chrome/browser/chromeos/smb_client/smb_service.cc +++ b/chrome/browser/chromeos/smb_client/smb_service.cc
@@ -132,7 +132,8 @@ std::unique_ptr<base::TickClock> tick_clock) : provider_id_(ProviderId::CreateFromNativeId("smb")), profile_(profile), - tick_clock_(std::move(tick_clock)) { + tick_clock_(std::move(tick_clock)), + registry_(profile) { user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile(profile_); DCHECK(user); @@ -178,13 +179,18 @@ registry->RegisterBooleanPref(prefs::kNTLMShareAuthenticationEnabled, true); registry->RegisterListPref(prefs::kNetworkFileSharesPreconfiguredShares); registry->RegisterStringPref(prefs::kMostRecentlyUsedNetworkFileShareURL, ""); + SmbPersistedShareRegistry::RegisterProfilePrefs(registry); } void SmbService::UnmountSmbFs(const base::FilePath& mount_path) { DCHECK(!mount_path.empty()); for (auto it = smbfs_shares_.begin(); it != smbfs_shares_.end(); ++it) { - if (it->second->mount_path() == mount_path) { + SmbFsShare* share = it->second.get(); + if (share->mount_path() == mount_path) { + // UnmountSmbFs() is called by an explicit unmount by the user. In this + // case, forget the share. + registry_.Delete(share->share_url()); smbfs_shares_.erase(it); return; } @@ -347,13 +353,14 @@ false /* skip_connect */, base::BindOnce(&SmbService::MountInternalDone, base::Unretained(this), std::move(callback), - should_open_file_manager_after_mount)); + info, should_open_file_manager_after_mount)); profile_->GetPrefs()->SetString(prefs::kMostRecentlyUsedNetworkFileShareURL, share_path.value()); } void SmbService::MountInternalDone(MountResponse callback, + const SmbShareInfo& info, bool should_open_file_manager_after_mount, SmbMountResult result, const base::FilePath& mount_path) { @@ -367,6 +374,10 @@ platform_util::ShowItemInFolder(profile_, mount_path); } + if (IsSmbFsEnabled()) { + registry_.Save(info); + } + RecordMountCount(); std::move(callback).Run(SmbMountResult::kSuccess); } @@ -535,25 +546,38 @@ } void SmbService::RestoreMounts() { - std::vector<ProvidedFileSystemInfo> file_systems = + std::vector<ProvidedFileSystemInfo> provided_file_systems = GetProviderService()->GetProvidedFileSystemInfoList(provider_id_); std::vector<SmbUrl> preconfigured_shares = GetPreconfiguredSharePathsForPremount(); - if (!file_systems.empty() || !preconfigured_shares.empty()) { + std::vector<SmbShareInfo> saved_smbfs_shares; + if (IsSmbFsEnabled()) { + // Restore smbfs shares. + // TODO(crbug.com/1055571): Migrate saved smbprovider shares to smbfs. + saved_smbfs_shares = registry_.GetAll(); + } + + if (!provided_file_systems.empty() || !saved_smbfs_shares.empty() || + !preconfigured_shares.empty()) { share_finder_->DiscoverHostsInNetwork(base::BindOnce( - &SmbService::OnHostsDiscovered, AsWeakPtr(), std::move(file_systems), + &SmbService::OnHostsDiscovered, AsWeakPtr(), + std::move(provided_file_systems), std::move(saved_smbfs_shares), std::move(preconfigured_shares))); } } void SmbService::OnHostsDiscovered( const std::vector<ProvidedFileSystemInfo>& file_systems, + const std::vector<SmbShareInfo>& saved_smbfs_shares, const std::vector<SmbUrl>& preconfigured_shares) { for (const auto& file_system : file_systems) { Remount(file_system); } + for (const auto& smbfs_share : saved_smbfs_shares) { + MountSavedSmbfsShare(smbfs_share); + } for (const auto& url : preconfigured_shares) { MountPreconfiguredShare(url); } @@ -647,6 +671,17 @@ mount_id_map_[file_system_id] = mount_id; } +void SmbService::MountSavedSmbfsShare(const SmbShareInfo& info) { + MountInternal( + {} /* fsp::MountOptions, ignored by smbfs */, info, "" /* password */, + false /* save_credentials */, true /* skip_connect */, + base::BindOnce( + [](SmbMountResult result, const base::FilePath& mount_path) { + LOG_IF(ERROR, result != SmbMountResult::kSuccess) + << "Error restoring saved share: " << static_cast<int>(result); + })); +} + void SmbService::MountPreconfiguredShare(const SmbUrl& share_url) { file_system_provider::MountOptions mount_options; mount_options.display_name =
diff --git a/chrome/browser/chromeos/smb_client/smb_service.h b/chrome/browser/chromeos/smb_client/smb_service.h index e7d01585..43e5614 100644 --- a/chrome/browser/chromeos/smb_client/smb_service.h +++ b/chrome/browser/chromeos/smb_client/smb_service.h
@@ -20,6 +20,7 @@ #include "chrome/browser/chromeos/file_system_provider/provider_interface.h" #include "chrome/browser/chromeos/file_system_provider/service.h" #include "chrome/browser/chromeos/smb_client/smb_errors.h" +#include "chrome/browser/chromeos/smb_client/smb_persisted_share_registry.h" #include "chrome/browser/chromeos/smb_client/smb_share_finder.h" #include "chrome/browser/chromeos/smb_client/smb_task_queue.h" #include "chrome/browser/chromeos/smb_client/smbfs_share.h" @@ -132,6 +133,7 @@ // Callback passed to MountInternal(). void MountInternalDone(MountResponse callback, + const SmbShareInfo& info, bool should_open_file_manager_after_mount, SmbMountResult result, const base::FilePath& mount_path); @@ -180,6 +182,7 @@ void OnHostsDiscovered( const std::vector<ProvidedFileSystemInfo>& file_systems, + const std::vector<SmbShareInfo>& saved_smbfs_shares, const std::vector<SmbUrl>& preconfigured_shares); // Closure for OnHostDiscovered(). |reply| is passed down to @@ -199,6 +202,9 @@ smbprovider::ErrorType error, int32_t mount_id); + // Mounts a saved (smbfs) SMB share with details |info|. + void MountSavedSmbfsShare(const SmbShareInfo& info); + // Mounts a preconfigured (by policy) SMB share with path |share_url|. The // share is mounted with empty credentials. void MountPreconfiguredShare(const SmbUrl& share_url); @@ -310,6 +316,7 @@ // Note, mount ID for smbfs is a randomly generated string. For smbprovider // shares, it is an integer. std::unordered_map<std::string, std::unique_ptr<SmbFsShare>> smbfs_shares_; + SmbPersistedShareRegistry registry_; std::unique_ptr<SmbKerberosCredentialsUpdater> smb_credentials_updater_;
diff --git a/chrome/browser/chromeos/smb_client/smb_service_unittest.cc b/chrome/browser/chromeos/smb_client/smb_service_unittest.cc index a483af6..b6396d9 100644 --- a/chrome/browser/chromeos/smb_client/smb_service_unittest.cc +++ b/chrome/browser/chromeos/smb_client/smb_service_unittest.cc
@@ -30,6 +30,7 @@ #include "chrome/browser/chromeos/file_system_provider/service.h" #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/smb_client/smb_file_system_id.h" +#include "chrome/browser/chromeos/smb_client/smb_persisted_share_registry.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_browser_process.h" @@ -730,6 +731,16 @@ } } EXPECT_TRUE(found); + + // Check that the share was saved. + SmbPersistedShareRegistry registry(profile_); + base::Optional<SmbShareInfo> info = registry.Get(SmbUrl(kShareUrl)); + ASSERT_TRUE(info); + EXPECT_EQ(info->share_url().ToString(), kShareUrl); + EXPECT_EQ(info->display_name(), kDisplayName); + EXPECT_EQ(info->username(), kTestUser); + EXPECT_TRUE(info->workgroup().empty()); + EXPECT_FALSE(info->use_kerberos()); } TEST_F(SmbServiceWithSmbfsTest, Mount_ActiveDirectory) { @@ -790,6 +801,17 @@ run_loop.Quit(); })); run_loop.Run(); + + // Check that the share was saved. + SmbPersistedShareRegistry registry(ad_profile_); + base::Optional<SmbShareInfo> info = registry.Get(SmbUrl(kShareUrl)); + ASSERT_TRUE(info); + EXPECT_EQ(info->share_url().ToString(), kShareUrl); + EXPECT_EQ(info->display_name(), kDisplayName); + EXPECT_EQ(info->username(), kTestADUser); + // Workgroup/domain is converted to upper-case. + EXPECT_EQ(info->workgroup(), base::ToUpperASCII(kTestADDomain)); + EXPECT_TRUE(info->use_kerberos()); } TEST_F(SmbServiceWithSmbfsTest, PreconfiguredMount) { @@ -843,5 +865,64 @@ run_loop.Run(); } +TEST_F(SmbServiceWithSmbfsTest, MountSaved) { + // Save share in profile. + { + SmbPersistedShareRegistry registry(profile_); + SmbShareInfo info(SmbUrl(kShareUrl), kDisplayName, kTestUser, kTestDomain, + false /* use_kerberos */); + registry.Save(info); + } + + CreateService(profile_); + + mojo::Remote<smbfs::mojom::SmbFs> smbfs_remote; + MockSmbFsImpl smbfs_impl(smbfs_remote.BindNewPipeAndPassReceiver()); + mojo::Remote<smbfs::mojom::SmbFsDelegate> smbfs_delegate_remote; + + smbfs::SmbFsHost::Delegate* smbfs_host_delegate = nullptr; + std::unique_ptr<MockSmbFsMounter> mock_mounter = + std::make_unique<MockSmbFsMounter>(); + smb_service_->SetSmbFsMounterCreationCallbackForTesting( + base::BindLambdaForTesting([&mock_mounter, &smbfs_host_delegate]( + const std::string& share_path, + const std::string& mount_dir_name, + const SmbFsShare::MountOptions& options, + smbfs::SmbFsHost::Delegate* delegate) + -> std::unique_ptr<smbfs::SmbFsMounter> { + EXPECT_EQ(share_path, kShareUrl); + EXPECT_EQ(options.username, kTestUser); + EXPECT_EQ(options.workgroup, kTestDomain); + EXPECT_TRUE(options.password.empty()); + EXPECT_EQ(options.allow_ntlm, true); + EXPECT_FALSE(options.kerberos_options); + smbfs_host_delegate = delegate; + return std::move(mock_mounter); + })); + + base::RunLoop run_loop; + EXPECT_CALL(*mock_mounter, Mount(_)) + .WillOnce([this, &smbfs_host_delegate, &smbfs_remote, + &smbfs_delegate_remote, + &run_loop](smbfs::SmbFsMounter::DoneCallback callback) { + std::move(callback).Run( + smbfs::mojom::MountError::kOk, + std::make_unique<smbfs::SmbFsHost>( + MakeMountPoint(base::FilePath(kMountPath)), smbfs_host_delegate, + std::move(smbfs_remote), + smbfs_delegate_remote.BindNewPipeAndPassReceiver())); + run_loop.Quit(); + }); + + run_loop.Run(); + + // Unmounting should remove the saved share. + smb_service_->UnmountSmbFs(base::FilePath(kMountPath)); + SmbPersistedShareRegistry registry(profile_); + base::Optional<SmbShareInfo> info = registry.Get(SmbUrl(kShareUrl)); + EXPECT_FALSE(info); + EXPECT_TRUE(registry.GetAll().empty()); +} + } // namespace smb_client } // namespace chromeos
diff --git a/chrome/browser/chromeos/system_logs/device_event_log_source.cc b/chrome/browser/chromeos/system_logs/device_event_log_source.cc index 75c34d7..9f4510d 100644 --- a/chrome/browser/chromeos/system_logs/device_event_log_source.cc +++ b/chrome/browser/chromeos/system_logs/device_event_log_source.cc
@@ -23,7 +23,7 @@ DCHECK(!callback.is_null()); auto response = std::make_unique<SystemLogsResponse>(); - const int kMaxDeviceEventsForAboutSystem = 400; + const int kMaxDeviceEventsForAboutSystem = 4000; (*response)[kNetworkEventLogEntry] = device_event_log::GetAsString( device_event_log::OLDEST_FIRST, "unixtime,file,level", "network", device_event_log::kDefaultLogLevel, kMaxDeviceEventsForAboutSystem);
diff --git a/chrome/browser/chromeos/ui/echo_dialog_view.cc b/chrome/browser/chromeos/ui/echo_dialog_view.cc index 00c52bf6..e1e8bd5 100644 --- a/chrome/browser/chromeos/ui/echo_dialog_view.cc +++ b/chrome/browser/chromeos/ui/echo_dialog_view.cc
@@ -24,9 +24,8 @@ std::unique_ptr<views::ImageButton> CreateLearnMoreButton( views::ButtonListener* listener) { - auto learn_more_button = views::CreateVectorImageButton(listener); - views::SetImageFromVectorIcon(learn_more_button.get(), - vector_icons::kHelpOutlineIcon); + auto learn_more_button = views::CreateVectorImageButtonWithNativeTheme( + listener, vector_icons::kHelpOutlineIcon); learn_more_button->SetAccessibleName( l10n_util::GetStringUTF16(IDS_CHROMEOS_ACC_LEARN_MORE)); learn_more_button->SetFocusForPlatform(); @@ -120,12 +119,6 @@ return false; } -void EchoDialogView::ButtonPressed(views::Button* sender, - const ui::Event& event) { - DCHECK(sender == learn_more_button_); - listener_->OnMoreInfoLinkClicked(); -} - gfx::Size EchoDialogView::CalculatePreferredSize() const { const int default_width = views::LayoutProvider::Get()->GetDistanceMetric( DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH); @@ -134,6 +127,12 @@ GetLayoutManager()->GetPreferredHeightForWidth(this, default_width)); } +void EchoDialogView::ButtonPressed(views::Button* sender, + const ui::Event& event) { + DCHECK(sender == learn_more_button_); + listener_->OnMoreInfoLinkClicked(); +} + void EchoDialogView::SetBorderAndLabel(std::unique_ptr<views::View> label, const gfx::FontList& label_font_list) { SetLayoutManager(std::make_unique<views::FillLayout>());
diff --git a/chrome/browser/chromeos/ui/echo_dialog_view.h b/chrome/browser/chromeos/ui/echo_dialog_view.h index f20b43b5..223b8108 100644 --- a/chrome/browser/chromeos/ui/echo_dialog_view.h +++ b/chrome/browser/chromeos/ui/echo_dialog_view.h
@@ -60,17 +60,15 @@ // The dialog will have only Cancel button. void InitForDisabledEcho(); - // views::WidgetDelegate overrides. + // views::DialogDelegateView: ui::ModalType GetModalType() const override; bool ShouldShowWindowTitle() const override; bool ShouldShowCloseButton() const override; - - // views::ButtonListener overrides. - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - - // views::View override. gfx::Size CalculatePreferredSize() const override; + // views::ButtonListener: + void ButtonPressed(views::Button* sender, const ui::Event& event) override; + // Sets the border and label view. void SetBorderAndLabel(std::unique_ptr<views::View> label, const gfx::FontList& label_font_list);
diff --git a/chrome/browser/devtools/devtools_sanity_browsertest.cc b/chrome/browser/devtools/devtools_sanity_browsertest.cc index 04640137..69293f91 100644 --- a/chrome/browser/devtools/devtools_sanity_browsertest.cc +++ b/chrome/browser/devtools/devtools_sanity_browsertest.cc
@@ -833,7 +833,7 @@ // hadn't been shown by the moment inspected paged refreshed. // @see http://crbug.com/26312 // This test is flaky on windows and linux asan. See https://crbug.com/1013003 -#if defined(OS_WIN) || defined(OS_MACOSX) +#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) #define MAYBE_TestScriptsTabIsPopulatedOnInspectedPageRefresh \ DISABLED_TestScriptsTabIsPopulatedOnInspectedPageRefresh #else
diff --git a/chrome/browser/download/download_target_determiner.cc b/chrome/browser/download/download_target_determiner.cc index 73a5c62..dfe5552 100644 --- a/chrome/browser/download/download_target_determiner.cc +++ b/chrome/browser/download/download_target_determiner.cc
@@ -239,43 +239,7 @@ // (WebStore, Drag&Drop). Treat the path as a virtual path. We will // eventually determine whether this is a local path and if not, figure out // a local path. - std::string suggested_filename = download_->GetSuggestedFilename(); - if (suggested_filename.empty() && - download_->GetMimeType() == "application/x-x509-user-cert") { - suggested_filename = "user.crt"; - } - - std::string default_filename( - l10n_util::GetStringUTF8(IDS_DEFAULT_DOWNLOAD_FILENAME)); - std::string referrer_charset = - GetProfile()->GetPrefs()->GetString(prefs::kDefaultCharset); - base::FilePath generated_filename = net::GenerateFileName( - download_->GetURL(), download_->GetContentDisposition(), - referrer_charset, suggested_filename, download_->GetMimeType(), - default_filename); - - // Replace the file extension based on the mime type informed by - // Content-Type header if the file extension generated by the URL is - // considered safe by safe browsing. Noticed that when generating file name, - // |suggested_filename| and Content-Disposition header have higher priority - // than the URL. - bool safe_file_ext = - !safe_browsing::FileTypePolicies::GetInstance()->IsCheckedBinaryFile( - generated_filename); - net::HttpContentDisposition content_disposition_header( - download_->GetContentDisposition(), referrer_charset); - bool should_replace_extension = - safe_file_ext && !download_->GetMimeType().empty() && - suggested_filename.empty() && - content_disposition_header.filename().empty(); - if (should_replace_extension) { - generated_filename = net::GenerateFileName( - download_->GetURL(), std::string() /* content_disposition */, - referrer_charset, std::string() /* suggested_filename */, - download_->GetMimeType(), default_filename, - true /* should_replace_extension */); - } - + base::FilePath generated_filename = GenerateFileName(); confirmation_reason_ = NeedsConfirmation(generated_filename); base::FilePath target_directory; if (confirmation_reason_ != DownloadConfirmationReason::NONE) { @@ -309,6 +273,59 @@ return CONTINUE; } +base::FilePath DownloadTargetDeterminer::GenerateFileName() const { + std::string suggested_filename = download_->GetSuggestedFilename(); + std::string sniffed_mime_type = download_->GetMimeType(); + + if (suggested_filename.empty() && + sniffed_mime_type == "application/x-x509-user-cert") { + suggested_filename = "user.crt"; + } + + // Generate the file name, we may replace the file extension based on mime + // type under certain condition. + std::string default_filename( + l10n_util::GetStringUTF8(IDS_DEFAULT_DOWNLOAD_FILENAME)); + std::string referrer_charset = + GetProfile()->GetPrefs()->GetString(prefs::kDefaultCharset); + base::FilePath generated_filename = net::GenerateFileName( + download_->GetURL(), download_->GetContentDisposition(), referrer_charset, + suggested_filename, sniffed_mime_type, default_filename); + + // We don't replace the file extension if safe browsing consider the file + // extension to be unsafe. Just let safe browsing scan the generated file. + if (safe_browsing::FileTypePolicies::GetInstance()->IsCheckedBinaryFile( + generated_filename)) { + return generated_filename; + } + + // If no mime type or explicitly specified a name, don't replace file + // extension. + if (sniffed_mime_type.empty() || !suggested_filename.empty()) + return generated_filename; + + // Trust content disposition header filename attribute. + net::HttpContentDisposition content_disposition_header( + download_->GetContentDisposition(), referrer_charset); + if (!content_disposition_header.filename().empty()) + return generated_filename; + + // When headers have X-Content-Type-Options:nosniff, or for many text file + // types like csv, sniffed mime type will be text/plain. Prefer the extension + // generated by the URL here. + if (sniffed_mime_type == "text/plain" && + download_->GetOriginalMimeType() != "text/plain") { + return generated_filename; + } + + // Replaces file extension based on sniffed mime type in network layer. + generated_filename = net::GenerateFileName( + download_->GetURL(), std::string() /* content_disposition */, + referrer_charset, std::string() /* suggested_filename */, + sniffed_mime_type, default_filename, true /* should_replace_extension */); + return generated_filename; +} + DownloadTargetDeterminer::Result DownloadTargetDeterminer::DoSetMixedContentStatus() { DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/chrome/browser/download/download_target_determiner.h b/chrome/browser/download/download_target_determiner.h index 7282810..b4727d8 100644 --- a/chrome/browser/download/download_target_determiner.h +++ b/chrome/browser/download/download_target_determiner.h
@@ -324,6 +324,10 @@ safe_browsing::DownloadFileType::DangerLevel GetDangerLevel( PriorVisitsToReferrer visits) const; + // Generates the download file name based on information from URL, response + // headers and sniffed mime type. + base::FilePath GenerateFileName() const; + // download::DownloadItem::Observer void OnDownloadDestroyed(download::DownloadItem* download) override;
diff --git a/chrome/browser/download/download_target_determiner_unittest.cc b/chrome/browser/download/download_target_determiner_unittest.cc index 77cf2e2..4f6bd7d 100644 --- a/chrome/browser/download/download_target_determiner_unittest.cc +++ b/chrome/browser/download/download_target_determiner_unittest.cc
@@ -2167,6 +2167,9 @@ // Return value of DownloadItem::GetSuggestedFilename(). std::string suggested_file_name; + + // Return value of DownloadItem::GetOriginalMimeType(). + std::string original_mime_type; } kTestCases[] = { {{// 0: Unsafe file extension generated by URL should not be replaced // to a safe extension to bypass the safe browsing check. @@ -2175,14 +2178,36 @@ FILE_PATH_LITERAL(""), FILE_PATH_LITERAL("foo.bad"), DownloadItem::TARGET_DISPOSITION_OVERWRITE, EXPECT_UNCONFIRMED}, ""}, - {{// 1: Safe file extension generated by URL can be replaced based on - // mime type. + {{// 1: Generate file extension based on non-text sniffed mime types. AUTOMATIC, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, DownloadFileType::NOT_DANGEROUS, "http://example.com/foo.png", "image/gif", FILE_PATH_LITERAL(""), FILE_PATH_LITERAL("foo.gif"), DownloadItem::TARGET_DISPOSITION_OVERWRITE, EXPECT_CRDOWNLOAD}, ""}, - {{// 2: Forced file path. Mime type from Content-Type should not affect + {{// 2: Generate file extension from URL for text/plain sniffed mime type. + AUTOMATIC, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, + DownloadFileType::NOT_DANGEROUS, "http://example.com/foo.csv", + "text/plain", FILE_PATH_LITERAL(""), FILE_PATH_LITERAL("foo.csv"), + DownloadItem::TARGET_DISPOSITION_OVERWRITE, EXPECT_CRDOWNLOAD}, + ""}, + {{// 3: Sniffed mime type and original mime type are both text/plain. + AUTOMATIC, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, + DownloadFileType::NOT_DANGEROUS, "http://example.com/foo.xml", + "text/plain" /*mime_type*/, FILE_PATH_LITERAL(""), + FILE_PATH_LITERAL("foo.txt"), + DownloadItem::TARGET_DISPOSITION_OVERWRITE, EXPECT_CRDOWNLOAD}, + "", + "text/plain" /*original_mime_type*/}, + {{// 4: Sniffed mime type is text/plain, original mime type is not + // text/plain. Use the URL file extension. + AUTOMATIC, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, + DownloadFileType::NOT_DANGEROUS, "http://example.com/foo.xml", + "text/plain" /*mime_type*/, FILE_PATH_LITERAL(""), + FILE_PATH_LITERAL("foo.xml"), + DownloadItem::TARGET_DISPOSITION_OVERWRITE, EXPECT_CRDOWNLOAD}, + "", + "image/png" /*original_mime_type*/}, + {{// 5: Forced file path. Mime type from Content-Type should not affect // file extension. AUTOMATIC, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, DownloadFileType::NOT_DANGEROUS, "http://example.com/foo.png", @@ -2190,13 +2215,13 @@ FILE_PATH_LITERAL("foo.txt"), DownloadItem::TARGET_DISPOSITION_OVERWRITE, EXPECT_LOCAL_PATH}, ""}, - {{// 3: Empty mime type. + {{// 6: Empty mime type. AUTOMATIC, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, DownloadFileType::NOT_DANGEROUS, "http://example.com/foo.png", "", FILE_PATH_LITERAL(""), FILE_PATH_LITERAL("foo.png"), DownloadItem::TARGET_DISPOSITION_OVERWRITE, EXPECT_CRDOWNLOAD}, ""}, - {{// 4: Suggested file name. Mime type from Content-Type should not affect + {{// 7: Suggested file name. Mime type from Content-Type should not affect // file extension. AUTOMATIC, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, DownloadFileType::NOT_DANGEROUS, "http://example.com/foo.png", @@ -2209,6 +2234,8 @@ CreateActiveDownloadItem(i, kTestCases[i].general); ON_CALL(*item, GetSuggestedFilename()) .WillByDefault(Return(kTestCases[i].suggested_file_name)); + ON_CALL(*item, GetOriginalMimeType()) + .WillByDefault(Return(kTestCases[i].original_mime_type)); RunTestCase(kTestCases[i].general, base::FilePath(), item.get()); } }
diff --git a/chrome/browser/extensions/api/declarative_net_request/rule_indexing_unittest.cc b/chrome/browser/extensions/api/declarative_net_request/rule_indexing_unittest.cc index 0b66240..9e2e5d3 100644 --- a/chrome/browser/extensions/api/declarative_net_request/rule_indexing_unittest.cc +++ b/chrome/browser/extensions/api/declarative_net_request/rule_indexing_unittest.cc
@@ -10,6 +10,7 @@ #include "base/files/file_util.h" #include "base/json/json_reader.h" #include "base/memory/ref_counted.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -40,6 +41,20 @@ const base::FilePath::CharType kJSONRulesetFilepath[] = FILE_PATH_LITERAL("rules_file.json"); +std::string GetParseError(ParseResult result, int rule_id) { + ParseInfo info; + info.SetError(result, &rule_id); + return info.error(); +} + +InstallWarning GetLargeRegexWarning(int rule_id) { + return InstallWarning( + ErrorUtils::FormatErrorMessage( + kErrorRegexTooLarge, base::NumberToString(rule_id), kRegexFilterKey), + manifest_keys::kDeclarativeNetRequestKey, + manifest_keys::kDeclarativeRuleResourcesKey); +} + // Fixure testing that declarative rules corresponding to the Declarative Net // Request API are correctly indexed, for both packed and unpacked // extensions. @@ -185,8 +200,7 @@ rule.condition->excluded_resource_types = std::vector<std::string>({"image"}); AddRule(rule); LoadAndExpectError( - ParseInfo(ParseResult::ERROR_RESOURCE_TYPE_DUPLICATED, *rule.id) - .GetErrorDescription()); + GetParseError(ParseResult::ERROR_RESOURCE_TYPE_DUPLICATED, *rule.id)); } TEST_P(RuleIndexingTest, EmptyRedirectRulePriority) { @@ -196,8 +210,8 @@ rule.action->redirect->url = std::string("https://google.com"); rule.priority.reset(); AddRule(rule); - LoadAndExpectError(ParseInfo(ParseResult::ERROR_EMPTY_RULE_PRIORITY, *rule.id) - .GetErrorDescription()); + LoadAndExpectError( + GetParseError(ParseResult::ERROR_EMPTY_RULE_PRIORITY, *rule.id)); } TEST_P(RuleIndexingTest, EmptyRedirectRuleUrl) { @@ -210,16 +224,16 @@ rule.priority = kMinValidPriority; AddRule(rule); - LoadAndExpectError(ParseInfo(ParseResult::ERROR_INVALID_REDIRECT, *rule.id) - .GetErrorDescription()); + LoadAndExpectError( + GetParseError(ParseResult::ERROR_INVALID_REDIRECT, *rule.id)); } TEST_P(RuleIndexingTest, InvalidRuleID) { TestRule rule = CreateGenericRule(); rule.id = kMinValidID - 1; AddRule(rule); - LoadAndExpectError(ParseInfo(ParseResult::ERROR_INVALID_RULE_ID, *rule.id) - .GetErrorDescription()); + LoadAndExpectError( + GetParseError(ParseResult::ERROR_INVALID_RULE_ID, *rule.id)); } TEST_P(RuleIndexingTest, InvalidRedirectRulePriority) { @@ -230,8 +244,7 @@ rule.priority = kMinValidPriority - 1; AddRule(rule); LoadAndExpectError( - ParseInfo(ParseResult::ERROR_INVALID_RULE_PRIORITY, *rule.id) - .GetErrorDescription()); + GetParseError(ParseResult::ERROR_INVALID_RULE_PRIORITY, *rule.id)); } TEST_P(RuleIndexingTest, NoApplicableResourceTypes) { @@ -242,16 +255,15 @@ "other"}); AddRule(rule); LoadAndExpectError( - ParseInfo(ParseResult::ERROR_NO_APPLICABLE_RESOURCE_TYPES, *rule.id) - .GetErrorDescription()); + GetParseError(ParseResult::ERROR_NO_APPLICABLE_RESOURCE_TYPES, *rule.id)); } TEST_P(RuleIndexingTest, EmptyDomainsList) { TestRule rule = CreateGenericRule(); rule.condition->domains = std::vector<std::string>(); AddRule(rule); - LoadAndExpectError(ParseInfo(ParseResult::ERROR_EMPTY_DOMAINS_LIST, *rule.id) - .GetErrorDescription()); + LoadAndExpectError( + GetParseError(ParseResult::ERROR_EMPTY_DOMAINS_LIST, *rule.id)); } TEST_P(RuleIndexingTest, EmptyResourceTypeList) { @@ -259,16 +271,15 @@ rule.condition->resource_types = std::vector<std::string>(); AddRule(rule); LoadAndExpectError( - ParseInfo(ParseResult::ERROR_EMPTY_RESOURCE_TYPES_LIST, *rule.id) - .GetErrorDescription()); + GetParseError(ParseResult::ERROR_EMPTY_RESOURCE_TYPES_LIST, *rule.id)); } TEST_P(RuleIndexingTest, EmptyURLFilter) { TestRule rule = CreateGenericRule(); rule.condition->url_filter = std::string(); AddRule(rule); - LoadAndExpectError(ParseInfo(ParseResult::ERROR_EMPTY_URL_FILTER, *rule.id) - .GetErrorDescription()); + LoadAndExpectError( + GetParseError(ParseResult::ERROR_EMPTY_URL_FILTER, *rule.id)); } TEST_P(RuleIndexingTest, InvalidRedirectURL) { @@ -279,8 +290,7 @@ rule.priority = kMinValidPriority; AddRule(rule); LoadAndExpectError( - ParseInfo(ParseResult::ERROR_INVALID_REDIRECT_URL, *rule.id) - .GetErrorDescription()); + GetParseError(ParseResult::ERROR_INVALID_REDIRECT_URL, *rule.id)); } TEST_P(RuleIndexingTest, ListNotPassed) { @@ -292,8 +302,7 @@ TestRule rule = CreateGenericRule(); AddRule(rule); AddRule(rule); - LoadAndExpectError(ParseInfo(ParseResult::ERROR_DUPLICATE_IDS, *rule.id) - .GetErrorDescription()); + LoadAndExpectError(GetParseError(ParseResult::ERROR_DUPLICATE_IDS, *rule.id)); } // Ensure that we limit the number of parse failure warnings shown. @@ -493,6 +502,64 @@ } } +// Ensure that regex rules which exceed the per rule memory limit are ignored +// and raise an install warning. +TEST_P(RuleIndexingTest, LargeRegexIgnored) { + TestRule rule = CreateGenericRule(); + rule.condition->url_filter.reset(); + int id = kMinValidID; + + const int kNumSmallRegex = 5; + std::string small_regex = "http://(yahoo|google)\\.com"; + for (int i = 0; i < kNumSmallRegex; i++, id++) { + rule.id = id; + rule.condition->regex_filter = small_regex; + AddRule(rule); + } + + const int kNumLargeRegex = 2; + std::string large_regex = ".{512}x"; + for (int i = 0; i < kNumLargeRegex; i++, id++) { + rule.id = id; + rule.condition->regex_filter = large_regex; + AddRule(rule); + } + + extension_loader()->set_ignore_manifest_warnings(true); + LoadAndExpectSuccess(kNumSmallRegex); + + // TODO(crbug.com/879355): CrxInstaller reloads the extension after moving it, + // which causes it to lose the install warning. This should be fixed. + if (GetParam() != ExtensionLoadType::PACKED) { + InstallWarning warning_1 = GetLargeRegexWarning(kMinValidID + 5); + InstallWarning warning_2 = GetLargeRegexWarning(kMinValidID + 6); + EXPECT_THAT( + extension()->install_warnings(), + ::testing::UnorderedElementsAre(::testing::Eq(std::cref(warning_1)), + ::testing::Eq(std::cref(warning_2)))); + } +} + +// Test an extension with both an error and an install warning. +TEST_P(RuleIndexingTest, WarningAndError) { + // Add a large regex rule which will exceed the per rule memory limit and + // cause an install warning. + TestRule rule = CreateGenericRule(); + rule.condition->url_filter.reset(); + rule.id = kMinValidID; + rule.condition->regex_filter = ".{512}x"; + AddRule(rule); + + // Add a regex rule with a syntax error. + rule.condition->regex_filter = "abc("; + rule.id = kMinValidID + 1; + AddRule(rule); + + extension_loader()->set_ignore_manifest_warnings(true); + LoadAndExpectError( + GetParseError(ParseResult::ERROR_INVALID_REGEX_FILTER, kMinValidID + 1)); +} + TEST_P(RuleIndexingTest, InvalidJSONFile) { set_persist_invalid_json_file(); // The error is returned by the JSON parser we use. Hence just test an error
diff --git a/chrome/browser/extensions/api/identity/identity_api.h b/chrome/browser/extensions/api/identity/identity_api.h index 5b8ff1b..f991b7a 100644 --- a/chrome/browser/extensions/api/identity/identity_api.h +++ b/chrome/browser/extensions/api/identity/identity_api.h
@@ -28,7 +28,6 @@ #include "chrome/browser/extensions/api/identity/identity_mint_queue.h" #include "chrome/browser/extensions/api/identity/identity_remove_cached_auth_token_function.h" #include "chrome/browser/extensions/api/identity/web_auth_flow.h" -#include "chrome/browser/extensions/chrome_extension_function.h" #include "components/signin/public/base/signin_buildflags.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "extensions/browser/browser_context_keyed_api_factory.h"
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc index 0213e2a..69ae281 100644 --- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc +++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
@@ -89,13 +89,12 @@ this); } -bool IdentityGetAuthTokenFunction::RunAsync() { +ExtensionFunction::ResponseAction IdentityGetAuthTokenFunction::Run() { TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("identity", "IdentityGetAuthTokenFunction", this, "extension", extension()->id()); if (GetProfile()->IsOffTheRecord()) { - error_ = identity_constants::kOffTheRecord; - return false; + return RespondNow(Error(identity_constants::kOffTheRecord)); } std::unique_ptr<api::identity::GetAuthToken::Params> params( @@ -114,8 +113,7 @@ // Check that the necessary information is present in the manifest. oauth2_client_id_ = GetOAuth2ClientId(); if (oauth2_client_id_.empty()) { - error_ = identity_constants::kInvalidClientId; - return false; + return RespondNow(Error(identity_constants::kInvalidClientId)); } std::set<std::string> scopes(oauth2_info.scopes.begin(), @@ -133,8 +131,7 @@ } if (scopes.empty()) { - error_ = identity_constants::kInvalidScopes; - return false; + return RespondNow(Error(identity_constants::kInvalidScopes)); } token_key_.scopes = scopes; @@ -159,7 +156,7 @@ weak_ptr_factory_.GetWeakPtr(), gaia_id)); } - return true; + return RespondLater(); } void IdentityGetAuthTokenFunction::GetAuthTokenForPrimaryAccount( @@ -282,25 +279,23 @@ &IdentityGetAuthTokenFunction::OnIdentityAPIShutdown, this)); } -void IdentityGetAuthTokenFunction::CompleteAsyncRun(bool success) { +void IdentityGetAuthTokenFunction::CompleteAsyncRun(ResponseValue response) { identity_api_shutdown_subscription_.reset(); - SendResponse(success); + Respond(std::move(response)); Release(); // Balanced in StartAsyncRun } void IdentityGetAuthTokenFunction::CompleteFunctionWithResult( const std::string& access_token) { - SetResult(std::make_unique<base::Value>(access_token)); - CompleteAsyncRun(true); + CompleteAsyncRun(OneArgument(std::make_unique<base::Value>(access_token))); } void IdentityGetAuthTokenFunction::CompleteFunctionWithError( const std::string& error) { TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("identity", "CompleteFunctionWithError", this, "error", error); - error_ = error; - CompleteAsyncRun(false); + CompleteAsyncRun(Error(error)); } bool IdentityGetAuthTokenFunction::ShouldStartSigninFlow() { @@ -940,4 +935,8 @@ ->AreExtensionsRestrictedToPrimaryAccount(); } +Profile* IdentityGetAuthTokenFunction::GetProfile() const { + return Profile::FromBrowserContext(browser_context()); +} + } // namespace extensions
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h index c7509cf..77dae78 100644 --- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h +++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h
@@ -15,8 +15,8 @@ #include "chrome/browser/extensions/api/identity/gaia_remote_consent_flow.h" #include "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h" #include "chrome/browser/extensions/api/identity/identity_mint_queue.h" -#include "chrome/browser/extensions/chrome_extension_function.h" #include "components/signin/public/identity_manager/identity_manager.h" +#include "extensions/browser/extension_function.h" #include "extensions/browser/extension_function_histogram_value.h" #include "google_apis/gaia/google_service_auth_error.h" #include "google_apis/gaia/oauth2_access_token_manager.h" @@ -46,7 +46,7 @@ // profile will be signed in already, but if it turns out we need a // new login token, there is a sign-in flow. If that flow completes // successfully, getAuthToken proceeds to the non-interactive flow. -class IdentityGetAuthTokenFunction : public ChromeAsyncExtensionFunction, +class IdentityGetAuthTokenFunction : public ExtensionFunction, public GaiaWebAuthFlow::Delegate, public GaiaRemoteConsentFlow::Delegate, public IdentityMintRequestQueue::Request, @@ -114,6 +114,8 @@ // Exposed for testing. virtual std::unique_ptr<OAuth2MintTokenFlow> CreateMintTokenFlow(); + Profile* GetProfile() const; + // Pending request for an access token from the device account (via // DeviceOAuth2TokenService). std::unique_ptr<OAuth2AccessTokenManager::Request> @@ -154,11 +156,11 @@ const CoreAccountInfo& primary_account_info) override; // ExtensionFunction: - bool RunAsync() override; + ResponseAction Run() override; // Helpers to report async function results to the caller. void StartAsyncRun(); - void CompleteAsyncRun(bool success); + void CompleteAsyncRun(ResponseValue response); void CompleteFunctionWithResult(const std::string& access_token); void CompleteFunctionWithError(const std::string& error);
diff --git a/chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.cc b/chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.cc index 32853d9..a2898874 100644 --- a/chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.cc +++ b/chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.cc
@@ -27,10 +27,10 @@ auth_flow_.release()->DetachDelegateAndDelete(); } -bool IdentityLaunchWebAuthFlowFunction::RunAsync() { - if (GetProfile()->IsOffTheRecord()) { - error_ = identity_constants::kOffTheRecord; - return false; +ExtensionFunction::ResponseAction IdentityLaunchWebAuthFlowFunction::Run() { + Profile* profile = Profile::FromBrowserContext(browser_context()); + if (profile->IsOffTheRecord()) { + return RespondNow(Error(identity_constants::kOffTheRecord)); } std::unique_ptr<api::identity::LaunchWebAuthFlow::Params> params( @@ -48,9 +48,9 @@ AddRef(); // Balanced in OnAuthFlowSuccess/Failure. - auth_flow_.reset(new WebAuthFlow(this, GetProfile(), auth_url, mode)); + auth_flow_.reset(new WebAuthFlow(this, profile, auth_url, mode)); auth_flow_->Start(); - return true; + return RespondLater(); } void IdentityLaunchWebAuthFlowFunction::InitFinalRedirectURLPrefixForTest( @@ -68,32 +68,32 @@ void IdentityLaunchWebAuthFlowFunction::OnAuthFlowFailure( WebAuthFlow::Failure failure) { + std::string error; switch (failure) { case WebAuthFlow::WINDOW_CLOSED: - error_ = identity_constants::kUserRejected; + error = identity_constants::kUserRejected; break; case WebAuthFlow::INTERACTION_REQUIRED: - error_ = identity_constants::kInteractionRequired; + error = identity_constants::kInteractionRequired; break; case WebAuthFlow::LOAD_FAILED: - error_ = identity_constants::kPageLoadFailure; + error = identity_constants::kPageLoadFailure; break; default: NOTREACHED() << "Unexpected error from web auth flow: " << failure; - error_ = identity_constants::kInvalidRedirect; + error = identity_constants::kInvalidRedirect; break; } - SendResponse(false); + Respond(Error(error)); if (auth_flow_) auth_flow_.release()->DetachDelegateAndDelete(); - Release(); // Balanced in RunAsync. + Release(); // Balanced in Run. } void IdentityLaunchWebAuthFlowFunction::OnAuthFlowURLChange( const GURL& redirect_url) { if (redirect_url.GetWithEmptyPath() == final_url_prefix_) { - SetResult(std::make_unique<base::Value>(redirect_url.spec())); - SendResponse(true); + Respond(OneArgument(std::make_unique<base::Value>(redirect_url.spec()))); if (auth_flow_) auth_flow_.release()->DetachDelegateAndDelete(); Release(); // Balanced in RunAsync.
diff --git a/chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.h b/chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.h index e40e5b126..f15067e 100644 --- a/chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.h +++ b/chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.h
@@ -8,12 +8,12 @@ #include <string> #include "chrome/browser/extensions/api/identity/web_auth_flow.h" -#include "chrome/browser/extensions/chrome_extension_function.h" +#include "extensions/browser/extension_function.h" #include "extensions/browser/extension_function_histogram_value.h" namespace extensions { -class IdentityLaunchWebAuthFlowFunction : public ChromeAsyncExtensionFunction, +class IdentityLaunchWebAuthFlowFunction : public ExtensionFunction, public WebAuthFlow::Delegate { public: DECLARE_EXTENSION_FUNCTION("identity.launchWebAuthFlow", @@ -26,7 +26,7 @@ private: ~IdentityLaunchWebAuthFlowFunction() override; - bool RunAsync() override; + ResponseAction Run() override; // WebAuthFlow::Delegate implementation. void OnAuthFlowFailure(WebAuthFlow::Failure failure) override;
diff --git a/chrome/browser/gpu/chrome_browser_main_extra_parts_gpu.cc b/chrome/browser/gpu/chrome_browser_main_extra_parts_gpu.cc new file mode 100644 index 0000000..f08847a --- /dev/null +++ b/chrome/browser/gpu/chrome_browser_main_extra_parts_gpu.cc
@@ -0,0 +1,49 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/gpu/chrome_browser_main_extra_parts_gpu.h" + +#include "base/logging.h" +#include "chrome/browser/metrics/chrome_metrics_service_accessor.h" +#include "components/viz/common/features.h" +#include "content/public/browser/gpu_data_manager.h" +#include "gpu/config/gpu_info.h" + +namespace { +const char kTrialName[] = "SkiaBackend"; +const char kGL[] = "GL"; +const char kVulkan[] = "Vulkan"; +} // namespace + +ChromeBrowserMainExtraPartsGpu::ChromeBrowserMainExtraPartsGpu() = default; + +ChromeBrowserMainExtraPartsGpu::~ChromeBrowserMainExtraPartsGpu() { + if (features::IsUsingSkiaRenderer()) + content::GpuDataManager::GetInstance()->RemoveObserver(this); +} + +void ChromeBrowserMainExtraPartsGpu::PostEarlyInitialization() { + if (features::IsUsingSkiaRenderer()) + content::GpuDataManager::GetInstance()->AddObserver(this); +} + +void ChromeBrowserMainExtraPartsGpu::OnGpuInfoUpdate() { + DCHECK(features::IsUsingSkiaRenderer()); + const auto* backend_name = GetSkiaBackendName(); + if (backend_name) { + ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial( + kTrialName, GetSkiaBackendName()); + } +} + +const char* ChromeBrowserMainExtraPartsGpu::GetSkiaBackendName() const { + auto* manager = content::GpuDataManager::GetInstance(); + if (!manager->IsEssentialGpuInfoAvailable()) + return nullptr; + if (manager->GetFeatureStatus(gpu::GpuFeatureType::GPU_FEATURE_TYPE_VULKAN) == + gpu::GpuFeatureStatus::kGpuFeatureStatusEnabled) { + return kVulkan; + } + return kGL; +}
diff --git a/chrome/browser/gpu/chrome_browser_main_extra_parts_gpu.h b/chrome/browser/gpu/chrome_browser_main_extra_parts_gpu.h new file mode 100644 index 0000000..0457ed8 --- /dev/null +++ b/chrome/browser/gpu/chrome_browser_main_extra_parts_gpu.h
@@ -0,0 +1,36 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GPU_CHROME_BROWSER_MAIN_EXTRA_PARTS_GPU_H_ +#define CHROME_BROWSER_GPU_CHROME_BROWSER_MAIN_EXTRA_PARTS_GPU_H_ + +#include "chrome/browser/chrome_browser_main_extra_parts.h" +#include "content/public/browser/gpu_data_manager_observer.h" + +namespace content { +class GpuDataManagerObserver; +} + +class ChromeBrowserMainExtraPartsGpu : public ChromeBrowserMainExtraParts, + public content::GpuDataManagerObserver { + public: + ChromeBrowserMainExtraPartsGpu(); + ~ChromeBrowserMainExtraPartsGpu() override; + + ChromeBrowserMainExtraPartsGpu(const ChromeBrowserMainExtraPartsGpu&) = + delete; + ChromeBrowserMainExtraPartsGpu& operator=( + const ChromeBrowserMainExtraPartsGpu&) = delete; + + // ChromeBrowserMainExtraParts: + void PostEarlyInitialization() override; + + // content::GpuDataManagerObserver: + void OnGpuInfoUpdate() override; + + private: + const char* GetSkiaBackendName() const; +}; + +#endif // CHROME_BROWSER_GPU_CHROME_BROWSER_MAIN_EXTRA_PARTS_GPU_H_
diff --git a/chrome/browser/printing/print_preview_dialog_controller.cc b/chrome/browser/printing/print_preview_dialog_controller.cc index 2f84976..84818167 100644 --- a/chrome/browser/printing/print_preview_dialog_controller.cc +++ b/chrome/browser/printing/print_preview_dialog_controller.cc
@@ -39,6 +39,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_ui.h" #include "ui/base/l10n/l10n_util.h" #include "ui/web_dialogs/web_dialog_delegate.h"
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn index 3b8830dd..a693a599 100644 --- a/chrome/browser/resources/settings/BUILD.gn +++ b/chrome/browser/resources/settings/BUILD.gn
@@ -86,7 +86,6 @@ "appearance_page:closure_compile", "autofill_page:closure_compile", "basic_page:closure_compile", - "change_password_page:closure_compile", "clear_browsing_data_dialog:closure_compile", "controls:closure_compile", "downloads_page:closure_compile", @@ -383,7 +382,6 @@ "appearance_page:polymer3_elements", "autofill_page:polymer3_elements", "basic_page:polymer3_elements", - "change_password_page:polymer3_elements", "clear_browsing_data_dialog:polymer3_elements", "controls:polymer3_elements", "downloads_page:polymer3_elements",
diff --git a/chrome/browser/resources/settings/basic_page/BUILD.gn b/chrome/browser/resources/settings/basic_page/BUILD.gn index 6f58f66..593f7fe 100644 --- a/chrome/browser/resources/settings/basic_page/BUILD.gn +++ b/chrome/browser/resources/settings/basic_page/BUILD.gn
@@ -14,12 +14,10 @@ "..:route", "..:router", "..:search_settings", - "../change_password_page:change_password_browser_proxy", "../chrome_cleanup_page:chrome_cleanup_proxy", "../prefs:prefs_behavior", "../settings_page:main_page_behavior", "//ui/webui/resources/js:load_time_data", - "//ui/webui/resources/js:web_ui_listener_behavior", ] externs_list = [ "$externs_path/pending_polymer.js" ] }
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.html b/chrome/browser/resources/settings/basic_page/basic_page.html index dda53db1..83f3e4b 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.html +++ b/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -3,12 +3,10 @@ <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> -<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> <link rel="import" href="../appearance_page/appearance_page.html"> <link rel="import" href="../privacy_page/privacy_page.html"> <link rel="import" href="../safety_check_page/safety_check_page.html"> <link rel="import" href="../autofill_page/autofill_page.html"> -<link rel="import" href="../change_password_page/change_password_page.html"> <link rel="import" href="../controls/settings_idle_load.html"> <link rel="import" href="../on_startup_page/on_startup_page.html"> <link rel="import" href="../people_page/people_page.html"> @@ -109,11 +107,6 @@ </div> </template> </if> - <template is="dom-if" if="[[showChangePassword]]" restamp> - <settings-section section="changePassword"> - <settings-change-password-page></settings-change-password-page> - </settings-section> - </template> <template is="dom-if" if="[[showPage_(pageVisibility.people)]]" restamp> <settings-section page-title="$i18n{peoplePageTitle}" section="people">
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.js b/chrome/browser/resources/settings/basic_page/basic_page.js index e7a5bd9..a762fe6 100644 --- a/chrome/browser/resources/settings/basic_page/basic_page.js +++ b/chrome/browser/resources/settings/basic_page/basic_page.js
@@ -33,7 +33,6 @@ settings.MainPageBehavior, settings.RouteObserverBehavior, PrefsBehavior, - WebUIListenerBehavior, ], properties: { @@ -43,11 +42,6 @@ notify: true, }, - showChangePassword: { - type: Boolean, - value: false, - }, - /** * Dictionary defining page visibility. * @type {!PageVisibility} @@ -122,10 +116,6 @@ /** @override */ attached() { this.currentRoute_ = settings.Router.getInstance().getCurrentRoute(); - - this.addWebUIListener('change-password-visibility', visibility => { - this.showChangePassword = visibility; - }); }, /**
diff --git a/chrome/browser/resources/settings/change_password_page/BUILD.gn b/chrome/browser/resources/settings/change_password_page/BUILD.gn deleted file mode 100644 index 5c77d18..0000000 --- a/chrome/browser/resources/settings/change_password_page/BUILD.gn +++ /dev/null
@@ -1,76 +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. - -import("//third_party/closure_compiler/compile_js.gni") - -js_type_check("closure_compile") { - deps = [ - ":change_password_browser_proxy", - ":change_password_page", - ] -} - -js_library("change_password_browser_proxy") { - deps = [ - "//ui/webui/resources/js:assert", - "//ui/webui/resources/js:cr", - ] -} - -js_library("change_password_page") { - deps = [ - ":change_password_browser_proxy", - "//ui/webui/resources/js:cr", - "//ui/webui/resources/js:load_time_data", - "//ui/webui/resources/js:util", - "//ui/webui/resources/js:web_ui_listener_behavior", - ] - externs_list = [ "$externs_path/settings_private.js" ] -} - -# TODO(crbug.com/1026426): Fix and enable. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":change_password_browser_proxy.m", -# ":change_password_page.m", -# ] -#} - -js_library("change_password_browser_proxy.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/change_password_page/change_password_browser_proxy.m.js" ] - deps = [ - # TODO: Fill those in. - ] - extra_deps = [ ":modulize" ] -} - -js_library("change_password_page.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/change_password_page/change_password_page.m.js" ] - deps = [ - # TODO: Fill those in. - ] - extra_deps = [ ":change_password_page_module" ] -} - -import("//tools/polymer/polymer.gni") - -group("polymer3_elements") { - deps = [ - ":change_password_page_module", - ":modulize", - ] -} - -polymer_modulizer("change_password_page") { - js_file = "change_password_page.js" - html_file = "change_password_page.html" - html_type = "dom-module" -} - -import("//ui/webui/resources/tools/js_modulizer.gni") - -js_modulizer("modulize") { - input_files = [ "change_password_browser_proxy.js" ] -}
diff --git a/chrome/browser/resources/settings/change_password_page/change_password_browser_proxy.html b/chrome/browser/resources/settings/change_password_page/change_password_browser_proxy.html deleted file mode 100644 index 583ede1..0000000 --- a/chrome/browser/resources/settings/change_password_page/change_password_browser_proxy.html +++ /dev/null
@@ -1,3 +0,0 @@ -<link rel="import" href="chrome://resources/html/assert.html"> -<link rel="import" href="chrome://resources/html/cr.html"> -<script src="change_password_browser_proxy.js"></script>
diff --git a/chrome/browser/resources/settings/change_password_page/change_password_browser_proxy.js b/chrome/browser/resources/settings/change_password_page/change_password_browser_proxy.js deleted file mode 100644 index 8d0abdc..0000000 --- a/chrome/browser/resources/settings/change_password_page/change_password_browser_proxy.js +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -cr.define('settings', function() { - /** @interface */ - class ChangePasswordBrowserProxy { - /** Initialize the change password handler.*/ - initializeChangePasswordHandler() {} - - /** - * Initiate the change password process. e.g., for Gmail users, it - * navigates to accounts.google.com; for GSuite users, it navigates to the - * corresponding change password URLs. - */ - changePassword() {} - } - - /** - * @implements {settings.ChangePasswordBrowserProxy} - */ - class ChangePasswordBrowserProxyImpl { - /** @override */ - initializeChangePasswordHandler() { - chrome.send('initializeChangePasswordHandler'); - } - - /** @override */ - changePassword() { - chrome.send('changePassword'); - } - } - - cr.addSingletonGetter(ChangePasswordBrowserProxyImpl); - - // #cr_define_end - return { - ChangePasswordBrowserProxy: ChangePasswordBrowserProxy, - ChangePasswordBrowserProxyImpl: ChangePasswordBrowserProxyImpl, - }; -});
diff --git a/chrome/browser/resources/settings/change_password_page/change_password_page.html b/chrome/browser/resources/settings/change_password_page/change_password_page.html deleted file mode 100644 index f2833f0..0000000 --- a/chrome/browser/resources/settings/change_password_page/change_password_page.html +++ /dev/null
@@ -1,50 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="../settings_shared_css.html"> -<link rel="import" href="change_password_browser_proxy.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> -<link rel="import" href="chrome://resources/cr_elements/icons.html"> -<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> - -<dom-module id="settings-change-password-page"> - <template> - <style include="settings-shared"> - .icon-container { - padding-inline-end: var(--cr-section-padding); - } - - .change-password-icon { - vertical-align: top; - } - - iron-icon[icon='cr:warning'] { - --iron-icon-fill-color: var(--settings-error-color); - } - - .top-aligned-settings-box { - align-items: start; - min-height: 0; - padding: var(--cr-section-vertical-padding) var(--cr-section-padding); - } - </style> - <div class="settings-box first top-aligned-settings-box"> - <div class="icon-container"> - <iron-icon icon="cr:security" - class="change-password-icon"></iron-icon> - </div> - <div class="start"> - <div>$i18n{changePasswordPageTitle}</div> - <div class="secondary"> - $i18n{changePasswordPageDetails} - </div> - </div> - <div class="separator"></div> - <cr-button class="action-button" id="changePassword" - on-click="changePassword_"> - $i18n{changePasswordPageButton} - </cr-button> - </div> - </template> - <script src="change_password_page.js"></script> -</dom-module>
diff --git a/chrome/browser/resources/settings/change_password_page/change_password_page.js b/chrome/browser/resources/settings/change_password_page/change_password_page.js deleted file mode 100644 index 1444757..0000000 --- a/chrome/browser/resources/settings/change_password_page/change_password_page.js +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview - * 'change-password-page' is the settings page containing change password - * settings. - */ -Polymer({ - is: 'settings-change-password-page', - - /** @private */ - changePassword_() { - settings.ChangePasswordBrowserProxyImpl.getInstance().changePassword(); - }, -});
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/os_a11y_page.html b/chrome/browser/resources/settings/chromeos/os_a11y_page/os_a11y_page.html index e7ff0cf..ddac1d0 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/os_a11y_page.html +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/os_a11y_page.html
@@ -68,7 +68,7 @@ <template is="dom-if" route-path="/manageAccessibility/switchAccess"> <settings-subpage associated-control="[[$$('#subpage-trigger')]]" page-title="$i18n{manageSwitchAccessSettings}"> - <settings-switch-access-subpage prefs="{{prefs.settings.a11y}}"> + <settings-switch-access-subpage prefs="{{prefs}}"> </settings-switch-access-subpage> </settings-subpage> </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.html b/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.html index e5da706..af66730 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.html +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.html
@@ -23,9 +23,8 @@ $i18n{assignSelectSwitchLabel} </div> <settings-dropdown-menu label="$i18n{assignSelectSwitchLabel}" - pref="{{prefs.switch_access.select.setting}}" - menu-options="[[switchAssignOptions_]]" - on-settings-control-change="onSelectAssigned_"> + pref="{{prefs.settings.a11y.switch_access.select.setting}}" + menu-options="[[switchAssignOptions_]]"> </settings-dropdown-menu> </div> <div class="settings-box continuation list-item"> @@ -33,9 +32,8 @@ $i18n{assignNextSwitchLabel} </div> <settings-dropdown-menu label="$i18n{assignNextSwitchLabel}" - pref="{{prefs.switch_access.next.setting}}" - menu-options="[[switchAssignOptions_]]" - on-settings-control-change="onNextAssigned_"> + pref="{{prefs.settings.a11y.switch_access.next.setting}}" + menu-options="[[switchAssignOptions_]]"> </settings-dropdown-menu> </div> <div class="settings-box continuation list-item"> @@ -43,26 +41,25 @@ $i18n{assignPreviousSwitchLabel} </div> <settings-dropdown-menu label="$i18n{assignPreviousSwitchLabel}" - pref="{{prefs.switch_access.previous.setting}}" - menu-options="[[switchAssignOptions_]]" - on-settings-control-change="onPreviousAssigned_"> + pref="{{prefs.settings.a11y.switch_access.previous.setting}}" + menu-options="[[switchAssignOptions_]]"> </settings-dropdown-menu> </div> </div> <h2>$i18n{switchAccessAutoScanHeading}</h2> <div class="list-frame"> <settings-toggle-button class="continuation list-item" - pref="{{prefs.switch_access.auto_scan.enabled}}" + pref="{{prefs.settings.a11y.switch_access.auto_scan.enabled}}" label="$i18n{switchAccessAutoScanLabel}"> </settings-toggle-button> <div class="settings-box continuation list-item" - hidden$="[[!prefs.switch_access.auto_scan.enabled.value]]"> + hidden$="[[!prefs.settings.a11y.switch_access.auto_scan.enabled.value]]"> <div class="start sub-item settings-box-text" id="scanSpeed" aria-hidden="true"> $i18n{switchAccessAutoScanSpeedLabel} </div> <settings-slider id="scanSpeedSlider" - pref="{{prefs.switch_access.auto_scan.speed_ms}}" + pref="{{prefs.settings.a11y.switch_access.auto_scan.speed_ms}}" ticks="[[autoScanSpeedRangeMs_]]" min="[[minScanSpeedMs_]]" max="[[maxScanSpeedMs_]]" @@ -73,13 +70,13 @@ </div> <div class="settings-box continuation list-item" hidden$="[[!showKeyboardScanSettings_( - prefs.switch_access.auto_scan.enabled.value)]]"> + prefs.settings.a11y.switch_access.auto_scan.enabled.value)]]"> <div class="start sub-item settings-box-text" id="keyboardScanSpeed" aria-hidden="true"> $i18n{switchAccessAutoScanKeyboardSpeedLabel} </div> <settings-slider id="keyboardScanSpeedSlider" - pref="{{prefs.switch_access.auto_scan.keyboard.speed_ms}}" + pref="{{prefs.settings.a11y.switch_access.auto_scan.keyboard.speed_ms}}" ticks="[[autoScanSpeedRangeMs_]]" min="[[minScanSpeedMs_]]" max="[[maxScanSpeedMs_]]"
diff --git a/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.js b/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.js index 2ed7a35..47a0af0a 100644 --- a/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.js +++ b/chrome/browser/resources/settings/chromeos/os_a11y_page/switch_access_subpage.js
@@ -20,6 +20,31 @@ ENTER: 2, }; +/** + * Available commands. + * @const + */ +const SWITCH_ACCESS_COMMANDS = ['next', 'previous', 'select']; + +/** + * The portion of the setting name common to all Switch Access preferences. + * @const + */ +const PREFIX = 'settings.a11y.switch_access.'; + +/** + * The ending of the setting name for all key code preferences. + * @const + */ +const KEY_CODE_SUFFIX = '.key_codes'; + +/** + * The ending of the setting name for all preferences referring to + * Switch Access command settings. + * @const + */ +const COMMAND_SUFFIX = '.setting'; + /** @type {!Array<number>} */ const AUTO_SCAN_SPEED_RANGE_MS = [ 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, @@ -28,6 +53,20 @@ ]; /** + * This function extracts the segment of a preference key after the fixed prefix + * and returns it. In cases where the preference is Switch Access command + * setting preference, it corresponds to the command name. + * + * @param {!chrome.settingsPrivate.PrefObject} pref + * @return {string} + */ +function getCommandNameFromCommandPref(pref) { + const nameStartIndex = PREFIX.length; + const nameEndIndex = pref.key.indexOf('.', nameStartIndex); + return pref.key.substring(nameStartIndex, nameEndIndex); +} + +/** * @param {!Array<number>} ticksInMs * @return {!Array<!cr_slider.SliderTick>} */ @@ -118,12 +157,27 @@ }, }, + /** @override */ + created() { + chrome.settingsPrivate.onPrefsChanged.addListener((prefs) => { + for (const pref of prefs) { + if (!pref.key.includes(PREFIX) || !pref.key.includes(COMMAND_SUFFIX)) { + continue; + } + const commandName = getCommandNameFromCommandPref(pref); + if (SWITCH_ACCESS_COMMANDS.includes(commandName)) { + this.onSwitchAssigned_(pref); + } + } + }); + }, + /** * @return {string} * @private */ currentSpeed_() { - const speed = this.get('prefs.switch_access.auto_scan.speed_ms.value'); + const speed = this.getPref(PREFIX + 'auto_scan.speed_ms').value; if (typeof speed != 'number') { return ''; } @@ -139,43 +193,48 @@ const improvedTextInputEnabled = loadTimeData.getBoolean( 'showExperimentalAccessibilitySwitchAccessImprovedTextInput'); const autoScanEnabled = /** @type {boolean} */ - (this.getPref('switch_access.auto_scan.enabled').value); + (this.getPref(PREFIX + 'auto_scan.enabled').value); return improvedTextInputEnabled && autoScanEnabled; }, - /** - * @param {string} command - */ - onSwitchAssigned_(command) { - const pref = 'prefs.switch_access.' + command; - const keyCodeSuffix = '.key_codes.value'; - const settingSuffix = '.setting.value'; + /** @param {!chrome.settingsPrivate.PrefObject} newPref */ + onSwitchAssigned_(newPref) { + const command = getCommandNameFromCommandPref(newPref); - switch (this.get(pref + settingSuffix)) { + if (newPref.value !== SwitchAccessAssignmentValue.NONE) { + // When setting to a value, enforce that no other command can have that + // value. + for (const val of SWITCH_ACCESS_COMMANDS) { + if (val === command) { + continue; + } + if (this.getPref(PREFIX + val + COMMAND_SUFFIX).value === + newPref.value) { + chrome.settingsPrivate.setPref( + PREFIX + val + COMMAND_SUFFIX, SwitchAccessAssignmentValue.NONE); + } + } + } + + // Because of complexities with mapping a ListPref to a settings-dropdown, + // we instead store two distinct preferences (one for the dropdown selection + // and one with the key codes that Switch Access intercepts). The following + // code sets the key code preference based on the dropdown preference. + switch (newPref.value) { case SwitchAccessAssignmentValue.NONE: - this.set(pref + keyCodeSuffix, []); + chrome.settingsPrivate.setPref(PREFIX + command + KEY_CODE_SUFFIX, []); break; case SwitchAccessAssignmentValue.SPACE: - this.set(pref + keyCodeSuffix, [32]); + chrome.settingsPrivate.setPref( + PREFIX + command + KEY_CODE_SUFFIX, [32]); break; case SwitchAccessAssignmentValue.ENTER: - this.set(pref + keyCodeSuffix, [13]); + chrome.settingsPrivate.setPref( + PREFIX + command + KEY_CODE_SUFFIX, [13]); break; } }, - onNextAssigned_() { - this.onSwitchAssigned_('next'); - }, - - onPreviousAssigned_() { - this.onSwitchAssigned_('previous'); - }, - - onSelectAssigned_() { - this.onSwitchAssigned_('select'); - }, - /** * @param {number} scanSpeedValueMs * @return {string} a string representing the scan speed in seconds.
diff --git a/chrome/browser/resources/settings/languages_page/BUILD.gn b/chrome/browser/resources/settings/languages_page/BUILD.gn index 403c786..d1bb13a 100644 --- a/chrome/browser/resources/settings/languages_page/BUILD.gn +++ b/chrome/browser/resources/settings/languages_page/BUILD.gn
@@ -17,6 +17,7 @@ js_library("edit_dictionary_page") { deps = [ + ":languages_browser_proxy", "..:global_scroll_target_behavior", "..:route", "../prefs",
diff --git a/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html b/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html index 662c42c1..d3e193e3 100644 --- a/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html +++ b/chrome/browser/resources/settings/languages_page/edit_dictionary_page.html
@@ -12,6 +12,7 @@ <link rel="import" href="../route.html"> <link rel="import" href="../settings_shared_css.html"> <link rel="import" href="../settings_vars_css.html"> +<link rel="import" href="./languages_browser_proxy.html"> <dom-module id="settings-edit-dictionary-page"> <template>
diff --git a/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js b/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js index 0a6c4e96..c40712e 100644 --- a/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js +++ b/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js
@@ -47,21 +47,21 @@ }, }, - /** @type {LanguageSettingsPrivate} */ - languageSettingsPrivate: null, + /** @private {LanguageSettingsPrivate} */ + languageSettingsPrivate_: null, /** @override */ ready() { - this.languageSettingsPrivate = settings.languageSettingsPrivateApiForTest || - /** @type {!LanguageSettingsPrivate} */ - (chrome.languageSettingsPrivate); + this.languageSettingsPrivate_ = + settings.LanguagesBrowserProxyImpl.getInstance() + .getLanguageSettingsPrivate(); - this.languageSettingsPrivate.getSpellcheckWords(words => { + this.languageSettingsPrivate_.getSpellcheckWords(words => { this.hasWords_ = words.length > 0; this.words_ = words; }); - this.languageSettingsPrivate.onCustomDictionaryChanged.addListener( + this.languageSettingsPrivate_.onCustomDictionaryChanged.addListener( this.onCustomDictionaryChanged_.bind(this)); // Add a key handler for the new-word input. @@ -77,7 +77,7 @@ const word = this.getTrimmedNewWord_(); this.newWordValue_ = ''; if (word) { - this.languageSettingsPrivate.addSpellcheckWord(word); + this.languageSettingsPrivate_.addSpellcheckWord(word); } }, @@ -204,6 +204,6 @@ * @param {!{model: !{item: string}}} e */ onRemoveWordTap_(e) { - this.languageSettingsPrivate.removeSpellcheckWord(e.model.item); + this.languageSettingsPrivate_.removeSpellcheckWord(e.model.item); }, });
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index 5080402..10cf993 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -270,20 +270,6 @@ <structure name="IDR_SETTINGS_GLOBAL_SCROLL_TARGET_BEHAVIOR_JS" file="global_scroll_target_behavior.js" type="chrome_html" /> - <structure name="IDR_SETTINGS_CHANGE_PASSWORD_BROWSER_PROXY_HTML" - file="change_password_page/change_password_browser_proxy.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_CHANGE_PASSWORD_BROWSER_PROXY_JS" - file="change_password_page/change_password_browser_proxy.js" - type="chrome_html" /> - <structure name="IDR_SETTINGS_CHANGE_PASSWORD_PAGE_HTML" - file="change_password_page/change_password_page.html" - type="chrome_html" - preprocess="true" /> - <structure name="IDR_SETTINGS_CHANGE_PASSWORD_PAGE_JS" - file="change_password_page/change_password_page.js" - type="chrome_html" - preprocess="true" /> <if expr="is_win"> <structure name="IDR_SETTINGS_CHROME_CLEANUP_PROXY_HTML" file="chrome_cleanup_page/chrome_cleanup_proxy.html"
diff --git a/chrome/browser/resources/tab_strip/tab_group.html b/chrome/browser/resources/tab_strip/tab_group.html index 71c46d6d..72df836 100644 --- a/chrome/browser/resources/tab_strip/tab_group.html +++ b/chrome/browser/resources/tab_strip/tab_group.html
@@ -72,10 +72,14 @@ --drag-image-padding: 25px; padding: var(--drag-image-padding); transform: translate( - calc(-1 * var(--drag-image-padding)), + calc(var(--drag-image-x-direction, -1) * var(--drag-image-padding)), calc(-1 * var(--drag-image-padding))); } +:host-context([dir='rtl']):host([getting-drag-image_]) #dragImage { + --drag-image-x-direction: 1; +} + :host([getting-drag-image_]) #tabGroup { background: var(--tabstrip-background-color); border-radius: var(--tabstrip-tab-border-radius);
diff --git a/chrome/browser/resources/tab_strip/tab_list.js b/chrome/browser/resources/tab_strip/tab_list.js index c5f36b1..3b51d8650 100644 --- a/chrome/browser/resources/tab_strip/tab_list.js +++ b/chrome/browser/resources/tab_strip/tab_list.js
@@ -285,6 +285,9 @@ 'tab-group-visuals-changed', (groupId, visualData) => this.onTabGroupVisualsChanged_(groupId, visualData)); + this.addWebUIListener_( + 'tab-group-id-replaced', + (oldId, newId) => this.onTabGroupIdReplaced_(oldId, newId)); }); } @@ -502,6 +505,18 @@ } /** + * @param {string} oldId + * @param {string} newId + * @private + */ + onTabGroupIdReplaced_(oldId, newId) { + const tabGroupElement = this.findTabGroupElement_(oldId); + if (tabGroupElement) { + tabGroupElement.dataset.groupId = newId; + } + } + + /** * @param {number} tabId * @param {number} index * @param {string} groupId
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc index 13e80d05..5267505 100644 --- a/chrome/browser/ssl/ssl_browsertest.cc +++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -7453,6 +7453,30 @@ EXPECT_EQ(security_interstitials::CMD_TEXT_FOUND, result); } +// Tests that the legacy TLS control config applies to subdomains if the +// registrable domain is in the control config. +IN_PROC_BROWSER_TEST_F(LegacyTLSInterstitialTest, + ControlConfigIncludesSubdomains) { + InitializeLegacyTLSConfigWithControl(); + base::RunLoop run_loop; + InitializeLegacyTLSConfigWithControlNetworkService(&run_loop); + + SetTLSVersion(net::SSL_PROTOCOL_VERSION_TLS1); + ASSERT_TRUE(https_server()->Start()); + + base::HistogramTester histograms; + + ui_test_utils::NavigateToURL( + browser(), https_server()->GetURL(std::string("www.") + kLegacyTLSHost, + "/ssl/google.html")); + auto* tab = browser()->tab_strip_model()->GetActiveWebContents(); + EXPECT_FALSE( + chrome_browser_interstitials::IsShowingLegacyTLSInterstitial(tab)); + + // Interstitial metrics should not have been recorded from this navigation. + histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 0); +} + // 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.
diff --git a/chrome/browser/subresource_redirect/subresource_redirect_observer.cc b/chrome/browser/subresource_redirect/subresource_redirect_observer.cc index a5236355..387f546 100644 --- a/chrome/browser/subresource_redirect/subresource_redirect_observer.cc +++ b/chrome/browser/subresource_redirect/subresource_redirect_observer.cc
@@ -118,7 +118,9 @@ content::NavigationHandle* navigation_handle) { DCHECK(navigation_handle); if (!navigation_handle->IsInMainFrame() || - navigation_handle->IsSameDocument()) { + !navigation_handle->HasCommitted() || + navigation_handle->IsSameDocument() || + !navigation_handle->GetURL().SchemeIsHTTPOrHTTPS()) { return; } auto* optimization_guide_decider = GetOptimizationGuideDeciderFromWebContents(
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 0279db5..80adc5a0 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1341,8 +1341,6 @@ "webui/settings/appearance_handler.h", "webui/settings/browser_lifetime_handler.cc", "webui/settings/browser_lifetime_handler.h", - "webui/settings/change_password_handler.cc", - "webui/settings/change_password_handler.h", "webui/settings/custom_home_pages_table_model.cc", "webui/settings/custom_home_pages_table_model.h", "webui/settings/downloads_handler.cc",
diff --git a/chrome/browser/ui/app_list/search/app_search_provider.cc b/chrome/browser/ui/app_list/search/app_search_provider.cc index 2ba8410..209fc2c6 100644 --- a/chrome/browser/ui/app_list/search/app_search_provider.cc +++ b/chrome/browser/ui/app_list/search/app_search_provider.cc
@@ -18,9 +18,12 @@ #include "ash/public/cpp/app_list/internal_app_id_constants.h" #include "base/bind.h" #include "base/callback_list.h" +#include "base/containers/flat_set.h" +#include "base/i18n/rtl.h" #include "base/macros.h" #include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_macros.h" +#include "base/no_destructor.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/clock.h" @@ -55,6 +58,13 @@ // is somewhat arbitrary, but is roughly equivalent to the 'ter' in 'terminal'. constexpr double kCrostiniTerminalRelevanceThreshold = 0.8; +// Parameters for FuzzyTokenizedStringMatch. +constexpr bool kUsePrefixOnly = false; +constexpr bool kUseWeightedRatio = true; +constexpr bool kUseEditDistance = false; +constexpr double kRelevanceThreshold = 0.3; +constexpr double kPartialMatchPenaltyRate = 0.9; + // Adds |app_result| to |results| only in case no duplicate apps were already // added. Duplicate means the same app but for different domain, Chrome and // Android. @@ -98,6 +108,19 @@ return min + score * (max - min); } +// Checks if current locale is non Latin locales. +bool IsNonLatinLocale(const std::string& locale) { + // A set of of non Latin locales. This set is used to select appropriate + // algorithm for app search. + static const base::NoDestructor<base::flat_set<std::string>> + non_latin_locales({"am", "ar", "be", "bg", "bn", "el", "fa", + "gu", "hi", "hy", "iw", "ja", "ka", "kk", + "km", "kn", "ko", "ky", "lo", "mk", "ml", + "mn", "mr", "my", "pa", "ru", "sr", "ta", + "te", "th", "uk", "zh-CN", "zh-HK", "zh-TW"}); + return base::Contains(*non_latin_locales, locale); +} + } // namespace namespace app_list { @@ -147,7 +170,7 @@ return base::Time(); } - bool MatchSearchableText(const TokenizedString& query) { + bool MatchSearchableText(const TokenizedString& query, bool use_exact_match) { if (searchable_text_.empty()) return false; if (tokenized_indexed_searchable_text_.empty()) { @@ -156,11 +179,23 @@ std::make_unique<TokenizedString>(curr_text)); } } - TokenizedStringMatch match; - for (auto& curr_text : tokenized_indexed_searchable_text_) { - match.Calculate(query, *curr_text); - if (match.relevance() > relevance_threshold()) - return true; + if (use_exact_match) { + TokenizedStringMatch match; + for (auto& curr_text : tokenized_indexed_searchable_text_) { + match.Calculate(query, *curr_text); + if (match.relevance() > relevance_threshold()) + return true; + } + } else { + FuzzyTokenizedStringMatch match; + for (auto& curr_text : tokenized_indexed_searchable_text_) { + if (match.IsRelevant(query, *curr_text, kRelevanceThreshold, + kUsePrefixOnly, kUseWeightedRatio, + kUseEditDistance, kPartialMatchPenaltyRate) && + match.relevance() >= relevance_threshold()) { + return true; + } + } } return false; } @@ -500,22 +535,27 @@ new_results.reserve(apps_size); const TokenizedString query_terms(query_); + const bool use_exact_match = + (!app_list_features::IsFuzzyAppSearchEnabled()) || + (app_list_features::IsExactMatchForNonLatinLocaleEnabled() && + IsNonLatinLocale(base::i18n::GetConfiguredLocale())); + for (auto& app : apps_) { if (!app->searchable()) continue; TokenizedString* indexed_name = app->GetTokenizedIndexedName(); - if (!app_list_features::IsFuzzyAppSearchEnabled()) { + if (use_exact_match) { TokenizedStringMatch match; if (match.Calculate(query_terms, *indexed_name)) { // Exact matches should be shown even if the threshold isn't reached, // e.g. due to a localized name being particularly short. if (match.relevance() <= app->relevance_threshold() && !base::EqualsCaseInsensitiveASCII(query_, app->name()) && - !app->MatchSearchableText(query_terms)) { + !app->MatchSearchableText(query_terms, use_exact_match)) { continue; } - } else if (!app->MatchSearchableText(query_terms)) { + } else if (!app->MatchSearchableText(query_terms, use_exact_match)) { continue; } std::unique_ptr<AppResult> result = @@ -524,28 +564,10 @@ MaybeAddResult(&new_results, std::move(result), &seen_or_filtered_apps); } else { FuzzyTokenizedStringMatch match; - - // TODO(crbug.com/1018613): consolidate finch parameters. - const bool use_prefix_only = base::GetFieldTrialParamByFeatureAsBool( - app_list_features::kEnableFuzzyAppSearch, "use_prefix_only", false); - const bool use_weighted_ratio = base::GetFieldTrialParamByFeatureAsBool( - app_list_features::kEnableFuzzyAppSearch, "use_weighted_ratio", true); - const bool use_edit_distance = base::GetFieldTrialParamByFeatureAsBool( - app_list_features::kEnableFuzzyAppSearch, "use_edit_distance", false); - - const double relevance_threshold = - base::GetFieldTrialParamByFeatureAsDouble( - app_list_features::kEnableFuzzyAppSearch, "relevance_threshold", - 0.3); - const double partial_match_penalty_rate = - base::GetFieldTrialParamByFeatureAsDouble( - app_list_features::kEnableFuzzyAppSearch, - "partial_match_penalty_rate", 0.9); - - if (match.IsRelevant(query_terms, *indexed_name, relevance_threshold, - use_prefix_only, use_weighted_ratio, - use_edit_distance, partial_match_penalty_rate) || - app->MatchSearchableText(query_terms) || + if (match.IsRelevant(query_terms, *indexed_name, kRelevanceThreshold, + kUsePrefixOnly, kUseWeightedRatio, kUseEditDistance, + kPartialMatchPenaltyRate) || + app->MatchSearchableText(query_terms, use_exact_match) || base::EqualsCaseInsensitiveASCII(query_, app->name())) { std::unique_ptr<AppResult> result = app->data_source()->CreateResult( app->id(), list_controller_, false);
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h index 0fb30fc..50d4e18 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h +++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h
@@ -80,6 +80,10 @@ // after a target or condition is deleted. void SaveToDisk(); + // Returns true if the model has been loaded from disk and is ready to use. + // Train and rank do nothing when this is false. + bool is_initialized() { return load_from_disk_completed_; } + // Return a pointer to the underlying storage of the FrecencyStore for targets // or conditions. These should not be used under normal use or ranking. // However, they are useful for custom cleanup logic.
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.cc b/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.cc index f0b324d..daa34e7 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.cc +++ b/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.cc
@@ -11,6 +11,7 @@ #include "ash/public/cpp/app_list/app_list_features.h" #include "ash/public/cpp/app_list/app_list_types.h" +#include "base/feature_list.h" #include "base/macros.h" #include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_macros.h" @@ -20,6 +21,7 @@ #include "base/task/post_task.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" +#include "chrome/browser/chromeos/extensions/default_web_app_ids.h" #include "chrome/browser/chromeos/file_manager/file_tasks_notifier.h" #include "chrome/browser/chromeos/file_manager/file_tasks_notifier_factory.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" @@ -32,6 +34,8 @@ #include "chrome/browser/ui/app_list/search/search_result_ranker/histogram_util.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h" +#include "chromeos/constants/chromeos_features.h" +#include "extensions/common/constants.h" #include "url/gurl.h" namespace app_list { @@ -338,8 +342,24 @@ query_based_mixed_types_ranker_->Rank(base::UTF16ToUTF8(query)); } - if (app_ranker_) + if (app_ranker_) { + // The Help app is being replaced with the Discover app, and we want to keep + // ranking consistent by swapping the app IDs. The rename is a no-op if the + // Help app ID doesn't exist, so it's safe to do it several times. + // Unfortunately we can't do this on initialization though, as the model + // won't have been loaded from disk. Instead, do it on the first rank. + // TODO(1052154): Remove this special case after M84, to give all devices + // time to swap IDs. + if (app_ranker_->is_initialized() && !have_renamed_help_app_ && + base::FeatureList::IsEnabled(chromeos::features::kHelpAppV2)) { + app_ranker_->RenameTarget(extension_misc::kGeniusAppId, + chromeos::default_web_apps::kHelpAppId); + app_ranker_->SaveToDisk(); + have_renamed_help_app_ = true; + } + app_ranks_ = app_ranker_->Rank(); + } } void SearchResultRanker::Rank(Mixer::SortedResults* results) {
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.h b/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.h index cbbdb3d..585b3ad 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.h +++ b/chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.h
@@ -167,6 +167,7 @@ // Ranks apps. std::unique_ptr<RecurrenceRanker> app_ranker_; std::map<std::string, float> app_ranks_; + bool have_renamed_help_app_ = false; // Testing-only closure to inform tests once a JSON config has been parsed. base::OnceClosure json_config_parsed_for_testing_;
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc index ab46f121..4165256 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
@@ -2254,8 +2254,7 @@ // Verify that the in-app shelf should be shown when the app icon receives // the accessibility focus. -// https://crbug.com/1020806 flaky. -IN_PROC_BROWSER_TEST_F(HotseatShelfAppBrowserTest, DISABLED_EnableChromeVox) { +IN_PROC_BROWSER_TEST_F(HotseatShelfAppBrowserTest, EnableChromeVox) { ash::Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); chromeos::SpeechMonitor speech_monitor; @@ -2267,13 +2266,12 @@ EXPECT_TRUE(speech_monitor.SkipChromeVoxEnabledMessage()); // Disable earcons (https://crbug.com/396507). - const std::string script( - "cvox.ChromeVox.earcons.playEarcon = function() {};"); + const std::string script("ChromeVox.earcons.playEarcon = function() {};"); extensions::ExtensionHost* host = extensions::ProcessManager::Get(browser()->profile()) ->GetBackgroundHostForExtension( extension_misc::kChromeVoxExtensionId); - CHECK(content::ExecuteScript(host->host_contents(), script)); + ASSERT_TRUE(content::ExecuteScript(host->host_contents(), script)); } ash::RootWindowController* controller = @@ -2291,12 +2289,12 @@ ASSERT_EQ("Tool bar", speech_monitor.GetNextUtterance()); ASSERT_EQ(", window", speech_monitor.GetNextUtterance()); - // Verifies that before moving the focus to the app icon, hotseat is hidden. - ASSERT_EQ(ash::HotseatState::kHidden, + // Hotseat is expected to be extended if spoken feedback is enabled. + ASSERT_EQ(ash::HotseatState::kExtended, controller->shelf()->shelf_layout_manager()->hotseat_state()); // Press the search + right. Expects that the browser icon receives the - // accessibility focus and the hotseat is shown in kExtended state. + // accessibility focus and the hotseat remains in kExtended state. event_generator.PressKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN); const int browser_index = ash::ShelfModel::Get()->GetItemIndexForType(ash::TYPE_BROWSER_SHORTCUT); @@ -2307,9 +2305,11 @@ controller->shelf()->shelf_layout_manager()->hotseat_state()); // Click on the home button. Expects that the hotseat is shown in - // kShownHomeLauncher state + // kShownHomeLauncher state. Note that the home button should be shown in + // tablet mode with spoken feedback enabled. event_generator.MoveMouseTo(home_button->GetBoundsInScreen().CenterPoint()); event_generator.ClickLeftButton(); + EXPECT_EQ(ash::HotseatState::kShownHomeLauncher, controller->shelf()->shelf_layout_manager()->hotseat_state()); }
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 1b77df2..436b503 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -773,7 +773,7 @@ result += "Platform_App"; } else if (app == arc_support_host_->id()) { result += "Play Store"; - } else if (app == crostini::kCrostiniTerminalId) { + } else if (app == crostini::GetTerminalId()) { result += "Terminal"; } else if (app == web_app_->id()) { result += "WebApp";
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc index 06b06c4a..68500f6 100644 --- a/chrome/browser/ui/search/search_tab_helper.cc +++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -656,6 +656,12 @@ autocomplete_input.set_from_omnibox_focus(input.empty()); autocomplete_input.set_prevent_inline_autocomplete( prevent_inline_autocomplete); + + // We do not want keyword matches for the NTP realbox, which has no UI + // facilities to support them. + autocomplete_input.set_prefer_keyword(false); + autocomplete_input.set_allow_exact_keyword_match(false); + autocomplete_controller_->Start(autocomplete_input); }
diff --git a/chrome/browser/ui/views/accessibility/invert_bubble_view.cc b/chrome/browser/ui/views/accessibility/invert_bubble_view.cc index e37e520..64e8061f 100644 --- a/chrome/browser/ui/views/accessibility/invert_bubble_view.cc +++ b/chrome/browser/ui/views/accessibility/invert_bubble_view.cc
@@ -47,9 +47,8 @@ constexpr int kLearnMoreButton = 100; std::unique_ptr<views::View> CreateExtraView(views::ButtonListener* listener) { - auto learn_more = views::CreateVectorImageButton(listener); - views::SetImageFromVectorIcon(learn_more.get(), - vector_icons::kHelpOutlineIcon); + auto learn_more = views::CreateVectorImageButtonWithNativeTheme( + listener, vector_icons::kHelpOutlineIcon); learn_more->SetTooltipText(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); learn_more->set_tag(kLearnMoreButton); return learn_more;
diff --git a/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc b/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc index 55f9969a..f486e18 100644 --- a/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc +++ b/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc
@@ -177,9 +177,7 @@ views::style::CONTEXT_LABEL, ChromeTextStyle::STYLE_RED)); auto delete_card_from_local_button = - views::CreateVectorImageButton(listener); - views::SetImageFromVectorIcon(delete_card_from_local_button.get(), - kTrashCanIcon); + views::CreateVectorImageButtonWithNativeTheme(listener, kTrashCanIcon); delete_card_from_local_button->SetTooltipText(l10n_util::GetStringUTF16( IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TRASH_CAN_BUTTON_TOOLTIP)); delete_card_from_local_button_ =
diff --git a/chrome/browser/ui/views/confirm_bubble_views.cc b/chrome/browser/ui/views/confirm_bubble_views.cc index fb01319..b2a0e3f 100644 --- a/chrome/browser/ui/views/confirm_bubble_views.cc +++ b/chrome/browser/ui/views/confirm_bubble_views.cc
@@ -28,10 +28,10 @@ namespace { std::unique_ptr<views::View> CreateExtraView(views::ButtonListener* listener) { - auto help_button = CreateVectorImageButton(listener); + auto help_button = CreateVectorImageButtonWithNativeTheme( + listener, vector_icons::kHelpOutlineIcon); help_button->SetFocusForPlatform(); help_button->SetTooltipText(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); - SetImageFromVectorIcon(help_button.get(), vector_icons::kHelpOutlineIcon); return help_button; }
diff --git a/chrome/browser/ui/views/device_chooser_content_view.cc b/chrome/browser/ui/views/device_chooser_content_view.cc index dfd5cc57..ac58b50 100644 --- a/chrome/browser/ui/views/device_chooser_content_view.cc +++ b/chrome/browser/ui/views/device_chooser_content_view.cc
@@ -297,9 +297,8 @@ std::unique_ptr<views::View> DeviceChooserContentView::CreateExtraView() { const auto make_help_button = [this]() { - auto help_button = views::CreateVectorImageButton(this); - views::SetImageFromVectorIcon(help_button.get(), - vector_icons::kHelpOutlineIcon); + auto help_button = views::CreateVectorImageButtonWithNativeTheme( + this, vector_icons::kHelpOutlineIcon); help_button->SetFocusForPlatform(); help_button->SetTooltipText(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); help_button->set_tag(kHelpButtonTag);
diff --git a/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc b/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc index 746ca0c..ef6199e 100644 --- a/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc +++ b/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc
@@ -49,6 +49,7 @@ #include "components/feature_engagement/public/event_constants.h" #include "components/feature_engagement/public/feature_constants.h" #include "components/feature_engagement/public/tracker.h" +#include "content/public/browser/web_ui.h" #include "content/public/common/drop_data.h" #include "ui/aura/window.h" #include "ui/base/clipboard/clipboard_format_type.h"
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc index 0605c47e..86998cbd 100644 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc +++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -75,21 +75,18 @@ } }; -class ZoomButton : public views::ImageButton { - public: - explicit ZoomButton(views::ButtonListener* listener, - const gfx::VectorIcon& icon, - int tooltip_id) - : ImageButton(listener) { - views::ConfigureVectorImageButton(this); - views::SetImageFromVectorIcon(this, icon); - SetFocusForPlatform(); - SetTooltipText(l10n_util::GetStringUTF16(tooltip_id)); - views::HighlightPathGenerator::Install( - this, std::make_unique<ZoomButtonHighlightPathGenerator>()); - } - ~ZoomButton() override = default; -}; +std::unique_ptr<views::ImageButton> CreateZoomButton( + views::ButtonListener* listener, + const gfx::VectorIcon& icon, + int tooltip_id) { + auto zoom_button = + views::CreateVectorImageButtonWithNativeTheme(listener, icon); + zoom_button->SetFocusForPlatform(); + zoom_button->SetTooltipText(l10n_util::GetStringUTF16(tooltip_id)); + views::HighlightPathGenerator::Install( + zoom_button.get(), std::make_unique<ZoomButtonHighlightPathGenerator>()); + return zoom_button; +} class ZoomValue : public views::Label { public: @@ -408,13 +405,13 @@ // Add Zoom Out ("-") button. zoom_out_button_ = AddChildView( - std::make_unique<ZoomButton>(this, kRemoveIcon, IDS_ACCNAME_ZOOM_MINUS2)); + CreateZoomButton(this, kRemoveIcon, IDS_ACCNAME_ZOOM_MINUS2)); zoom_out_button_->SetProperty(views::kMarginsKey, gfx::Insets(vector_button_margin)); // Add Zoom In ("+") button. - zoom_in_button_ = AddChildView( - std::make_unique<ZoomButton>(this, kAddIcon, IDS_ACCNAME_ZOOM_PLUS2)); + zoom_in_button_ = + AddChildView(CreateZoomButton(this, kAddIcon, IDS_ACCNAME_ZOOM_PLUS2)); zoom_in_button_->SetProperty(views::kMarginsKey, gfx::Insets(vector_button_margin));
diff --git a/chrome/browser/ui/views/passwords/password_items_view.cc b/chrome/browser/ui/views/passwords/password_items_view.cc index ba8d5e7..e0da42d 100644 --- a/chrome/browser/ui/views/passwords/password_items_view.cc +++ b/chrome/browser/ui/views/passwords/password_items_view.cc
@@ -80,8 +80,7 @@ views::ButtonListener* listener, const base::string16& username) { std::unique_ptr<views::ImageButton> button( - views::CreateVectorImageButton(listener)); - views::SetImageFromVectorIcon(button.get(), kTrashCanIcon); + views::CreateVectorImageButtonWithNativeTheme(listener, kTrashCanIcon)); button->SetFocusForPlatform(); button->SetTooltipText( l10n_util::GetStringFUTF16(IDS_MANAGE_PASSWORDS_DELETE, username));
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 bc754f0..4ea775e1 100644 --- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc +++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -306,8 +306,7 @@ return result == Browser::WarnBeforeClosingResult::kOkToClose; } -void BrowserTabStripController::CloseTab(int model_index, - CloseTabSource source) { +void BrowserTabStripController::CloseTab(int model_index) { // Cancel any pending tab transition. hover_tab_selector_.CancelTabTransition(); @@ -316,26 +315,6 @@ TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); } -void BrowserTabStripController::CloseAllTabsInGroup( - const tab_groups::TabGroupId& group) { - tabstrip_->UpdateHoverCard(nullptr); - - std::vector<int> tabs = ListTabsInGroup(group); - for (int i = tabs.size() - 1; i >= 0; --i) - CloseTab(tabs[i], CLOSE_TAB_FROM_MOUSE); -} - -void BrowserTabStripController::UngroupAllTabsInGroup( - const tab_groups::TabGroupId& group) { - model_->RemoveFromGroup(ListTabsInGroup(group)); -} - -void BrowserTabStripController::AddNewTabInGroup( - const tab_groups::TabGroupId& group) { - const std::vector<int> tabs = ListTabsInGroup(group); - model_->delegate()->AddTabAt(GURL(), tabs.back() + 1, true, group); -} - void BrowserTabStripController::AddTabToGroup( int model_index, const tab_groups::TabGroupId& group) {
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h index 2e557751..52168c5f 100644 --- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h +++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h
@@ -63,10 +63,7 @@ void ToggleSelected(int model_index) override; void AddSelectionFromAnchorTo(int model_index) override; bool BeforeCloseTab(int model_index, CloseTabSource source) override; - void CloseTab(int model_index, CloseTabSource source) override; - void CloseAllTabsInGroup(const tab_groups::TabGroupId& group) override; - void UngroupAllTabsInGroup(const tab_groups::TabGroupId& group) override; - void AddNewTabInGroup(const tab_groups::TabGroupId& group) override; + void CloseTab(int model_index) override; void AddTabToGroup(int model_index, const tab_groups::TabGroupId& group) override; void RemoveTabFromGroup(int model_index) override;
diff --git a/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc index 945e9b0..7056910 100644 --- a/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc +++ b/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.cc
@@ -88,15 +88,6 @@ fake_group_data_ = visual_data; } -void FakeBaseTabStripController::CloseAllTabsInGroup( - const tab_groups::TabGroupId& group) {} - -void FakeBaseTabStripController::UngroupAllTabsInGroup( - const tab_groups::TabGroupId& group) {} - -void FakeBaseTabStripController::AddNewTabInGroup( - const tab_groups::TabGroupId& group) {} - void FakeBaseTabStripController::AddTabToGroup( int model_index, const tab_groups::TabGroupId& group) { @@ -196,7 +187,7 @@ return true; } -void FakeBaseTabStripController::CloseTab(int index, CloseTabSource source) { +void FakeBaseTabStripController::CloseTab(int index) { RemoveTab(index); }
diff --git a/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h b/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h index 4029b77b..f0fdf98c2 100644 --- a/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h +++ b/chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h
@@ -45,7 +45,7 @@ void ToggleSelected(int index) override; void AddSelectionFromAnchorTo(int index) override; bool BeforeCloseTab(int index, CloseTabSource source) override; - void CloseTab(int index, CloseTabSource source) override; + void CloseTab(int index) override; void MoveTab(int from_index, int to_index) override; void MoveGroup(const tab_groups::TabGroupId&, int to_index) override; void ShowContextMenuForTab(Tab* tab, @@ -70,9 +70,6 @@ const tab_groups::TabGroupVisualData& visual_data) override; std::vector<int> ListTabsInGroup( const tab_groups::TabGroupId& group) const override; - void CloseAllTabsInGroup(const tab_groups::TabGroupId& group) override; - void UngroupAllTabsInGroup(const tab_groups::TabGroupId& group) override; - void AddNewTabInGroup(const tab_groups::TabGroupId& group) override; void AddTabToGroup(int model_index, const tab_groups::TabGroupId& group) override; void RemoveTabFromGroup(int model_index) override;
diff --git a/chrome/browser/ui/views/tabs/tab_group_editor_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_group_editor_bubble_view.cc index 1dbb48fa..90133aa 100644 --- a/chrome/browser/ui/views/tabs/tab_group_editor_bubble_view.cc +++ b/chrome/browser/ui/views/tabs/tab_group_editor_bubble_view.cc
@@ -17,12 +17,16 @@ #include "base/no_destructor.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/ui/tabs/tab_group.h" +#include "chrome/browser/ui/tabs/tab_group_model.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/tabs/tab_strip_model_delegate.h" #include "chrome/browser/ui/views/bubble_menu_item_factory.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/tabs/color_picker_view.h" -#include "chrome/browser/ui/views/tabs/tab_strip_controller.h" #include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h" #include "chrome/grit/generated_resources.h" #include "components/tab_groups/tab_group_color.h" @@ -45,10 +49,10 @@ // static views::Widget* TabGroupEditorBubbleView::Show( TabGroupHeader* anchor_view, - TabStripController* tab_strip_controller, + const Browser* browser, const tab_groups::TabGroupId& group) { views::Widget* const widget = BubbleDialogDelegateView::CreateBubble( - new TabGroupEditorBubbleView(anchor_view, tab_strip_controller, group)); + new TabGroupEditorBubbleView(anchor_view, browser, group)); widget->Show(); return widget; } @@ -69,18 +73,22 @@ TabGroupEditorBubbleView::TabGroupEditorBubbleView( TabGroupHeader* anchor_view, - TabStripController* tab_strip_controller, + const Browser* browser, const tab_groups::TabGroupId& group) - : tab_strip_controller_(tab_strip_controller), + : browser_(browser), group_(group), title_field_controller_(this), - button_listener_(tab_strip_controller, anchor_view, group) { + button_listener_(browser, anchor_view, group) { SetAnchorView(anchor_view); set_margins(gfx::Insets()); DialogDelegate::set_buttons(ui::DIALOG_BUTTON_NONE); - const base::string16 title = tab_strip_controller_->GetGroupTitle(group_); + const base::string16 title = browser_->tab_strip_model() + ->group_model() + ->GetTabGroup(group_) + ->visual_data() + ->title(); title_at_opening_ = title; DialogDelegate::set_close_callback(base::BindOnce( &TabGroupEditorBubbleView::OnBubbleClose, base::Unretained(this))); @@ -200,7 +208,11 @@ // Keep track of the current group's color, to be returned as the initial // selected value. const tab_groups::TabGroupColorId initial_color_id = - tab_strip_controller_->GetGroupColorId(group_); + browser_->tab_strip_model() + ->group_model() + ->GetTabGroup(group_) + ->visual_data() + ->color(); SkColor initial_color; color_ids_.reserve(all_colors.size()); @@ -221,8 +233,11 @@ void TabGroupEditorBubbleView::UpdateGroup() { base::Optional<int> selected_element = color_selector_->GetSelectedElement(); + TabGroup* tab_group = + browser_->tab_strip_model()->group_model()->GetTabGroup(group_); + const tab_groups::TabGroupColorId current_color = - tab_strip_controller_->GetGroupColorId(group_); + tab_group->visual_data()->color(); const tab_groups::TabGroupColorId updated_color = selected_element.has_value() ? color_ids_[selected_element.value()] : current_color; @@ -234,7 +249,7 @@ tab_groups::TabGroupVisualData new_data(title_field_->GetText(), updated_color); - tab_strip_controller_->SetVisualDataForGroup(group_, new_data); + tab_group->SetVisualData(new_data); } void TabGroupEditorBubbleView::OnBubbleClose() { @@ -276,39 +291,44 @@ } TabGroupEditorBubbleView::ButtonListener::ButtonListener( - TabStripController* tab_strip_controller, + const Browser* browser, TabGroupHeader* anchor_view, tab_groups::TabGroupId group) - : tab_strip_controller_(tab_strip_controller), - anchor_view_(anchor_view), - group_(group) {} + : browser_(browser), anchor_view_(anchor_view), group_(group) {} void TabGroupEditorBubbleView::ButtonListener::ButtonPressed( views::Button* sender, const ui::Event& event) { + TabStripModel* model = browser_->tab_strip_model(); + const std::vector<int> tabs_in_group = + model->group_model()->GetTabGroup(group_)->ListTabs(); switch (sender->GetID()) { case TAB_GROUP_HEADER_CXMENU_NEW_TAB_IN_GROUP: base::RecordAction( base::UserMetricsAction("TabGroups_TabGroupBubble_NewTabInGroup")); - tab_strip_controller_->AddNewTabInGroup(group_); + model->delegate()->AddTabAt(GURL(), tabs_in_group.back() + 1, true, + group_); break; case TAB_GROUP_HEADER_CXMENU_UNGROUP: base::RecordAction( base::UserMetricsAction("TabGroups_TabGroupBubble_Ungroup")); anchor_view_->RemoveObserverFromWidget(sender->GetWidget()); - tab_strip_controller_->UngroupAllTabsInGroup(group_); + model->RemoveFromGroup(tabs_in_group); break; case TAB_GROUP_HEADER_CXMENU_CLOSE_GROUP: base::RecordAction( base::UserMetricsAction("TabGroups_TabGroupBubble_CloseGroup")); - tab_strip_controller_->CloseAllTabsInGroup(group_); + for (int i = tabs_in_group.size() - 1; i >= 0; --i) { + model->CloseWebContentsAt( + tabs_in_group[i], TabStripModel::CLOSE_USER_GESTURE | + TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); + } break; case TAB_GROUP_HEADER_CXMENU_FEEDBACK: { base::RecordAction( base::UserMetricsAction("TabGroups_TabGroupBubble_SendFeedback")); - const Browser* browser = tab_strip_controller_->GetBrowser(); chrome::ShowFeedbackPage( - browser, chrome::FeedbackSource::kFeedbackSourceDesktopTabGroups, + browser_, chrome::FeedbackSource::kFeedbackSourceDesktopTabGroups, std::string() /* description_template */, std::string() /* description_placeholder_text */, std::string("DESKTOP_TAB_GROUPS") /* category_tag */,
diff --git a/chrome/browser/ui/views/tabs/tab_group_editor_bubble_view.h b/chrome/browser/ui/views/tabs/tab_group_editor_bubble_view.h index d8a2a71..2fc4585 100644 --- a/chrome/browser/ui/views/tabs/tab_group_editor_bubble_view.h +++ b/chrome/browser/ui/views/tabs/tab_group_editor_bubble_view.h
@@ -12,7 +12,7 @@ #include "ui/views/controls/textfield/textfield.h" #include "ui/views/controls/textfield/textfield_controller.h" -class TabStripController; +class Browser; namespace gfx { class Size; @@ -37,7 +37,7 @@ // Shows the editor for |group|. Returns an *unowned* pointer to the // bubble's widget. static views::Widget* Show(TabGroupHeader* anchor_view, - TabStripController* tab_strip_controller, + const Browser* browser, const tab_groups::TabGroupId& group); // views::BubbleDialogDelegateView: @@ -47,7 +47,7 @@ private: TabGroupEditorBubbleView(TabGroupHeader* anchor_view, - TabStripController* tab_strip_controller, + const Browser* browser, const tab_groups::TabGroupId& group); ~TabGroupEditorBubbleView() override; @@ -57,7 +57,7 @@ void OnBubbleClose(); - TabStripController* const tab_strip_controller_; + const Browser* const browser_; const tab_groups::TabGroupId group_; class TitleFieldController : public views::TextfieldController { @@ -80,7 +80,7 @@ class ButtonListener : public views::ButtonListener { public: - explicit ButtonListener(TabStripController* tab_strip_controller, + explicit ButtonListener(const Browser* browser, TabGroupHeader* anchor_view, tab_groups::TabGroupId group); @@ -88,7 +88,7 @@ void ButtonPressed(views::Button* sender, const ui::Event& event) override; private: - TabStripController* const tab_strip_controller_; + const Browser* const browser_; TabGroupHeader* anchor_view_; const tab_groups::TabGroupId group_; };
diff --git a/chrome/browser/ui/views/tabs/tab_group_header.cc b/chrome/browser/ui/views/tabs/tab_group_header.cc index a4d0b14..74ecb94 100644 --- a/chrome/browser/ui/views/tabs/tab_group_header.cc +++ b/chrome/browser/ui/views/tabs/tab_group_header.cc
@@ -106,7 +106,7 @@ event.key_code() == ui::VKEY_RETURN) && !editor_bubble_tracker_.is_open()) { editor_bubble_tracker_.Opened(TabGroupEditorBubbleView::Show( - this, tab_strip_->controller(), group().value())); + this, tab_strip_->controller()->GetBrowser(), group().value())); return true; } @@ -155,7 +155,7 @@ void TabGroupHeader::OnMouseReleased(const ui::MouseEvent& event) { if (!dragging()) { editor_bubble_tracker_.Opened(TabGroupEditorBubbleView::Show( - this, tab_strip_->controller(), group().value())); + this, tab_strip_->controller()->GetBrowser(), group().value())); } tab_strip_->EndDrag(END_DRAG_COMPLETE); } @@ -175,7 +175,7 @@ switch (event->type()) { case ui::ET_GESTURE_TAP: { editor_bubble_tracker_.Opened(TabGroupEditorBubbleView::Show( - this, tab_strip_->controller(), group().value())); + this, tab_strip_->controller()->GetBrowser(), group().value())); break; }
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index da03292c..949daae 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -1641,7 +1641,7 @@ UpdateHoverCard(nullptr); if (tab->group().has_value()) base::RecordAction(base::UserMetricsAction("CloseGroupedTab")); - controller_->CloseTab(model_index, source); + controller_->CloseTab(model_index); } void TabStrip::ShiftTabLeft(Tab* tab) {
diff --git a/chrome/browser/ui/views/tabs/tab_strip_controller.h b/chrome/browser/ui/views/tabs/tab_strip_controller.h index 96cc7c4e..e0971680 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_controller.h +++ b/chrome/browser/ui/views/tabs/tab_strip_controller.h
@@ -80,16 +80,7 @@ virtual bool BeforeCloseTab(int index, CloseTabSource source) = 0; // Closes the tab at the specified index in the model. - virtual void CloseTab(int index, CloseTabSource source) = 0; - - // Closes all tabs belonging in the given |group|. - virtual void CloseAllTabsInGroup(const tab_groups::TabGroupId& group) = 0; - - // Ungroups the tabs at the specified index in the model. - virtual void UngroupAllTabsInGroup(const tab_groups::TabGroupId& group) = 0; - - // Adds a new tab to end of the tab group. - virtual void AddNewTabInGroup(const tab_groups::TabGroupId& group) = 0; + virtual void CloseTab(int index) = 0; // Adds a tab to an existing tab group. virtual void AddTabToGroup(int model_index,
diff --git a/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc b/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc index 2bae516..93fcba05 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc
@@ -102,11 +102,10 @@ const base::string16& text = extra_view_info->text; if (!text.empty()) { if (extra_view_info->is_learn_more) { - auto image_button = views::CreateVectorImageButton(this); + auto image_button = views::CreateVectorImageButtonWithNativeTheme( + this, vector_icons::kHelpOutlineIcon); image_button->SetFocusForPlatform(); image_button->SetTooltipText(text); - views::SetImageFromVectorIcon(image_button.get(), - vector_icons::kHelpOutlineIcon); learn_more_button_ = image_button.get(); extra_view = std::move(image_button); } else {
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc index 8562439..7d449218 100644 --- a/chrome/browser/ui/web_applications/web_app_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -471,6 +471,18 @@ kNotPresent); } +// Tests that both installing a PWA and creating a shortcut app are disabled for +// an error page. +IN_PROC_BROWSER_TEST_P(WebAppBrowserTest, ShortcutMenuOptionsForErrorPage) { + ASSERT_TRUE(https_server()->Start()); + + EXPECT_FALSE(NavigateAndAwaitInstallabilityCheck( + browser(), https_server()->GetURL("/invalid_path.html"))); + + EXPECT_EQ(GetAppMenuCommandState(IDC_CREATE_SHORTCUT, browser()), kDisabled); + EXPECT_EQ(GetAppMenuCommandState(IDC_INSTALL_PWA, browser()), kNotPresent); +} + // Tests that both installing a PWA and creating a shortcut app are available // for an installable PWA. IN_PROC_BROWSER_TEST_P(WebAppBrowserTest,
diff --git a/chrome/browser/ui/web_applications/web_app_dialog_utils.cc b/chrome/browser/ui/web_applications/web_app_dialog_utils.cc index 1cc13d0..58c2a86f 100644 --- a/chrome/browser/ui/web_applications/web_app_dialog_utils.cc +++ b/chrome/browser/ui/web_applications/web_app_dialog_utils.cc
@@ -25,6 +25,7 @@ #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/chrome_features.h" #include "chrome/common/web_application_info.h" +#include "content/public/browser/navigation_entry.h" namespace web_app { @@ -71,6 +72,10 @@ browser->tab_strip_model()->GetActiveWebContents(); if (!WebAppProvider::GetForWebContents(web_contents)) return false; + content::NavigationEntry* entry = + web_contents->GetController().GetLastCommittedEntry(); + bool is_error_page = + entry && entry->GetPageType() == content::PAGE_TYPE_ERROR; Profile* web_contents_profile = Profile::FromBrowserContext(web_contents->GetBrowserContext()); banners::AppBannerManager* app_banner_manager = @@ -80,7 +85,7 @@ return AreWebAppsUserInstallable(web_contents_profile) && IsValidWebAppUrl(web_contents->GetLastCommittedURL()) && - !externally_installed; + !is_error_page && !externally_installed; } bool CanPopOutWebApp(Profile* profile) {
diff --git a/chrome/browser/ui/webui/autofill_and_password_manager_internals/autofill_internals_ui.h b/chrome/browser/ui/webui/autofill_and_password_manager_internals/autofill_internals_ui.h index c38a6d9b..4869bd69 100644 --- a/chrome/browser/ui/webui/autofill_and_password_manager_internals/autofill_internals_ui.h +++ b/chrome/browser/ui/webui/autofill_and_password_manager_internals/autofill_internals_ui.h
@@ -6,9 +6,12 @@ #define CHROME_BROWSER_UI_WEBUI_AUTOFILL_AND_PASSWORD_MANAGER_INTERNALS_AUTOFILL_INTERNALS_UI_H_ #include "base/macros.h" -#include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_controller.h" +namespace content { +class WebUI; +} + class AutofillInternalsUI : public content::WebUIController { public: explicit AutofillInternalsUI(content::WebUI* web_ui);
diff --git a/chrome/browser/ui/webui/autofill_and_password_manager_internals/password_manager_internals_ui.h b/chrome/browser/ui/webui/autofill_and_password_manager_internals/password_manager_internals_ui.h index 19d8ed9..3e557dd 100644 --- a/chrome/browser/ui/webui/autofill_and_password_manager_internals/password_manager_internals_ui.h +++ b/chrome/browser/ui/webui/autofill_and_password_manager_internals/password_manager_internals_ui.h
@@ -6,9 +6,12 @@ #define CHROME_BROWSER_UI_WEBUI_AUTOFILL_AND_PASSWORD_MANAGER_INTERNALS_PASSWORD_MANAGER_INTERNALS_UI_H_ #include "base/macros.h" -#include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_controller.h" +namespace content { +class WebUI; +} + class PasswordManagerInternalsUI : public content::WebUIController { public: explicit PasswordManagerInternalsUI(content::WebUI* web_ui);
diff --git a/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.h index 7ac15fc..619e5b9a 100644 --- a/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.h
@@ -9,7 +9,6 @@ #include "base/macros.h" #include "chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen_view.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" -#include "content/public/browser/web_ui.h" namespace chromeos {
diff --git a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h index 9a14d39c..848c494 100644 --- a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h
@@ -10,7 +10,6 @@ #include "base/memory/ref_counted.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" #include "components/login/secure_module_util_chromeos.h" -#include "content/public/browser/web_ui.h" namespace base { class DictionaryValue;
diff --git a/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.h index a731413..ea48af5d 100644 --- a/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.h
@@ -12,7 +12,6 @@ #include "base/values.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" #include "components/prefs/pref_registry_simple.h" -#include "content/public/browser/web_ui.h" namespace chromeos {
diff --git a/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.h index 4b296b9..8a9d07f 100644 --- a/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.h
@@ -9,7 +9,6 @@ #include "base/macros.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" -#include "content/public/browser/web_ui.h" namespace chromeos {
diff --git a/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h index e7feeb5..a608bdfd 100644 --- a/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h
@@ -9,7 +9,6 @@ #include "base/macros.h" #include "chrome/browser/chromeos/tpm_firmware_update.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" -#include "content/public/browser/web_ui.h" namespace chromeos {
diff --git a/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h index 11ab991..c66ca810 100644 --- a/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.h
@@ -8,7 +8,6 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" -#include "content/public/browser/web_ui.h" namespace chromeos {
diff --git a/chrome/browser/ui/webui/chromeos/system_web_dialog_browsertest.cc b/chrome/browser/ui/webui/chromeos/system_web_dialog_browsertest.cc index 15decff..e90675f 100644 --- a/chrome/browser/ui/webui/chromeos/system_web_dialog_browsertest.cc +++ b/chrome/browser/ui/webui/chromeos/system_web_dialog_browsertest.cc
@@ -18,6 +18,7 @@ #include "components/account_id/account_id.h" #include "components/prefs/pref_service.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/web_ui.h" #include "content/public/common/service_manager_connection.h" #include "content/public/common/web_preferences.h" #include "services/service_manager/public/cpp/connector.h"
diff --git a/chrome/browser/ui/webui/history/foreign_session_handler.h b/chrome/browser/ui/webui/history/foreign_session_handler.h index 3d78112..efd0a977 100644 --- a/chrome/browser/ui/webui/history/foreign_session_handler.h +++ b/chrome/browser/ui/webui/history/foreign_session_handler.h
@@ -15,9 +15,12 @@ #include "base/values.h" #include "chrome/browser/sessions/session_service.h" #include "components/sync_sessions/open_tabs_ui_delegate.h" -#include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_message_handler.h" +namespace content { +class WebUI; +} + namespace user_prefs { class PrefRegistrySyncable; }
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc index 3af2267..d09c660 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
@@ -22,6 +22,7 @@ #include "content/public/browser/plugin_service.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui.h" #include "printing/print_job_constants.h" using content::WebContents;
diff --git a/chrome/browser/ui/webui/settings/change_password_handler.cc b/chrome/browser/ui/webui/settings/change_password_handler.cc deleted file mode 100644 index 6382a152..0000000 --- a/chrome/browser/ui/webui/settings/change_password_handler.cc +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/settings/change_password_handler.h" - -#include "base/bind.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/safe_browsing/chrome_password_protection_service.h" -#include "components/prefs/pref_service.h" -#include "components/safe_browsing/content/password_protection/metrics_util.h" -#include "components/safe_browsing/core/proto/csd.pb.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" - -namespace settings { - -using password_manager::metrics_util::PasswordType; -using safe_browsing::ChromePasswordProtectionService; -using safe_browsing::LoginReputationClientResponse; -using safe_browsing::RequestOutcome; - -ChangePasswordHandler::ChangePasswordHandler( - Profile* profile, - safe_browsing::ChromePasswordProtectionService* service) - : profile_(profile), service_(service) { - DCHECK(service_); -} - -ChangePasswordHandler::~ChangePasswordHandler() {} - -void ChangePasswordHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "initializeChangePasswordHandler", - base::BindRepeating(&ChangePasswordHandler::HandleInitialize, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "changePassword", - base::BindRepeating(&ChangePasswordHandler::HandleChangePassword, - base::Unretained(this))); -} - -void ChangePasswordHandler::OnJavascriptAllowed() { - pref_registrar_.Init(profile_->GetPrefs()); - pref_registrar_.Add( - prefs::kSafeBrowsingUnhandledGaiaPasswordReuses, - base::Bind(&ChangePasswordHandler::UpdateChangePasswordCardVisibility, - base::Unretained(this))); -} - -void ChangePasswordHandler::OnJavascriptDisallowed() { - pref_registrar_.RemoveAll(); -} - -void ChangePasswordHandler::HandleInitialize(const base::ListValue* args) { - AllowJavascript(); - UpdateChangePasswordCardVisibility(); -} - -void ChangePasswordHandler::HandleChangePassword(const base::ListValue* args) { - service_->OnUserAction( - web_ui()->GetWebContents(), - service_->reused_password_account_type_for_last_shown_warning(), - RequestOutcome::UNKNOWN, - LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, "unused_token", - safe_browsing::WarningUIType::CHROME_SETTINGS, - safe_browsing::WarningAction::CHANGE_PASSWORD); -} - -void ChangePasswordHandler::UpdateChangePasswordCardVisibility() { - FireWebUIListener( - "change-password-visibility", - base::Value( - service_->IsWarningEnabled( - service_ - ->reused_password_account_type_for_last_shown_warning()) && - safe_browsing::ChromePasswordProtectionService:: - ShouldShowChangePasswordSettingUI(profile_))); -} - -} // namespace settings
diff --git a/chrome/browser/ui/webui/settings/change_password_handler.h b/chrome/browser/ui/webui/settings/change_password_handler.h deleted file mode 100644 index f1ea38064..0000000 --- a/chrome/browser/ui/webui/settings/change_password_handler.h +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHANGE_PASSWORD_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHANGE_PASSWORD_HANDLER_H_ - -#include "base/macros.h" -#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" -#include "components/prefs/pref_change_registrar.h" - -class Profile; - -namespace safe_browsing { -class ChromePasswordProtectionService; -} - -namespace settings { - -// Chrome "Change Password" settings page UI handler. -class ChangePasswordHandler : public SettingsPageUIHandler { - public: - explicit ChangePasswordHandler( - Profile* profile, - safe_browsing::ChromePasswordProtectionService* service); - ~ChangePasswordHandler() override; - - // settings::SettingsPageUIHandler: - void RegisterMessages() override; - void OnJavascriptAllowed() override; - void OnJavascriptDisallowed() override; - - private: - void HandleInitialize(const base::ListValue* args); - - void HandleChangePassword(const base::ListValue* args); - - void UpdateChangePasswordCardVisibility(); - - Profile* profile_; - - PrefChangeRegistrar pref_registrar_; - - safe_browsing::ChromePasswordProtectionService* service_; - - DISALLOW_COPY_AND_ASSIGN(ChangePasswordHandler); -}; - -} // namespace settings - -#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHANGE_PASSWORD_HANDLER_H_
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index eac1346..8c5c871 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -306,15 +306,6 @@ dom_distiller::OfferReaderModeInSettings()); } -void AddChangePasswordStrings(content::WebUIDataSource* html_source) { - static constexpr webui::LocalizedString kLocalizedStrings[] = { - {"changePasswordPageTitle", IDS_SETTINGS_CHANGE_PASSWORD_TITLE}, - {"changePasswordPageDetails", IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS}, - {"changePasswordPageButton", IDS_SETTINGS_CHANGE_PASSWORD_BUTTON}, - }; - AddLocalizedStringsBulk(html_source, kLocalizedStrings); -} - void AddClearBrowsingDataStrings(content::WebUIDataSource* html_source, Profile* profile) { static constexpr webui::LocalizedString kLocalizedStrings[] = { @@ -1913,7 +1904,6 @@ AddIncompatibleApplicationsStrings(html_source); #endif // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) - AddChangePasswordStrings(html_source); AddClearBrowsingDataStrings(html_source, profile); AddCommonStrings(html_source, profile); AddDownloadsStrings(html_source);
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.cc b/chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.cc index cf06057..3cf2c39d 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.cc
@@ -19,6 +19,7 @@ #include "chromeos/constants/chromeos_pref_names.h" #include "components/prefs/pref_service.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" +#include "content/public/browser/web_ui.h" #include "google_apis/gaia/gaia_auth_util.h" #include "net/base/url_util.h" #include "ui/aura/window.h"
diff --git a/chrome/browser/ui/webui/site_settings_helper.h b/chrome/browser/ui/webui/site_settings_helper.h index 70b5ff5..382b4d7e 100644 --- a/chrome/browser/ui/webui/site_settings_helper.h +++ b/chrome/browser/ui/webui/site_settings_helper.h
@@ -16,13 +16,16 @@ #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_pattern.h" #include "components/content_settings/core/common/content_settings_types.h" -#include "content/public/browser/web_ui.h" #include "extensions/common/extension.h" class ChooserContextBase; class HostContentSettingsMap; class Profile; +namespace content { +class WebUI; +} + namespace extensions { class ExtensionRegistry; }
diff --git a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_browsertest.cc b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_browsertest.cc index de27360..43d10a63 100644 --- a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_browsertest.cc +++ b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_browsertest.cc
@@ -23,6 +23,7 @@ #include "content/public/browser/navigation_controller.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui.h" #include "content/public/test/browser_test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "ui/base/accelerators/accelerator.h"
diff --git a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_handler.cc b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_handler.cc index bc01f17..b8e16fc 100644 --- a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_handler.cc +++ b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_handler.cc
@@ -623,6 +623,13 @@ new_group_id, base::Optional<tab_groups::TabGroupVisualData>{*group->visual_data()}); + // The front-end needs to understand that the tab group ID has changed so + // that when the tabs are moved into the new group, the new group ID is + // updated with the correct value. + FireWebUIListener("tab-group-id-replaced", + base::Value(group->id().ToString()), + base::Value(new_group_id.ToString())); + std::vector<int> source_tab_indices = group->ListTabs(); int tab_count = source_tab_indices.size(); for (int i = 0; i < tab_count; i++) {
diff --git a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_handler_unittest.cc b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_handler_unittest.cc index 413db8c..8c3d3fc 100644 --- a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_handler_unittest.cc +++ b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_handler_unittest.cc
@@ -354,6 +354,7 @@ new_browser.get()->tab_strip_model()->GetWebContentsAt(0); content::WebContents* moved_contents2 = new_browser.get()->tab_strip_model()->GetWebContentsAt(1); + web_ui()->ClearTrackedCalls(); int new_index = -1; base::ListValue args; @@ -383,6 +384,20 @@ ->visual_data(); ASSERT_EQ(visual_data.title(), new_visual_data->title()); ASSERT_EQ(visual_data.color(), new_visual_data->color()); + + // Test that a WebUI event for the ID change was sent first. + const content::TestWebUI::CallData& group_replaced_data = + *web_ui()->call_data().front(); + EXPECT_EQ("cr.webUIListenerCallback", group_replaced_data.function_name()); + std::string event_name; + ASSERT_TRUE(group_replaced_data.arg1()->GetAsString(&event_name)); + EXPECT_EQ("tab-group-id-replaced", event_name); + std::string old_group_id_arg; + ASSERT_TRUE(group_replaced_data.arg2()->GetAsString(&old_group_id_arg)); + EXPECT_EQ(group_id.ToString(), old_group_id_arg); + std::string new_group_id_arg; + ASSERT_TRUE(group_replaced_data.arg3()->GetAsString(&new_group_id_arg)); + EXPECT_EQ(new_group_id.value().ToString(), new_group_id_arg); } TEST_F(TabStripUIHandlerTest, MoveGroupAcrossProfiles) {
diff --git a/chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.h b/chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.h index faca789..504a189 100644 --- a/chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.h +++ b/chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.h
@@ -10,7 +10,6 @@ #include <utility> #include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_controller.h" #include "content/public/browser/web_ui_controller_factory.h" #include "content/public/test/test_utils.h"
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index e8022949..8a8107b5 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -970,6 +970,9 @@ const char kMostRecentlyUsedNetworkFileShareURL[] = "network_file_shares.most_recently_used_url"; +// List of network files shares added by the user. +const char kNetworkFileSharesSavedShares[] = "network_file_shares.saved_shares"; + // A string pref storing the path of device wallpaper image file. const char kDeviceWallpaperImageFilePath[] = "policy.device_wallpaper_image_file_path";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 2f6e3858..899fde4 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -306,6 +306,7 @@ extern const char kNTLMShareAuthenticationEnabled[]; extern const char kNetworkFileSharesPreconfiguredShares[]; extern const char kMostRecentlyUsedNetworkFileShareURL[]; +extern const char kNetworkFileSharesSavedShares[]; extern const char kParentAccessCodeConfig[]; extern const char kPerAppTimeLimitsAppActivities[]; extern const char kPerAppTimeLimitsLastResetTime[];
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java b/chrome/test/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java index 54e7f55..f02a0ba 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java
@@ -6,7 +6,6 @@ import androidx.annotation.Nullable; -import org.chromium.chrome.browser.tab.TabUma.TabCreationState; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.WebContents;
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java index 15841b5..f9e405ece 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java
@@ -43,6 +43,7 @@ import org.chromium.chrome.browser.settings.SettingsLauncher; import org.chromium.chrome.browser.settings.privacy.PrivacyPreferencesManager; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; @@ -491,7 +492,8 @@ TabModel incognitoTabModel = getActivity().getTabModelSelector().getModel(true); TabModelObserver observer = new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { createdCallback.notifyCalled(); }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestRule.java index 13affc5..6b7db0e9 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestRule.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestRule.java
@@ -16,6 +16,7 @@ import org.chromium.base.test.util.CallbackHelper; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.test.util.ApplicationTestUtils; import org.chromium.chrome.test.util.ChromeTabUtils; @@ -56,7 +57,7 @@ final CallbackHelper newTabCreatorHelper = new CallbackHelper(); activity.getTabModelSelector().addObserver(new EmptyTabModelSelectorObserver() { @Override - public void onNewTabCreated(Tab tab) { + public void onNewTabCreated(Tab tab, @TabCreationState int creationState) { newTabCreatorHelper.notifyCalled(); } });
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java index 032ea1f..a126fd7 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java
@@ -23,6 +23,7 @@ import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutHelper; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabHidingType; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; @@ -339,7 +340,8 @@ final CallbackHelper createdCallback = new CallbackHelper(); normalTabModel.addObserver(new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { createdCallback.notifyCalled(); normalTabModel.removeObserver(this); } @@ -385,7 +387,8 @@ TabModel tabModel = activity.getTabModelSelector().getModel(incognito); TabModelObserver observer = new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { createdCallback.notifyCalled(); } @@ -640,7 +643,8 @@ testRule.getActivity().getTabModelSelector().getModel(expectIncognito); tabModel.addObserver(new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { if (TextUtils.equals(expectedUrl, tab.getUrlString())) { createdCallback.notifyCalled(); tabModel.removeObserver(this); @@ -689,7 +693,8 @@ backgroundActivity.getTabModelSelector().getModel(expectIncognito); tabModel.addObserver(new EmptyTabModelObserver() { @Override - public void didAddTab(Tab tab, @TabLaunchType int type) { + public void didAddTab( + Tab tab, @TabLaunchType int type, @TabCreationState int creationState) { if (TextUtils.equals(expectedUrl, tab.getUrlString())) { createdCallback.notifyCalled(); tabModel.removeObserver(this);
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModel.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModel.java index 0e9313e..1242f46 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModel.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModel.java
@@ -6,6 +6,7 @@ import org.chromium.chrome.browser.tab.MockTab; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tabmodel.EmptyTabModel; @@ -50,7 +51,8 @@ } @Override - public void addTab(Tab tab, int index, @TabLaunchType int type) { + public void addTab( + Tab tab, int index, @TabLaunchType int type, @TabCreationState int creationState) { if (index == -1) { mTabs.add(tab); } else {
diff --git a/chrome/test/data/extensions/api_test/declarative_net_request/dynamic_rules/background.js b/chrome/test/data/extensions/api_test/declarative_net_request/dynamic_rules/background.js index ce01e48..71120cc 100644 --- a/chrome/test/data/extensions/api_test/declarative_net_request/dynamic_rules/background.js +++ b/chrome/test/data/extensions/api_test/declarative_net_request/dynamic_rules/background.js
@@ -15,6 +15,15 @@ }; }; +var createLargeRegexRuleWithID = function(id) { + return { + id: id, + priority: 1, + condition: {regexFilter: '.{512}x'}, + action: {type: 'block'}, + }; +}; + // Verifies the current set of rules. Ensures no error is signalled and proceeds // to the next test. var verifyCurrentRulesCallback = function() { @@ -66,6 +75,16 @@ chrome.test.callbackFail('Rule with id 3 does not have a unique ID.')); }, + // Ensure we get an error on adding a rule which exceeds the regex memory + // limit. + function largeRegexError() { + updateDynamicRules( + [], [createLargeRegexRuleWithID(5)], + chrome.test.callbackFail( + 'Rule with id 5 specified a more complex regex than allowed as ' + + 'part of the "regexFilter" key.')); + }, + // Ensure we can add up to |ruleLimit| no. of rules. function ruleLimitReached() { // There is already a single rule present with 'id' 3.
diff --git a/chrome/test/data/webui/settings/change_password_page_test.js b/chrome/test/data/webui/settings/change_password_page_test.js deleted file mode 100644 index 2f91d593..0000000 --- a/chrome/test/data/webui/settings/change_password_page_test.js +++ /dev/null
@@ -1,46 +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. - -/** @implements {settings.ChangePasswordBrowserProxy} */ -class TestChangePasswordBrowserProxy extends TestBrowserProxy { - constructor() { - super([ - 'changePassword', - ]); - } - - /** @override */ - changePassword() { - this.methodCalled('changePassword'); - } -} - -suite('ChangePasswordHandler', function() { - let changePasswordPage = null; - - /** @type {?TestChangePasswordBrowserProxy} */ - let browserProxy = null; - - setup(function() { - browserProxy = new TestChangePasswordBrowserProxy(); - settings.ChangePasswordBrowserProxyImpl.instance_ = browserProxy; - - PolymerTest.clearBody(); - - changePasswordPage = - document.createElement('settings-change-password-page'); - document.body.appendChild(changePasswordPage); - }); - - teardown(function() { - changePasswordPage.remove(); - }); - - test('changePasswordButtonPressed', function() { - const actionButton = changePasswordPage.$$('#changePassword'); - assertTrue(!!actionButton); - actionButton.click(); - return browserProxy.whenCalled('changePassword'); - }); -});
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index a5f376d..635c08c 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -1073,11 +1073,11 @@ return super.extraLibraries.concat([ BROWSER_SETTINGS_PATH + '../fake_chrome_event.js', BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', + BROWSER_SETTINGS_PATH + 'fake_input_method_private.js', BROWSER_SETTINGS_PATH + 'fake_language_settings_private.js', BROWSER_SETTINGS_PATH + 'test_languages_browser_proxy.js', BROWSER_SETTINGS_PATH + 'fake_settings_private.js', BROWSER_SETTINGS_PATH + '../test_util.js', - 'fake_input_method_private.js', 'os_languages_page_tests.js', ]); }
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index 9e3993c..f305db0 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -1670,7 +1670,9 @@ '../fake_chrome_event.js', 'fake_settings_private.js', '../test_browser_proxy.js', + 'fake_input_method_private.js', 'fake_language_settings_private.js', + 'test_languages_browser_proxy.js', 'edit_dictionary_page_test.js', ]), }; @@ -1701,7 +1703,7 @@ '../test_browser_proxy.js', 'fake_language_settings_private.js', 'fake_settings_private.js', - 'chromeos/fake_input_method_private.js', + 'fake_input_method_private.js', 'test_languages_browser_proxy.js', 'languages_tests.js', ]), @@ -1730,7 +1732,7 @@ '../test_browser_proxy.js', 'fake_settings_private.js', 'fake_language_settings_private.js', - 'chromeos/fake_input_method_private.js', + 'fake_input_method_private.js', 'test_languages_browser_proxy.js', 'languages_page_tests.js', ]), @@ -1890,7 +1892,7 @@ // Times out on Windows Tests (dbg). See https://crbug.com/651296. // Times out / crashes on chromium.linux/Linux Tests (dbg) crbug.com/667882 // Times out on Linux CFI. See http://crbug.com/929288. -GEN('#if !defined(NDEBUG) || defined(OS_LINUX)'); +GEN('#if !defined(NDEBUG) || (defined(OS_LINUX) && defined(IS_CFI))'); GEN('#define MAYBE_MainPage DISABLED_MainPage'); GEN('#else'); GEN('#define MAYBE_MainPage MainPage'); @@ -2016,30 +2018,6 @@ * @constructor * @extends {CrSettingsBrowserTest} */ -function CrSettingsChangePasswordPageTest() {} - -CrSettingsChangePasswordPageTest.prototype = { - __proto__: CrSettingsBrowserTest.prototype, - - /** @override */ - browsePreload: - 'chrome://settings/change_password_page/change_password_page.html', - - /** @override */ - extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ - '../test_browser_proxy.js', - 'change_password_page_test.js', - ]), -}; - -TEST_F('CrSettingsChangePasswordPageTest', 'All', function() { - mocha.run(); -}); - -/** - * @constructor - * @extends {CrSettingsBrowserTest} - */ function CrSettingsOnStartupPageTest() {} CrSettingsOnStartupPageTest.prototype = {
diff --git a/chrome/test/data/webui/settings/edit_dictionary_page_test.js b/chrome/test/data/webui/settings/edit_dictionary_page_test.js index f99918e..2277fe2 100644 --- a/chrome/test/data/webui/settings/edit_dictionary_page_test.js +++ b/chrome/test/data/webui/settings/edit_dictionary_page_test.js
@@ -66,7 +66,9 @@ languageSettingsPrivate = new settings.FakeLanguageSettingsPrivate(); languageSettingsPrivate.setSettingsPrefs(settingsPrefs); - settings.languageSettingsPrivateApiForTest = languageSettingsPrivate; + const browserProxy = new settings.TestLanguagesBrowserProxy(); + settings.LanguagesBrowserProxyImpl.instance_ = browserProxy; + browserProxy.setLanguageSettingsPrivate(languageSettingsPrivate); editDictPage = document.createElement('settings-edit-dictionary-page');
diff --git a/chrome/test/data/webui/settings/chromeos/fake_input_method_private.js b/chrome/test/data/webui/settings/fake_input_method_private.js similarity index 100% rename from chrome/test/data/webui/settings/chromeos/fake_input_method_private.js rename to chrome/test/data/webui/settings/fake_input_method_private.js
diff --git a/chrome/test/data/webui/settings/languages_tests.js b/chrome/test/data/webui/settings/languages_tests.js index 1ac4777..cf13798 100644 --- a/chrome/test/data/webui/settings/languages_tests.js +++ b/chrome/test/data/webui/settings/languages_tests.js
@@ -2,162 +2,160 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -cr.define('settings-languages', function() { - suite('settings-languages', function() { - /** - * @param {!Array<string>} expected - */ - function assertLanguageOrder(expected) { - assertEquals(expected.length, languageHelper.languages.enabled.length); - for (let i = 0; i < expected.length; i++) { - assertEquals( - expected[i], languageHelper.languages.enabled[i].language.code); - } +suite('settings-languages', function() { + /** + * @param {!Array<string>} expected + */ + function assertLanguageOrder(expected) { + assertEquals(expected.length, languageHelper.languages.enabled.length); + for (let i = 0; i < expected.length; i++) { + assertEquals( + expected[i], languageHelper.languages.enabled[i].language.code); } + } - /** @type {?settings.LanguagesBrowserProxy} */ - let browserProxy = null; + /** @type {?settings.LanguagesBrowserProxy} */ + let browserProxy = null; - let languageHelper; + let languageHelper; - suiteSetup(function() { - CrSettingsPrefs.deferInitialization = true; - PolymerTest.clearBody(); - }); - - setup(function() { - const settingsPrefs = document.createElement('settings-prefs'); - const settingsPrivate = - new settings.FakeSettingsPrivate(settings.getFakeLanguagePrefs()); - settingsPrefs.initialize(settingsPrivate); - document.body.appendChild(settingsPrefs); - - // Setup test browser proxy. - browserProxy = new settings.TestLanguagesBrowserProxy(); - settings.LanguagesBrowserProxyImpl.instance_ = browserProxy; - - // Setup fake languageSettingsPrivate API. - const languageSettingsPrivate = browserProxy.getLanguageSettingsPrivate(); - languageSettingsPrivate.setSettingsPrefs(settingsPrefs); - - languageHelper = document.createElement('settings-languages'); - - // Prefs would normally be data-bound to settings-languages. - test_util.fakeDataBind(settingsPrefs, languageHelper, 'prefs'); - - document.body.appendChild(languageHelper); - return languageHelper.whenReady().then(function() { - if (cr.isChromeOS || cr.isWindows) { - return browserProxy.whenCalled('getProspectiveUILanguage'); - } - }); - }); - - test('languages model', function() { - const languageSettingsPrivate = browserProxy.getLanguageSettingsPrivate(); - for (let i = 0; i < languageSettingsPrivate.languages.length; i++) { - assertEquals( - languageSettingsPrivate.languages[i].code, - languageHelper.languages.supported[i].code); - } - assertLanguageOrder(['en-US', 'sw']); - assertEquals('en', languageHelper.languages.translateTarget); - - // TODO(michaelpg): Test other aspects of the model. - }); - - test('get language', function() { - // If a language code is not found, try language without location. - lang = languageHelper.getLanguage('en-CN'); - assertEquals('en', lang.code); - - // The old language code for Hebriew is supported. - lang = languageHelper.getLanguage('iw'); - assertEquals('he', lang.code); - - // The 'no' macrolanguage is returned for Norsk Nynorsk. - lang = languageHelper.getLanguage('nn'); - assertEquals('no', lang.code); - }); - - test('modifying languages', function() { - assertTrue(languageHelper.isLanguageEnabled('en-US')); - assertTrue(languageHelper.isLanguageEnabled('sw')); - assertFalse(languageHelper.isLanguageEnabled('en-CA')); - - languageHelper.enableLanguage('en-CA'); - assertTrue(languageHelper.isLanguageEnabled('en-CA')); - languageHelper.disableLanguage('sw'); - assertFalse(languageHelper.isLanguageEnabled('sw')); - - // TODO(michaelpg): Test other modifications. - }); - - test('reorder languages', function() { - // New language is added at the end. - languageHelper.enableLanguage('en-CA'); - assertLanguageOrder(['en-US', 'sw', 'en-CA']); - - // Can move a language up. - languageHelper.moveLanguage('en-CA', true /* upDirection */); - assertLanguageOrder(['en-US', 'en-CA', 'sw']); - - // Can move a language down. - languageHelper.moveLanguage('en-US', false /* upDirection */); - assertLanguageOrder(['en-CA', 'en-US', 'sw']); - - // Can move a language to the front. - languageHelper.moveLanguageToFront('sw'); - const expectedOrder = ['sw', 'en-CA', 'en-US']; - assertLanguageOrder(expectedOrder); - - // Moving the first language up has no effect. - languageHelper.moveLanguage('sw', true /* upDirection */); - assertLanguageOrder(expectedOrder); - - // Moving the first language to top has no effect. - languageHelper.moveLanguageToFront('sw'); - assertLanguageOrder(expectedOrder); - - // Moving the last language down has no effect. - languageHelper.moveLanguage('en-US', false /* upDirection */); - assertLanguageOrder(expectedOrder); - }); - - if (cr.isChromeOS) { - test('modifying input methods', function() { - assertEquals(2, languageHelper.languages.inputMethods.enabled.length); - const inputMethods = languageHelper.getInputMethodsForLanguage('en-US'); - assertEquals(3, inputMethods.length); - - // We can remove one input method. - const dvorak = - '_comp_ime_fgoepimhcoialccpbmpnnblemnepkkaoxkb:us:dvorak:eng'; - languageHelper.removeInputMethod(dvorak); - assertEquals(1, languageHelper.languages.inputMethods.enabled.length); - - // Enable Swahili. - languageHelper.enableLanguage('sw'); - assertEquals(1, languageHelper.languages.inputMethods.enabled.length); - - // Add input methods for Swahili. - const sw = '_comp_ime_abcdefghijklmnopqrstuvwxyzabcdefxkb:sw:sw'; - const swUS = '_comp_ime_abcdefghijklmnopqrstuvwxyzabcdefxkb:us:sw'; - languageHelper.addInputMethod(sw); - languageHelper.addInputMethod(swUS); - assertEquals(3, languageHelper.languages.inputMethods.enabled.length); - - // Disable Swahili. The Swahili-only keyboard should be removed. - languageHelper.disableLanguage('sw'); - assertEquals(2, languageHelper.languages.inputMethods.enabled.length); - - // The US Swahili keyboard should still be enabled, because it supports - // English which is still enabled. - assertTrue(languageHelper.languages.inputMethods.enabled.some(function( - inputMethod) { - return inputMethod.id == swUS; - })); - }); - } + suiteSetup(function() { + CrSettingsPrefs.deferInitialization = true; + PolymerTest.clearBody(); }); + + setup(function() { + const settingsPrefs = document.createElement('settings-prefs'); + const settingsPrivate = + new settings.FakeSettingsPrivate(settings.getFakeLanguagePrefs()); + settingsPrefs.initialize(settingsPrivate); + document.body.appendChild(settingsPrefs); + + // Setup test browser proxy. + browserProxy = new settings.TestLanguagesBrowserProxy(); + settings.LanguagesBrowserProxyImpl.instance_ = browserProxy; + + // Setup fake languageSettingsPrivate API. + const languageSettingsPrivate = browserProxy.getLanguageSettingsPrivate(); + languageSettingsPrivate.setSettingsPrefs(settingsPrefs); + + languageHelper = document.createElement('settings-languages'); + + // Prefs would normally be data-bound to settings-languages. + test_util.fakeDataBind(settingsPrefs, languageHelper, 'prefs'); + + document.body.appendChild(languageHelper); + return languageHelper.whenReady().then(function() { + if (cr.isChromeOS || cr.isWindows) { + return browserProxy.whenCalled('getProspectiveUILanguage'); + } + }); + }); + + test('languages model', function() { + const languageSettingsPrivate = browserProxy.getLanguageSettingsPrivate(); + for (let i = 0; i < languageSettingsPrivate.languages.length; i++) { + assertEquals( + languageSettingsPrivate.languages[i].code, + languageHelper.languages.supported[i].code); + } + assertLanguageOrder(['en-US', 'sw']); + assertEquals('en', languageHelper.languages.translateTarget); + + // TODO(michaelpg): Test other aspects of the model. + }); + + test('get language', function() { + // If a language code is not found, try language without location. + lang = languageHelper.getLanguage('en-CN'); + assertEquals('en', lang.code); + + // The old language code for Hebriew is supported. + lang = languageHelper.getLanguage('iw'); + assertEquals('he', lang.code); + + // The 'no' macrolanguage is returned for Norsk Nynorsk. + lang = languageHelper.getLanguage('nn'); + assertEquals('no', lang.code); + }); + + test('modifying languages', function() { + assertTrue(languageHelper.isLanguageEnabled('en-US')); + assertTrue(languageHelper.isLanguageEnabled('sw')); + assertFalse(languageHelper.isLanguageEnabled('en-CA')); + + languageHelper.enableLanguage('en-CA'); + assertTrue(languageHelper.isLanguageEnabled('en-CA')); + languageHelper.disableLanguage('sw'); + assertFalse(languageHelper.isLanguageEnabled('sw')); + + // TODO(michaelpg): Test other modifications. + }); + + test('reorder languages', function() { + // New language is added at the end. + languageHelper.enableLanguage('en-CA'); + assertLanguageOrder(['en-US', 'sw', 'en-CA']); + + // Can move a language up. + languageHelper.moveLanguage('en-CA', true /* upDirection */); + assertLanguageOrder(['en-US', 'en-CA', 'sw']); + + // Can move a language down. + languageHelper.moveLanguage('en-US', false /* upDirection */); + assertLanguageOrder(['en-CA', 'en-US', 'sw']); + + // Can move a language to the front. + languageHelper.moveLanguageToFront('sw'); + const expectedOrder = ['sw', 'en-CA', 'en-US']; + assertLanguageOrder(expectedOrder); + + // Moving the first language up has no effect. + languageHelper.moveLanguage('sw', true /* upDirection */); + assertLanguageOrder(expectedOrder); + + // Moving the first language to top has no effect. + languageHelper.moveLanguageToFront('sw'); + assertLanguageOrder(expectedOrder); + + // Moving the last language down has no effect. + languageHelper.moveLanguage('en-US', false /* upDirection */); + assertLanguageOrder(expectedOrder); + }); + + if (cr.isChromeOS) { + test('modifying input methods', function() { + assertEquals(2, languageHelper.languages.inputMethods.enabled.length); + const inputMethods = languageHelper.getInputMethodsForLanguage('en-US'); + assertEquals(3, inputMethods.length); + + // We can remove one input method. + const dvorak = + '_comp_ime_fgoepimhcoialccpbmpnnblemnepkkaoxkb:us:dvorak:eng'; + languageHelper.removeInputMethod(dvorak); + assertEquals(1, languageHelper.languages.inputMethods.enabled.length); + + // Enable Swahili. + languageHelper.enableLanguage('sw'); + assertEquals(1, languageHelper.languages.inputMethods.enabled.length); + + // Add input methods for Swahili. + const sw = '_comp_ime_abcdefghijklmnopqrstuvwxyzabcdefxkb:sw:sw'; + const swUS = '_comp_ime_abcdefghijklmnopqrstuvwxyzabcdefxkb:us:sw'; + languageHelper.addInputMethod(sw); + languageHelper.addInputMethod(swUS); + assertEquals(3, languageHelper.languages.inputMethods.enabled.length); + + // Disable Swahili. The Swahili-only keyboard should be removed. + languageHelper.disableLanguage('sw'); + assertEquals(2, languageHelper.languages.inputMethods.enabled.length); + + // The US Swahili keyboard should still be enabled, because it supports + // English which is still enabled. + assertTrue(languageHelper.languages.inputMethods.enabled.some(function( + inputMethod) { + return inputMethod.id == swUS; + })); + }); + } });
diff --git a/chrome/test/data/webui/settings/settings_main_test.js b/chrome/test/data/webui/settings/settings_main_test.js index 37449c8..dd5640b6 100644 --- a/chrome/test/data/webui/settings/settings_main_test.js +++ b/chrome/test/data/webui/settings/settings_main_test.js
@@ -350,25 +350,6 @@ return assertPageVisibility('block', 'block'); }); - test('verify showChangePassword value', function() { - settings.Router.getInstance().navigateTo(settings.routes.BASIC); - Polymer.dom.flush(); - const basicPage = settingsMain.$$('settings-basic-page'); - assertTrue(!!basicPage); - assertFalse(basicPage.showChangePassword); - assertFalse(!!basicPage.$$('settings-change-password-page')); - - cr.webUIListenerCallback('change-password-visibility', true); - Polymer.dom.flush(); - assertTrue(basicPage.showChangePassword); - assertTrue(!!basicPage.$$('settings-change-password-page')); - - cr.webUIListenerCallback('change-password-visibility', false); - Polymer.dom.flush(); - assertFalse(basicPage.showChangePassword); - assertFalse(!!basicPage.$$('settings-change-password-page')); - }); - test('updates the title based on current route', function() { settings.Router.getInstance().navigateTo(settings.routes.BASIC); assertEquals(document.title, loadTimeData.getString('settings'));
diff --git a/chrome/test/data/webui/settings/test_languages_browser_proxy.js b/chrome/test/data/webui/settings/test_languages_browser_proxy.js index 0fc56c0..a1b048b 100644 --- a/chrome/test/data/webui/settings/test_languages_browser_proxy.js +++ b/chrome/test/data/webui/settings/test_languages_browser_proxy.js
@@ -30,6 +30,11 @@ getInputMethodPrivate() { return this.inputMethodPrivate_; } + + /** @param {!LanguageSettingsPrivate} languageSettingsPrivate */ + setLanguageSettingsPrivate(languageSettingsPrivate) { + this.languageSettingsPrivate_ = languageSettingsPrivate; + } } if (cr.isChromeOS || cr.isWindows) {
diff --git a/chrome/test/data/webui/tab_strip/tab_group_test.js b/chrome/test/data/webui/tab_strip/tab_group_test.js index 9f34bf4..3f78cc0 100644 --- a/chrome/test/data/webui/tab_strip/tab_group_test.js +++ b/chrome/test/data/webui/tab_strip/tab_group_test.js
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'chrome://tab-strip/tab.js'; import 'chrome://tab-strip/tab_group.js'; suite('TabGroup', () => { @@ -10,6 +11,8 @@ setup(() => { document.body.innerHTML = ''; tabGroupElement = document.createElement('tabstrip-tab-group'); + tabGroupElement.appendChild(document.createElement('tabstrip-tab')); + document.body.appendChild(tabGroupElement); }); test('UpdatesVisuals', () => { @@ -31,4 +34,25 @@ tabGroupElement.style.getPropertyValue( '--tabstrip-tab-group-text-color-rgb')); }); + + test('DraggableChipStaysInPlace', () => { + const originalChipRect = tabGroupElement.$('#chip').getBoundingClientRect(); + tabGroupElement.setDragging(true); + const newChipRect = tabGroupElement.$('#chip').getBoundingClientRect(); + assertEquals(originalChipRect.left, newChipRect.left); + assertEquals(originalChipRect.top, newChipRect.top); + assertEquals(originalChipRect.right, newChipRect.right); + assertEquals(originalChipRect.bottom, newChipRect.bottom); + }); + + test('DraggableChipStaysInPlaceInRTL', () => { + document.documentElement.dir = 'rtl'; + const originalChipRect = tabGroupElement.$('#chip').getBoundingClientRect(); + tabGroupElement.setDragging(true); + const newChipRect = tabGroupElement.$('#chip').getBoundingClientRect(); + assertEquals(originalChipRect.left, newChipRect.left); + assertEquals(originalChipRect.top, newChipRect.top); + assertEquals(originalChipRect.right, newChipRect.right); + assertEquals(originalChipRect.bottom, newChipRect.bottom); + }); });
diff --git a/chrome/test/data/webui/tab_strip/tab_list_test.js b/chrome/test/data/webui/tab_strip/tab_list_test.js index e537f3d5..2e7c9a5 100644 --- a/chrome/test/data/webui/tab_strip/tab_list_test.js +++ b/chrome/test/data/webui/tab_strip/tab_list_test.js
@@ -387,6 +387,16 @@ assertEquals(tabGroup.children[1].tab.id, originalTabInGroup.id); }); + test('HandleReplacedGroupId', () => { + webUIListenerCallback( + 'tab-group-state-changed', tabs[1].id, tabs[1].index, 'oldGroupId'); + const group = getTabGroups()[0]; + assertEquals('oldGroupId', group.dataset.groupId); + + webUIListenerCallback('tab-group-id-replaced', 'oldGroupId', 'newGroupId'); + assertEquals('newGroupId', group.dataset.groupId); + }); + test('removes a tab when tab is removed from current window', async () => { const tabToRemove = tabs[0]; webUIListenerCallback('tab-removed', tabToRemove.id);
diff --git a/chromeos/network/device_state.cc b/chromeos/network/device_state.cc index 1b18bc2..a066a1a 100644 --- a/chromeos/network/device_state.cc +++ b/chromeos/network/device_state.cc
@@ -120,6 +120,10 @@ return false; } +bool DeviceState::IsActive() const { + return true; +} + void DeviceState::IPConfigPropertiesChanged(const std::string& ip_config_path, const base::Value& properties) { NET_LOG(EVENT) << "IPConfig for: " << path()
diff --git a/chromeos/network/device_state.h b/chromeos/network/device_state.h index 4aa84ed..88845a6 100644 --- a/chromeos/network/device_state.h +++ b/chromeos/network/device_state.h
@@ -26,6 +26,7 @@ // ManagedState overrides bool PropertyChanged(const std::string& key, const base::Value& value) override; + bool IsActive() const override; void IPConfigPropertiesChanged(const std::string& ip_config_path, const base::Value& properties);
diff --git a/chromeos/network/managed_state.h b/chromeos/network/managed_state.h index c767b8f7..e620141a 100644 --- a/chromeos/network/managed_state.h +++ b/chromeos/network/managed_state.h
@@ -72,6 +72,10 @@ // properties are included. virtual void GetStateProperties(base::Value* dictionary) const; + // Returns true if a state is "Active". For networks that means connected, + // connecting, or activating. Devices are always "active". + virtual bool IsActive() const = 0; + ManagedType managed_type() const { return managed_type_; } const std::string& path() const { return path_; } const std::string& name() const { return name_; }
diff --git a/chromeos/network/network_configuration_handler.cc b/chromeos/network/network_configuration_handler.cc index 0d55403..3713f64 100644 --- a/chromeos/network/network_configuration_handler.cc +++ b/chromeos/network/network_configuration_handler.cc
@@ -247,7 +247,7 @@ const std::string& service_path, const network_handler::DictionaryResultCallback& callback, const network_handler::ErrorCallback& error_callback) { - NET_LOG(USER) << "GetShillProperties: " << service_path; + NET_LOG(DEBUG) << "GetShillProperties: " << service_path; const NetworkState* network_state = network_state_handler_->GetNetworkState(service_path);
diff --git a/chromeos/network/network_state.cc b/chromeos/network/network_state.cc index 666031b..275ba86f 100644 --- a/chromeos/network/network_state.cc +++ b/chromeos/network/network_state.cc
@@ -330,6 +330,11 @@ } } +bool NetworkState::IsActive() const { + return IsConnectingOrConnected() || + activation_state() == shill::kActivationStateActivating; +} + void NetworkState::IPConfigPropertiesChanged(const base::Value& properties) { if (properties.DictEmpty()) { ipv4_config_.reset(); @@ -476,11 +481,6 @@ StateIsConnected(connection_state_)); } -bool NetworkState::IsActive() const { - return IsConnectingOrConnected() || - activation_state() == shill::kActivationStateActivating; -} - bool NetworkState::IsOnline() const { return connection_state() == shill::kStateOnline; }
diff --git a/chromeos/network/network_state.h b/chromeos/network/network_state.h index 6b4d55a..c372821 100644 --- a/chromeos/network/network_state.h +++ b/chromeos/network/network_state.h
@@ -60,6 +60,7 @@ const base::Value& value) override; bool InitialPropertiesReceived(const base::Value& properties) override; void GetStateProperties(base::Value* dictionary) const override; + bool IsActive() const override; // Called when the IPConfig properties may have changed. |properties| is // expected to be of type DICTIONARY. @@ -180,9 +181,6 @@ bool IsConnectingState() const; bool IsConnectingOrConnected() const; - // Similar to IsConnectingOrConnected but also checks activation state. - bool IsActive() const; - // Returns true if |connection_state_| is online. bool IsOnline() const;
diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc index 8ee6815e..0735c5b 100644 --- a/chromeos/network/network_state_handler.cc +++ b/chromeos/network/network_state_handler.cc
@@ -2020,10 +2020,11 @@ ? "Device" : state->path() == default_network_path_ ? "DefaultNetwork" : "Network"; - device_event_log::LogLevel log_level = - (key == shill::kErrorProperty || key == shill::kErrorDetailsProperty) - ? device_event_log::LOG_LEVEL_ERROR - : device_event_log::LOG_LEVEL_EVENT; + device_event_log::LogLevel log_level = device_event_log::LOG_LEVEL_EVENT; + if (key == shill::kErrorProperty || key == shill::kErrorDetailsProperty) + log_level = device_event_log::LOG_LEVEL_ERROR; + else if (key == shill::kSignalStrengthProperty && !state->IsActive()) + log_level = device_event_log::LOG_LEVEL_DEBUG; DEVICE_LOG(::device_event_log::LOG_TYPE_NETWORK, log_level) << type_str << "PropertyUpdated: " << state->path() << " (" << state->name() << ") " << key << " = " << value;
diff --git a/components/device_event_log/device_event_log_impl.cc b/components/device_event_log/device_event_log_impl.cc index 29a27ba..9134908 100644 --- a/components/device_event_log/device_event_log_impl.cc +++ b/components/device_event_log/device_event_log_impl.cc
@@ -475,9 +475,9 @@ : file_line(file_line), log_type(log_type), log_level(log_level), - event(event), time(base::Time::Now()), count(1) { + base::TrimWhitespaceASCII(event, base::TRIM_ALL, &this->event); if (filedesc) { file = filedesc; size_t last_slash_pos = file.find_last_of("\\/");
diff --git a/components/feed/core/proto/BUILD.gn b/components/feed/core/proto/BUILD.gn index e552d80..003907e 100644 --- a/components/feed/core/proto/BUILD.gn +++ b/components/feed/core/proto/BUILD.gn
@@ -40,12 +40,31 @@ "ui/stream/stream_structure.proto", "v2/store.proto", "wire/action_payload.proto", + "wire/action_payload_for_test.proto", + "wire/action_request.proto", + "wire/action_type.proto", + "wire/capability.proto", + "wire/client_info.proto", + "wire/consistency_token.proto", "wire/content_id.proto", "wire/data_operation.proto", + "wire/display_info.proto", "wire/feature.proto", + "wire/feed_action.proto", + "wire/feed_action_query_data.proto", + "wire/feed_action_request.proto", + "wire/feed_action_response.proto", + "wire/feed_query.proto", + "wire/feed_request.proto", + "wire/feed_response.proto", + "wire/mockserver/mock_server.proto", "wire/payload_metadata.proto", "wire/piet_shared_state_item.proto", + "wire/request.proto", + "wire/response.proto", "wire/semantic_properties.proto", + "wire/token.proto", + "wire/version.proto", ] }
diff --git a/components/feed/core/proto/libraries/api/internal/stream_data.proto b/components/feed/core/proto/libraries/api/internal/stream_data.proto index f506539..671982ff 100644 --- a/components/feed/core/proto/libraries/api/internal/stream_data.proto +++ b/components/feed/core/proto/libraries/api/internal/stream_data.proto
@@ -72,8 +72,7 @@ optional string content_id = 1; oneof share_state { // A Piet shared state item. - components.feed.core.proto.wire.PietSharedStateItem piet_shared_state_item = - 2; + feedwire.PietSharedStateItem piet_shared_state_item = 2; } } @@ -157,7 +156,7 @@ // The consistency token used to ensure that we are recording actions to // the same server store. - components.feed.core.proto.wire.ConsistencyToken consistency_token = 9; + feedwire.ConsistencyToken consistency_token = 9; } reserved 8; } @@ -228,7 +227,7 @@ // When the action was recorded optional int64 timestamp_seconds = 4; - optional wire.ActionPayload payload = 6; + optional feedwire.ActionPayload payload = 6; reserved 1, 5; // deprecated fields }
diff --git a/components/feed/core/proto/ui/action/ui_feed_action.proto b/components/feed/core/proto/ui/action/ui_feed_action.proto index 12f7c9c..4870d99 100644 --- a/components/feed/core/proto/ui/action/ui_feed_action.proto +++ b/components/feed/core/proto/ui/action/ui_feed_action.proto
@@ -106,9 +106,9 @@ // latest frequency token as the value of this query param. optional string consistency_token_query_param_name = 2; // The content ID that was interacted with to cause a URL open. - optional components.feed.core.proto.wire.ContentId content_id = 3; + optional feedwire.ContentId content_id = 3; // Roundtripped server data on a per-action level. - optional components.feed.core.proto.wire.ActionPayload payload = 4; + optional feedwire.ActionPayload payload = 4; } // Data needed by Stream to open a context menu. @@ -121,19 +121,19 @@ // The ContentId needed by the server to suppress reshowing the dismissed // content. This will usually be the ContentId of the card which holds the // content, not the ContentId of the content itself. - optional components.feed.core.proto.wire.ContentId content_id = 1; + optional feedwire.ContentId content_id = 1; // The DataOperations which are needed to actually perform the dismiss on the // client. This is typically a singleton list of a remove operation on the // Cluster that the content belongs to. - repeated components.feed.core.proto.wire.DataOperation data_operations = 2; + repeated feedwire.DataOperation data_operations = 2; // Data used by the client to show a confirmation message with option to undo. // This confirmation and undo option will only appear if the UndoAction is // present and the client can handle this capability. optional UndoAction undo_action = 3; // Roundtripped server data on a per-action level. - optional components.feed.core.proto.wire.ActionPayload payload = 4; + optional feedwire.ActionPayload payload = 4; } // Data needed by the client to handle the not interested action. @@ -143,9 +143,9 @@ // present and the client can handle this capability. optional UndoAction undo_action = 1; // The data needed by Stream to preform the dismiss. - repeated components.feed.core.proto.wire.DataOperation data_operations = 2; + repeated feedwire.DataOperation data_operations = 2; // Roundtripped server data on a per-action level. - optional components.feed.core.proto.wire.ActionPayload payload = 3; + optional feedwire.ActionPayload payload = 3; enum RecordedInterestType { UNKNOWN_INTEREST_TYPE = 0; TOPIC = 1;
diff --git a/components/feed/core/proto/ui/stream/stream_structure.proto b/components/feed/core/proto/ui/stream/stream_structure.proto index b529dbe..5cc7ca6 100644 --- a/components/feed/core/proto/ui/stream/stream_structure.proto +++ b/components/feed/core/proto/ui/stream/stream_structure.proto
@@ -19,9 +19,7 @@ // Top level feature which shows a stream of cards. Provides any UI information // which may be needed in order to render the stream of cards. message Stream { - extend components.feed.core.proto.wire.Feature { - optional Stream stream_extension = 185431437; - } + extend feedwire.Feature { optional Stream stream_extension = 185431437; } // Empty for now as don't support any custom information. } @@ -29,9 +27,7 @@ // Feature which represents a cluster in a Stream. May have a Card or Content // as children. message Cluster { - extend components.feed.core.proto.wire.Feature { - optional Cluster cluster_extension = 190812910; - } + extend feedwire.Feature { optional Cluster cluster_extension = 190812910; } // Empty for now as we don't support any custom information. } @@ -39,9 +35,7 @@ // Experimental feature which represents a carousel in a Stream. May have a list // of Cards or Content as children. message Carousel { - extend components.feed.core.proto.wire.Feature { - optional Carousel carousel_extension = 244251946; - } + extend feedwire.Feature { optional Carousel carousel_extension = 244251946; } // Please use CL numbers you own for extension numbers. extensions 10000 to max; @@ -50,9 +44,7 @@ // Feature which represents a full card in a Stream. Allows metadata to be sent // to describe how to render the card. message Card { - extend components.feed.core.proto.wire.Feature { - optional Card card_extension = 185431438; - } + extend feedwire.Feature { optional Card card_extension = 185431438; } // Please use CL numbers you own for extension numbers. extensions 10000 to max; @@ -98,9 +90,7 @@ // inside or outside a card. Actual data on what to display will be sent on an // extension. message Content { - extend components.feed.core.proto.wire.Feature { - optional Content content_extension = 185431439; - } + extend feedwire.Feature { optional Content content_extension = 185431439; } enum Type { UNKNOWN_CONTENT = 0; @@ -122,7 +112,7 @@ // Content Ids of Piet Shared States which should be provided to Piet in order // to show its content. - repeated components.feed.core.proto.wire.ContentId piet_shared_states = 1; + repeated feedwire.ContentId piet_shared_states = 1; // The Piet frame to render. optional components.feed.core.proto.ui.piet.Frame frame = 2;
diff --git a/components/feed/core/proto/v2/store.proto b/components/feed/core/proto/v2/store.proto index 8ef0dbf..4fcc9e9 100644 --- a/components/feed/core/proto/v2/store.proto +++ b/components/feed/core/proto/v2/store.proto
@@ -40,7 +40,7 @@ // Data about the Feed stream. There is at most one instance of StreamData. message StreamData { // Root ContentId, as provided by the server. - components.feed.core.proto.wire.ContentId content_id = 1; + feedwire.ContentId content_id = 1; // Token used to request a 'more' request to the server. bytes next_page_token = 2; // Token used to read or write to the same storage. @@ -48,21 +48,21 @@ // The unix timestamp in milliseconds that the most recent content was added. int64 last_added_time_millis = 4; // List of all clusters, in order they would be shown in the stream. - repeated components.feed.core.proto.wire.ContentId cluster_ids = 5; + repeated feedwire.ContentId cluster_ids = 5; // List of all stale clusters. Stale clusters can be removed when no session // references them. - repeated components.feed.core.proto.wire.ContentId stale_cluster_ids = 6; + repeated feedwire.ContentId stale_cluster_ids = 6; } message Cluster { - components.feed.core.proto.wire.ContentId content_id = 1; - components.feed.core.proto.wire.SemanticProperties semantic_properties = 2; + feedwire.ContentId content_id = 1; + feedwire.SemanticProperties semantic_properties = 2; repeated Card cards = 3; } message Card { - components.feed.core.proto.wire.ContentId card_id = 1; - components.feed.core.proto.wire.SemanticProperties semantic_properties = 2; + feedwire.ContentId card_id = 1; + feedwire.SemanticProperties semantic_properties = 2; // This may not be present if Card is part of a DataOperation. Content content = 3; // All actions bound to this card or content. @@ -78,8 +78,8 @@ message Content { // The parent Card's ContentId. - components.feed.core.proto.wire.ContentId content_id = 1; - components.feed.core.proto.wire.SemanticProperties semantic_properties = 2; + feedwire.ContentId content_id = 1; + feedwire.SemanticProperties semantic_properties = 2; enum ContentType { UNKNOWN_CONTENT = 0; @@ -102,7 +102,7 @@ message PietContent { // Content Ids of Piet Shared States which should be provided to Piet in order // to show its content. - repeated components.feed.core.proto.wire.ContentId piet_shared_states = 1; + repeated feedwire.ContentId piet_shared_states = 1; // The Piet frame to render. This is the same frame as sent over the wire, // except the action extensions have been replaced by ui.Action. @@ -111,9 +111,8 @@ // This represents a shared state item. message StreamSharedState { - components.feed.core.proto.wire.ContentId content_id = 1; - components.feed.core.proto.wire.PietSharedStateItem piet_shared_state_item = - 2; + feedwire.ContentId content_id = 1; + feedwire.PietSharedStateItem piet_shared_state_item = 2; } // An action that should be eventually uploaded, unless it is undone. @@ -123,17 +122,17 @@ DISMISS = 1; } Type action = 1; - components.feed.core.proto.wire.ContentId feature_content_id = 2; + feedwire.ContentId feature_content_id = 2; // When the action was recorded int64 timestamp_seconds = 3; } // An action ready to be uploaded. message StreamUploadableAction { - components.feed.core.proto.wire.ContentId feature_content_id = 1; + feedwire.ContentId feature_content_id = 1; // The number of time this action was attempted to be recorded int32 upload_attempts = 2; // Unix timestamp (seconds) when the action was recorded int64 timestamp_seconds = 3; - components.feed.core.proto.wire.ActionPayload payload = 4; + feedwire.ActionPayload payload = 4; }
diff --git a/components/feed/core/proto/wire/action_payload.proto b/components/feed/core/proto/wire/action_payload.proto index e7923e73..dd3db00 100644 --- a/components/feed/core/proto/wire/action_payload.proto +++ b/components/feed/core/proto/wire/action_payload.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/action_payload_for_test.proto b/components/feed/core/proto/wire/action_payload_for_test.proto index b382bc1..539d680 100644 --- a/components/feed/core/proto/wire/action_payload_for_test.proto +++ b/components/feed/core/proto/wire/action_payload_for_test.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME; @@ -19,7 +19,7 @@ // The mid that represents the topic of the story on the card optional string id = 1; - extend components.feed.core.proto.wire.ActionPayload { + extend feedwire.ActionPayload { optional ActionPayloadForTest action_payload_for_test_extension = 2; } }
diff --git a/components/feed/core/proto/wire/action_request.proto b/components/feed/core/proto/wire/action_request.proto index 5e47d7e..cb68eb6 100644 --- a/components/feed/core/proto/wire/action_request.proto +++ b/components/feed/core/proto/wire/action_request.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/action_type.proto b/components/feed/core/proto/wire/action_type.proto index efc1ddf8..a630f50 100644 --- a/components/feed/core/proto/wire/action_type.proto +++ b/components/feed/core/proto/wire/action_type.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/capability.proto b/components/feed/core/proto/wire/capability.proto index 48ac07c..14e2027 100644 --- a/components/feed/core/proto/wire/capability.proto +++ b/components/feed/core/proto/wire/capability.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/client_info.proto b/components/feed/core/proto/wire/client_info.proto index 4138682..59426d99 100644 --- a/components/feed/core/proto/wire/client_info.proto +++ b/components/feed/core/proto/wire/client_info.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/consistency_token.proto b/components/feed/core/proto/wire/consistency_token.proto index f172b36..0aeed759 100644 --- a/components/feed/core/proto/wire/consistency_token.proto +++ b/components/feed/core/proto/wire/consistency_token.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/content_id.proto b/components/feed/core/proto/wire/content_id.proto index f35d865..5df096d8 100644 --- a/components/feed/core/proto/wire/content_id.proto +++ b/components/feed/core/proto/wire/content_id.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/data_operation.proto b/components/feed/core/proto/wire/data_operation.proto index bc7f178..ac61d46 100644 --- a/components/feed/core/proto/wire/data_operation.proto +++ b/components/feed/core/proto/wire/data_operation.proto
@@ -8,7 +8,7 @@ import "components/feed/core/proto/wire/payload_metadata.proto"; import "components/feed/core/proto/ui/piet/piet.proto"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/display_info.proto b/components/feed/core/proto/wire/display_info.proto index ba2bd6b..d8f5b85 100644 --- a/components/feed/core/proto/wire/display_info.proto +++ b/components/feed/core/proto/wire/display_info.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/feature.proto b/components/feed/core/proto/wire/feature.proto index 9f0c4c01..f695b80 100644 --- a/components/feed/core/proto/wire/feature.proto +++ b/components/feed/core/proto/wire/feature.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/feed_action.proto b/components/feed/core/proto/wire/feed_action.proto index 8b04bc8..29beef4 100644 --- a/components/feed/core/proto/wire/feed_action.proto +++ b/components/feed/core/proto/wire/feed_action.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/feed_action_query_data.proto b/components/feed/core/proto/wire/feed_action_query_data.proto index ce228c1..2c6779e 100644 --- a/components/feed/core/proto/wire/feed_action_query_data.proto +++ b/components/feed/core/proto/wire/feed_action_query_data.proto
@@ -7,7 +7,7 @@ import "components/feed/core/proto/wire/action_type.proto"; import "components/feed/core/proto/wire/semantic_properties.proto"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/feed_action_request.proto b/components/feed/core/proto/wire/feed_action_request.proto index 72fda0e..9bf1102 100644 --- a/components/feed/core/proto/wire/feed_action_request.proto +++ b/components/feed/core/proto/wire/feed_action_request.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/feed_action_response.proto b/components/feed/core/proto/wire/feed_action_response.proto index 5ea0e39..570ecf2 100644 --- a/components/feed/core/proto/wire/feed_action_response.proto +++ b/components/feed/core/proto/wire/feed_action_response.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/feed_query.proto b/components/feed/core/proto/wire/feed_query.proto index 76a9414..6417a66 100644 --- a/components/feed/core/proto/wire/feed_query.proto +++ b/components/feed/core/proto/wire/feed_query.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/feed_request.proto b/components/feed/core/proto/wire/feed_request.proto index 162b640..75b6724 100644 --- a/components/feed/core/proto/wire/feed_request.proto +++ b/components/feed/core/proto/wire/feed_request.proto
@@ -11,7 +11,7 @@ import "components/feed/core/proto/wire/feed_query.proto"; import "components/feed/core/proto/wire/request.proto"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/feed_response.proto b/components/feed/core/proto/wire/feed_response.proto index 7457800..858be4a 100644 --- a/components/feed/core/proto/wire/feed_response.proto +++ b/components/feed/core/proto/wire/feed_response.proto
@@ -8,7 +8,7 @@ import "components/feed/core/proto/wire/data_operation.proto"; import "components/feed/core/proto/wire/response.proto"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/mockserver/mock_server.proto b/components/feed/core/proto/wire/mockserver/mock_server.proto index 67a2c39..242053a 100644 --- a/components/feed/core/proto/wire/mockserver/mock_server.proto +++ b/components/feed/core/proto/wire/mockserver/mock_server.proto
@@ -14,7 +14,7 @@ message MockServer { // The initial response - optional components.feed.core.proto.wire.Response initial_response = 1; + optional feedwire.Response initial_response = 1; // conditional responses represent responses for paged content repeated ConditionalResponse conditional_responses = 2; @@ -25,7 +25,7 @@ /** This represents a response providing updates to the stream. */ message MockUpdate { // The response with the push update - optional components.feed.core.proto.wire.Response response = 1; + optional feedwire.Response response = 1; // The amount of time to wait, in milliseconds, before the push is triggered. // This is relative to the time the GCL file is loaded. @@ -38,5 +38,5 @@ optional bytes continuation_token = 1; // The response to use - optional components.feed.core.proto.wire.Response response = 2; + optional feedwire.Response response = 2; }
diff --git a/components/feed/core/proto/wire/payload_metadata.proto b/components/feed/core/proto/wire/payload_metadata.proto index e40e0c4..9195803 100644 --- a/components/feed/core/proto/wire/payload_metadata.proto +++ b/components/feed/core/proto/wire/payload_metadata.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/piet_shared_state_item.proto b/components/feed/core/proto/wire/piet_shared_state_item.proto index c57a47c..427eef1 100644 --- a/components/feed/core/proto/wire/piet_shared_state_item.proto +++ b/components/feed/core/proto/wire/piet_shared_state_item.proto
@@ -7,7 +7,7 @@ import "components/feed/core/proto/ui/piet/piet.proto"; import "components/feed/core/proto/wire/content_id.proto"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/request.proto b/components/feed/core/proto/wire/request.proto index d26e808..c377a15 100644 --- a/components/feed/core/proto/wire/request.proto +++ b/components/feed/core/proto/wire/request.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/response.proto b/components/feed/core/proto/wire/response.proto index 81e4f26..39f0a3d 100644 --- a/components/feed/core/proto/wire/response.proto +++ b/components/feed/core/proto/wire/response.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/semantic_properties.proto b/components/feed/core/proto/wire/semantic_properties.proto index c6327b8c..939c24ab 100644 --- a/components/feed/core/proto/wire/semantic_properties.proto +++ b/components/feed/core/proto/wire/semantic_properties.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/proto/wire/token.proto b/components/feed/core/proto/wire/token.proto index 8cdb877..6426552 100644 --- a/components/feed/core/proto/wire/token.proto +++ b/components/feed/core/proto/wire/token.proto
@@ -6,7 +6,7 @@ import "components/feed/core/proto/wire/feature.proto"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME; @@ -15,9 +15,7 @@ // A continuation token (paging token). message Token { - extend components.feed.core.proto.wire.Feature { - optional Token token_extension = 194964015; - } + extend feedwire.Feature { optional Token token_extension = 194964015; } // Indicates the last position of the current content for a parent. A request // can be made using the next_page_token to get additional features which will
diff --git a/components/feed/core/proto/wire/version.proto b/components/feed/core/proto/wire/version.proto index 164753b..f96d979 100644 --- a/components/feed/core/proto/wire/version.proto +++ b/components/feed/core/proto/wire/version.proto
@@ -4,7 +4,7 @@ syntax = "proto2"; -package components.feed.core.proto.wire; +package feedwire; option optimize_for = LITE_RUNTIME;
diff --git a/components/feed/core/v2/BUILD.gn b/components/feed/core/v2/BUILD.gn index 3b172fb..09eee44 100644 --- a/components/feed/core/v2/BUILD.gn +++ b/components/feed/core/v2/BUILD.gn
@@ -10,6 +10,10 @@ source_set("feed_core_v2") { sources = [ + "feed_network.cc", + "feed_network.h", + "feed_network_impl.cc", + "feed_network_impl.h", "feed_stream.cc", "feed_stream.h", "feed_stream_api.h", @@ -21,14 +25,29 @@ "//components/feed/core/common:feed_core_common", "//components/offline_pages/task:task", "//components/prefs", + "//components/signin/public/identity_manager", + "//components/variations", + "//components/variations/net", + "//net", + "//services/network/public/cpp", + "//services/network/public/mojom", + "//third_party/zlib/google:compression_utils", ] - public_deps = [ "//base" ] + public_deps = [ + "//base", + "//components/feed/core/common:feed_core_common", + "//components/feed/core/proto:proto_v2", + ] } source_set("core_unit_tests") { testonly = true - sources = [ "feed_stream_unittest.cc" ] + sources = [ + "feed_network_impl_unittest.cc", + "feed_stream_unittest.cc", + ] + deps = [ ":feed_core_v2", "//base", @@ -36,6 +55,13 @@ "//components/feed/core:feed_core", "//components/feed/core/common:feed_core_common", "//components/prefs:test_support", + "//components/signin/public/identity_manager", + "//components/signin/public/identity_manager:test_support", + "//net:test_support", + "//services/network:test_support", + "//services/network/public/cpp", + "//services/network/public/mojom", "//testing/gtest", + "//third_party/zlib/google:compression_utils", ] }
diff --git a/components/feed/core/v2/feed_network.cc b/components/feed/core/v2/feed_network.cc new file mode 100644 index 0000000..ebcfe7b --- /dev/null +++ b/components/feed/core/v2/feed_network.cc
@@ -0,0 +1,30 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/feed/core/v2/feed_network.h" + +#include "components/feed/core/proto/wire/action_request.pb.h" +#include "components/feed/core/proto/wire/feed_action_response.pb.h" +#include "components/feed/core/proto/wire/request.pb.h" +#include "components/feed/core/proto/wire/response.pb.h" + +namespace feed { + +FeedNetwork::QueryRequestResult::QueryRequestResult() = default; +FeedNetwork::QueryRequestResult::~QueryRequestResult() = default; +FeedNetwork::QueryRequestResult::QueryRequestResult(QueryRequestResult&&) = + default; +FeedNetwork::QueryRequestResult& FeedNetwork::QueryRequestResult::operator=( + QueryRequestResult&&) = default; + +FeedNetwork::ActionRequestResult::ActionRequestResult() = default; +FeedNetwork::ActionRequestResult::~ActionRequestResult() = default; +FeedNetwork::ActionRequestResult::ActionRequestResult(ActionRequestResult&&) = + default; +FeedNetwork::ActionRequestResult& FeedNetwork::ActionRequestResult::operator=( + ActionRequestResult&&) = default; + +FeedNetwork::~FeedNetwork() = default; + +} // namespace feed
diff --git a/components/feed/core/v2/feed_network.h b/components/feed/core/v2/feed_network.h new file mode 100644 index 0000000..8a25a23 --- /dev/null +++ b/components/feed/core/v2/feed_network.h
@@ -0,0 +1,69 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_FEED_CORE_V2_FEED_NETWORK_H_ +#define COMPONENTS_FEED_CORE_V2_FEED_NETWORK_H_ + +#include <memory> +#include "base/callback.h" + +namespace feedwire { +class ActionRequest; +class FeedActionResponse; +class Request; +class Response; +} // namespace feedwire + +namespace feed { + +class FeedNetwork { + public: + // Result of SendQueryRequest. + struct QueryRequestResult { + QueryRequestResult(); + ~QueryRequestResult(); + QueryRequestResult(QueryRequestResult&&); + QueryRequestResult& operator=(QueryRequestResult&&); + // HTTP status code if one was received, 0 otherwise. + int32_t status_code = 0; + // Response body if one was received. + std::unique_ptr<feedwire::Response> response_body; + }; + + // Result of SendActionRequest. + struct ActionRequestResult { + ActionRequestResult(); + ~ActionRequestResult(); + ActionRequestResult(ActionRequestResult&&); + ActionRequestResult& operator=(ActionRequestResult&&); + // HTTP status code if one was received, 0 otherwise. + int32_t status_code = 0; + // Response body if one was received. + std::unique_ptr<feedwire::FeedActionResponse> response_body; + }; + + virtual ~FeedNetwork(); + + // Send a feedwire::Request, and receive the response in |callback|. + // |callback| will be called unless the request is canceled with + // |CancelRequests()|. + virtual void SendQueryRequest( + const feedwire::Request& request, + base::OnceCallback<void(QueryRequestResult)> callback) = 0; + + // Send a feedwire::ActionRequest, and receive the response in |callback|. + // |callback| will be called unless the request is canceled with + // |CancelRequests()|. + virtual void SendActionRequest( + const feedwire::ActionRequest& request, + base::OnceCallback<void(ActionRequestResult)> callback) = 0; + + // Cancels all pending requests immediately. This could be used, for example, + // if there are pending requests for a user who just signed out. + virtual void CancelRequests() = 0; +}; + +} // namespace feed + +#endif // COMPONENTS_FEED_CORE_V2_FEED_NETWORK_H_
diff --git a/components/feed/core/v2/feed_network_impl.cc b/components/feed/core/v2/feed_network_impl.cc new file mode 100644 index 0000000..d8cce0b --- /dev/null +++ b/components/feed/core/v2/feed_network_impl.cc
@@ -0,0 +1,432 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/feed/core/v2/feed_network_impl.h" +#include "base/bind.h" +#include "base/containers/flat_set.h" +#include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" +#include "base/time/tick_clock.h" +#include "base/time/time.h" +#include "components/feed/core/common/pref_names.h" +#include "components/feed/core/proto/wire/action_request.pb.h" +#include "components/feed/core/proto/wire/feed_action_response.pb.h" +#include "components/feed/core/proto/wire/request.pb.h" +#include "components/feed/core/proto/wire/response.pb.h" +#include "components/prefs/pref_service.h" +#include "components/signin/public/identity_manager/access_token_info.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h" +#include "components/signin/public/identity_manager/scope_set.h" +#include "components/variations/net/variations_http_headers.h" +#include "net/base/load_flags.h" +#include "net/base/url_util.h" +#include "net/http/http_response_headers.h" +#include "net/http/http_status_code.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/resource_request_body.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/simple_url_loader.h" +#include "third_party/zlib/google/compression_utils.h" + +namespace feed { +namespace { +constexpr char kAuthenticationScope[] = + "https://www.googleapis.com/auth/googlenow"; +constexpr char kApplicationOctetStream[] = "application/octet-stream"; +constexpr base::TimeDelta kNetworkTimeout = base::TimeDelta::FromSeconds(30); +using RawResponse = FeedNetworkImpl::RawResponse; +} // namespace + +struct FeedNetworkImpl::RawResponse { + // A union of net::Error (if the request failed) and the http + // status code(if the request succeeded in reaching the server). + int32_t status_code; + // HTTP response body. + std::string response_bytes; +}; + +namespace { +template <typename RESULT> +void ParseAndForwardResponse(base::OnceCallback<void(RESULT)> result_callback, + RawResponse raw_response) { + RESULT result; + result.status_code = raw_response.status_code; + if (result.status_code == 200) { + auto response_message = std::make_unique<typename decltype( + result.response_body)::element_type>(); + if (response_message->ParseFromString(raw_response.response_bytes)) { + result.response_body = std::move(response_message); + } + } + std::move(result_callback).Run(std::move(result)); +} + +void AddMothershipPayloadQueryParams(bool is_post, + const std::string& payload, + const std::string& language_tag, + GURL* url) { + if (!is_post) + *url = net::AppendQueryParameter(*url, "reqpld", payload); + *url = net::AppendQueryParameter(*url, "fmt", "bin"); + if (!language_tag.empty()) + *url = net::AppendQueryParameter(*url, "hl", language_tag); +} + +} // namespace + +// Each NetworkFetch instance represents a single "logical" fetch that ends by +// calling the associated callback. Network fetches will actually attempt two +// fetches if there is a signed in user; the first to retrieve an access token, +// and the second to the specified url. +class FeedNetworkImpl::NetworkFetch { + public: + NetworkFetch(const GURL& url, + const std::string& request_type, + std::string request_body, + signin::IdentityManager* identity_manager, + network::SharedURLLoaderFactory* loader_factory, + const std::string& api_key, + const base::TickClock* tick_clock, + PrefService* pref_service) + : url_(url), + request_type_(request_type), + request_body_(std::move(request_body)), + identity_manager_(identity_manager), + loader_factory_(loader_factory), + api_key_(api_key), + tick_clock_(tick_clock), + entire_send_start_ticks_(tick_clock_->NowTicks()), + pref_service_(pref_service) { + // Apply the host override (from snippets-internals). + std::string host_override = + pref_service_->GetString(feed::prefs::kHostOverrideHost); + if (!host_override.empty()) { + GURL override_host_url(host_override); + if (override_host_url.is_valid()) { + GURL::Replacements replacements; + replacements.SetSchemeStr(override_host_url.scheme_piece()); + replacements.SetHostStr(override_host_url.host_piece()); + replacements.SetPortStr(override_host_url.port_piece()); + url_ = url_.ReplaceComponents(replacements); + host_overridden_ = true; + } + } + } + ~NetworkFetch() = default; + NetworkFetch(const NetworkFetch&) = delete; + NetworkFetch& operator=(const NetworkFetch&) = delete; + + void Start(base::OnceCallback<void(RawResponse)> done_callback) { + done_callback_ = std::move(done_callback); + + if (!identity_manager_->HasPrimaryAccount()) { + StartLoader(); + return; + } + + StartAccessTokenFetch(); + } + + private: + void StartAccessTokenFetch() { + signin::ScopeSet scopes{kAuthenticationScope}; + // It's safe to pass base::Unretained(this) since deleting the token fetcher + // will prevent the callback from being completed. + token_fetcher_ = std::make_unique<signin::PrimaryAccountAccessTokenFetcher>( + "feed", identity_manager_, scopes, + base::BindOnce(&NetworkFetch::AccessTokenFetchFinished, + base::Unretained(this), tick_clock_->NowTicks()), + signin::PrimaryAccountAccessTokenFetcher::Mode::kWaitUntilAvailable); + } + + void AccessTokenFetchFinished(base::TimeTicks token_start_ticks, + GoogleServiceAuthError error, + signin::AccessTokenInfo access_token_info) { + UMA_HISTOGRAM_ENUMERATION( + "ContentSuggestions.Feed.Network.TokenFetchStatus", error.state(), + GoogleServiceAuthError::NUM_STATES); + + base::TimeDelta token_duration = + tick_clock_->NowTicks() - token_start_ticks; + UMA_HISTOGRAM_MEDIUM_TIMES("ContentSuggestions.Feed.Network.TokenDuration", + token_duration); + + access_token_ = access_token_info.token; + StartLoader(); + } + + void StartLoader() { + loader_only_start_ticks_ = tick_clock_->NowTicks(); + simple_loader_ = MakeLoader(); + simple_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + loader_factory_, base::BindOnce(&NetworkFetch::OnSimpleLoaderComplete, + base::Unretained(this))); + } + + std::unique_ptr<network::SimpleURLLoader> MakeLoader() { + // TODO(pnoland): Add data use measurement once it's supported for simple + // url loader. + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("interest_feedv2_send", R"( + semantics { + sender: "Feed Library" + description: "Chrome can show content suggestions (e.g. articles) " + "in the form of a feed. For signed-in users, these may be " + "personalized based on interest signals in the user's account." + trigger: "Triggered periodically in the background, or upon " + "explicit user request." + data: "The locale of the device and data describing the suggested " + "content that the user interacted with. For signed-in users " + "the request is authenticated. " + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: YES + cookies_store: "user" + setting: "This can be disabled from the New Tab Page by collapsing " + "the articles section." + chrome_policy { + NTPContentSuggestionsEnabled { + policy_options {mode: MANDATORY} + NTPContentSuggestionsEnabled: false + } + } + })"); + GURL url(url_); + if (access_token_.empty() && !api_key_.empty()) + url = net::AppendQueryParameter(url_, "key", api_key_); + + auto resource_request = std::make_unique<network::ResourceRequest>(); + resource_request->url = url; + + resource_request->load_flags = net::LOAD_BYPASS_CACHE; + resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit; + resource_request->method = request_type_; + + // Include credentials ONLY if the user has overridden the feed host through + // the internals page. This allows for some authentication workflows we need + // for testing. + if (host_overridden_) { + resource_request->credentials_mode = + network::mojom::CredentialsMode::kInclude; + resource_request->site_for_cookies = net::SiteForCookies::FromUrl(url); + } + + SetRequestHeaders(!request_body_.empty(), resource_request.get()); + + auto simple_loader = network::SimpleURLLoader::Create( + std::move(resource_request), traffic_annotation); + simple_loader->SetAllowHttpErrorResults(true); + simple_loader->SetTimeoutDuration(kNetworkTimeout); + PopulateRequestBody(simple_loader.get()); + return simple_loader; + } + + void SetRequestHeaders(bool has_request_body, + network::ResourceRequest* request) const { + if (has_request_body) { + request->headers.SetHeader(net::HttpRequestHeaders::kContentType, + kApplicationOctetStream); + request->headers.SetHeader("Content-Encoding", "gzip"); + } + + variations::SignedIn signed_in_status = variations::SignedIn::kNo; + if (!access_token_.empty()) { + request->headers.SetHeader(net::HttpRequestHeaders::kAuthorization, + "Bearer " + access_token_); + signed_in_status = variations::SignedIn::kYes; + } + + // Add X-Client-Data header with experiment IDs from field trials. + variations::AppendVariationsHeader(url_, variations::InIncognito::kNo, + signed_in_status, request); + } + + void PopulateRequestBody(network::SimpleURLLoader* loader) { + std::string compressed_request_body; + if (!request_body_.empty()) { + std::string uncompressed_request_body( + reinterpret_cast<const char*>(request_body_.data()), + request_body_.size()); + + compression::GzipCompress(uncompressed_request_body, + &compressed_request_body); + + loader->AttachStringForUpload(compressed_request_body, + kApplicationOctetStream); + } + + UMA_HISTOGRAM_COUNTS_1M( + "ContentSuggestions.Feed.Network.RequestSizeKB.Compressed", + static_cast<int>(compressed_request_body.size() / 1024)); + } + + void OnSimpleLoaderComplete(std::unique_ptr<std::string> response) { + int32_t status_code = simple_loader_->NetError(); + // If overriding the feed host, try to grab the Bless nonce. This is + // strictly informational, and only displayed in snippets-internals. + if (host_overridden_ && simple_loader_->ResponseInfo()) { + size_t iter = 0; + std::string value; + while (simple_loader_->ResponseInfo()->headers->EnumerateHeader( + &iter, "www-authenticate", &value)) { + size_t pos = value.find("nonce=\""); + if (pos != std::string::npos) { + std::string nonce = value.substr(pos + 7, 16); + if (nonce.size() == 16) { + pref_service_->SetString(feed::prefs::kHostOverrideBlessNonce, + nonce); + break; + } + } + } + } + + std::string response_body; + if (response) { + status_code = simple_loader_->ResponseInfo()->headers->response_code(); + response_body = std::move(*response); + + if (status_code == net::HTTP_UNAUTHORIZED) { + signin::ScopeSet scopes{kAuthenticationScope}; + CoreAccountId account_id = identity_manager_->GetPrimaryAccountId(); + if (!account_id.empty()) { + identity_manager_->RemoveAccessTokenFromCache(account_id, scopes, + access_token_); + } + } + } + + base::TimeDelta entire_send_duration = + tick_clock_->NowTicks() - entire_send_start_ticks_; + UMA_HISTOGRAM_MEDIUM_TIMES("ContentSuggestions.Feed.Network.Duration", + entire_send_duration); + + base::TimeDelta loader_only_duration = + tick_clock_->NowTicks() - loader_only_start_ticks_; + // This histogram purposefully matches name and bucket size used in + // RemoteSuggestionsFetcherImpl. + UMA_HISTOGRAM_TIMES("NewTabPage.Snippets.FetchTime", loader_only_duration); + + base::UmaHistogramSparse( + "ContentSuggestions.Feed.Network.RequestStatusCode", status_code); + + // The below is true even if there is a protocol error, so this will + // record response size as long as the request completed. + if (status_code >= 200) { + UMA_HISTOGRAM_COUNTS_1M("ContentSuggestions.Feed.Network.ResponseSizeKB", + static_cast<int>(response_body.size() / 1024)); + } + + std::move(done_callback_).Run({status_code, std::move(response_body)}); + } + + private: + GURL url_; + const std::string request_type_; + std::string access_token_; + const std::string request_body_; + signin::IdentityManager* const identity_manager_; + std::unique_ptr<signin::PrimaryAccountAccessTokenFetcher> token_fetcher_; + std::unique_ptr<network::SimpleURLLoader> simple_loader_; + base::OnceCallback<void(RawResponse)> done_callback_; + network::SharedURLLoaderFactory* loader_factory_; + const std::string api_key_; + const base::TickClock* tick_clock_; + + // Set when the NetworkFetch is constructed, before token and article fetch. + const base::TimeTicks entire_send_start_ticks_; + + // Should be set right before the article fetch, and after the token fetch if + // there is one. + base::TimeTicks loader_only_start_ticks_; + PrefService* pref_service_; + bool host_overridden_ = false; +}; + +FeedNetworkImpl::FeedNetworkImpl( + Delegate* delegate, + signin::IdentityManager* identity_manager, + const std::string& api_key, + scoped_refptr<network::SharedURLLoaderFactory> loader_factory, + const base::TickClock* tick_clock, + PrefService* pref_service) + : delegate_(delegate), + identity_manager_(identity_manager), + api_key_(api_key), + loader_factory_(loader_factory), + tick_clock_(tick_clock), + pref_service_(pref_service) {} + +FeedNetworkImpl::~FeedNetworkImpl() = default; + +void FeedNetworkImpl::SendQueryRequest( + const feedwire::Request& request, + base::OnceCallback<void(QueryRequestResult)> callback) { + // TODO(harringtond): Decide how we want to override these URLs for testing. + // Should probably add a command-line flag. + std::string binary_proto; + request.SerializeToString(&binary_proto); + GURL url( + "https://www.google.com/httpservice/noretry/DiscoverClankService/" + "FeedQuery"); + + AddMothershipPayloadQueryParams(/*is_post=*/false, binary_proto, + delegate_->GetLanguageTag(), &url); + Send(url, "GET", /*request_body=*/std::string(), + base::BindOnce(&ParseAndForwardResponse<QueryRequestResult>, + std::move(callback))); +} + +void FeedNetworkImpl::SendActionRequest( + const feedwire::ActionRequest& request, + base::OnceCallback<void(ActionRequestResult)> callback) { + std::string binary_proto; + request.SerializeToString(&binary_proto); + + GURL url( + "https://www.google.com/httpservice/retry/ClankActionUploadService/" + "ClankActionUpload"); + AddMothershipPayloadQueryParams(/*is_post=*/true, /*payload=*/std::string(), + delegate_->GetLanguageTag(), &url); + + Send(url, "POST", std::move(binary_proto), + base::BindOnce(&ParseAndForwardResponse<ActionRequestResult>, + std::move(callback))); +} + +void FeedNetworkImpl::CancelRequests() { + pending_requests_.clear(); +} + +void FeedNetworkImpl::Send(const GURL& url, + const std::string& request_type, + std::string request_body, + base::OnceCallback<void(RawResponse)> callback) { + auto fetch = std::make_unique<NetworkFetch>( + url, request_type, std::move(request_body), identity_manager_, + loader_factory_.get(), api_key_, tick_clock_, pref_service_); + NetworkFetch* fetch_unowned = fetch.get(); + pending_requests_.emplace(std::move(fetch)); + + // It's safe to pass base::Unretained(this) since deleting the network fetch + // will prevent the callback from being completed. + fetch_unowned->Start(base::BindOnce(&FeedNetworkImpl::SendComplete, + base::Unretained(this), fetch_unowned, + std::move(callback))); +} + +void FeedNetworkImpl::SendComplete( + NetworkFetch* fetch, + base::OnceCallback<void(RawResponse)> callback, + RawResponse raw_response) { + DCHECK_EQ(1UL, pending_requests_.count(fetch)); + pending_requests_.erase(fetch); + + std::move(callback).Run(std::move(raw_response)); +} + +} // namespace feed
diff --git a/components/feed/core/v2/feed_network_impl.h b/components/feed/core/v2/feed_network_impl.h new file mode 100644 index 0000000..fee77e8 --- /dev/null +++ b/components/feed/core/v2/feed_network_impl.h
@@ -0,0 +1,92 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_FEED_CORE_V2_FEED_NETWORK_IMPL_H_ +#define COMPONENTS_FEED_CORE_V2_FEED_NETWORK_IMPL_H_ + +#include <string> +#include "base/callback.h" +#include "base/containers/flat_set.h" +#include "base/containers/unique_ptr_adapters.h" +#include "base/memory/scoped_refptr.h" +#include "components/feed/core/v2/feed_network.h" +#include "url/gurl.h" + +class PrefService; +namespace base { +class TickClock; +} +namespace signin { +class IdentityManager; +} +namespace network { +class SharedURLLoaderFactory; +} + +namespace feed { + +class FeedNetworkImpl : public FeedNetwork { + public: + class NetworkFetch; + struct RawResponse; + class Delegate { + public: + // Returns a string which represents the top locale and region of the + // device. + // TODO(harringtond): Implement this. See + // https://cs.chromium.org/chromium/src/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/library/common/locale/LocaleUtils.java + virtual std::string GetLanguageTag() = 0; + }; + + FeedNetworkImpl(Delegate* delegate, + signin::IdentityManager* identity_manager, + const std::string& api_key, + scoped_refptr<network::SharedURLLoaderFactory> loader_factory, + const base::TickClock* tick_clock, + PrefService* pref_service); + ~FeedNetworkImpl() override; + FeedNetworkImpl(const FeedNetworkImpl&) = delete; + FeedNetworkImpl& operator=(FeedNetworkImpl&) = delete; + + // FeedNetwork. + + void SendQueryRequest( + const feedwire::Request& request, + base::OnceCallback<void(QueryRequestResult)> callback) override; + + void SendActionRequest( + const feedwire::ActionRequest& request, + base::OnceCallback<void(ActionRequestResult)> callback) override; + + // Cancels all pending requests immediately. This could be used, for example, + // if there are pending requests for a user who just signed out. + void CancelRequests() override; + + private: + // Start a request to |url| of type |request_type| with body |request_body|. + // |callback| will be called when the response is received or if there is + // an error, including non-protocol errors. The contents of |request_body| + // will be gzipped. + void Send(const GURL& url, + const std::string& request_type, + std::string request_body, + base::OnceCallback<void(FeedNetworkImpl::RawResponse)> callback); + + void SendComplete(NetworkFetch* fetch, + base::OnceCallback<void(RawResponse)> callback, + RawResponse raw_response); + + Delegate* delegate_; + signin::IdentityManager* identity_manager_; + const std::string api_key_; + scoped_refptr<network::SharedURLLoaderFactory> loader_factory_; + const base::TickClock* tick_clock_; + PrefService* pref_service_; + base::flat_set<std::unique_ptr<NetworkFetch>, base::UniquePtrComparator> + pending_requests_; +}; + +} // namespace feed + +#endif // COMPONENTS_FEED_CORE_V2_FEED_NETWORK_IMPL_H_
diff --git a/components/feed/core/v2/feed_network_impl_unittest.cc b/components/feed/core/v2/feed_network_impl_unittest.cc new file mode 100644 index 0000000..ce2056c --- /dev/null +++ b/components/feed/core/v2/feed_network_impl_unittest.cc
@@ -0,0 +1,420 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/feed/core/v2/feed_network_impl.h" + +#include <utility> + +#include "base/bind.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/test/bind_test_util.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/test/simple_test_tick_clock.h" +#include "base/test/task_environment.h" +#include "components/feed/core/common/pref_names.h" +#include "components/feed/core/proto/wire/action_request.pb.h" +#include "components/feed/core/proto/wire/feed_action_response.pb.h" +#include "components/feed/core/proto/wire/request.pb.h" +#include "components/feed/core/proto/wire/response.pb.h" +#include "components/prefs/testing_pref_service.h" +#include "components/signin/public/identity_manager/identity_test_environment.h" +#include "net/http/http_response_headers.h" +#include "net/http/http_status_code.h" +#include "net/http/http_util.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "services/network/public/cpp/url_loader_completion_status.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/zlib/google/compression_utils.h" +#include "url/gurl.h" + +namespace feed { +namespace { + +using base::TimeDelta; +using testing::ElementsAre; +using ActionRequestResult = FeedNetwork::ActionRequestResult; +using QueryRequestResult = FeedNetwork::QueryRequestResult; + +feedwire::Request GetTestFeedRequest() { + feedwire::Request request; + request.set_request_version(feedwire::Request::FEED_QUERY); + return request; +} + +feedwire::Response GetTestFeedResponse() { + feedwire::Response response; + response.set_response_version(feedwire::Response::FEED_RESPONSE); + return response; +} + +feedwire::ActionRequest GetTestActionRequest() { + feedwire::ActionRequest request; + request.set_request_version(feedwire::ActionRequest::FEED_UPLOAD_ACTION); + return request; +} + +feedwire::FeedActionResponse GetTestActionResponse() { + feedwire::FeedActionResponse response; + response.mutable_consistency_token()->set_token("tok"); + return response; +} + +template <typename T> +class CallbackReceiver { + public: + void Done(T result) { result_ = std::move(result); } + base::OnceCallback<void(T)> Bind() { + return base::BindOnce(&CallbackReceiver::Done, base::Unretained(this)); + } + + const base::Optional<T>& GetResult() { return result_; } + + private: + base::Optional<T> result_; +}; + +class TestDelegate : public FeedNetworkImpl::Delegate { + public: + std::string GetLanguageTag() override { return "en"; } +}; + +class FeedNetworkTest : public testing::Test { + public: + FeedNetworkTest() { + identity_test_env_.MakePrimaryAccountAvailable("example@gmail.com"); + identity_test_env_.SetAutomaticIssueOfAccessTokens(true); + } + FeedNetworkTest(FeedNetworkTest&) = delete; + FeedNetworkTest& operator=(const FeedNetworkTest&) = delete; + ~FeedNetworkTest() override = default; + + void SetUp() override { + feed::RegisterProfilePrefs(profile_prefs_.registry()); + + shared_url_loader_factory_ = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_factory_); + feed_network_ = std::make_unique<FeedNetworkImpl>( + &delegate_, identity_test_env_.identity_manager(), "dummy_api_key", + shared_url_loader_factory_, task_environment_.GetMockTickClock(), + &profile_prefs_); + } + + FeedNetwork* feed_network() { return feed_network_.get(); } + + signin::IdentityTestEnvironment* identity_env() { + return &identity_test_env_; + } + + network::TestURLLoaderFactory* test_factory() { return &test_factory_; } + + base::test::TaskEnvironment task_environment_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + + TestingPrefServiceSimple& profile_prefs() { return profile_prefs_; } + + void Respond(const GURL& url, + const std::string& response_string, + net::HttpStatusCode code = net::HTTP_OK, + network::URLLoaderCompletionStatus status = + network::URLLoaderCompletionStatus()) { + auto head = network::mojom::URLResponseHead::New(); + if (code >= 0) { + if (response_headers_) { + head->headers = response_headers_; + } else { + head->headers = base::MakeRefCounted<net::HttpResponseHeaders>( + "HTTP/1.1 " + base::NumberToString(code)); + } + status.decoded_body_length = response_string.length(); + } + + test_factory_.AddResponse(url, std::move(head), response_string, status); + } + + network::ResourceRequest RespondToQueryRequest( + const std::string& response_string, + net::HttpStatusCode code) { + task_environment_.RunUntilIdle(); + network::TestURLLoaderFactory::PendingRequest* pending_request = + test_factory()->GetPendingRequest(0); + CHECK(pending_request); + network::ResourceRequest resource_request = pending_request->request; + Respond(pending_request->request.url, response_string, code); + task_environment_.FastForwardUntilNoTasksRemain(); + return resource_request; + } + + network::ResourceRequest RespondToQueryRequest( + feedwire::Response response_message, + net::HttpStatusCode code) { + std::string binary_proto; + response_message.SerializeToString(&binary_proto); + return RespondToQueryRequest(binary_proto, code); + } + + network::ResourceRequest RespondToActionRequest( + feedwire::FeedActionResponse response_message, + net::HttpStatusCode code) { + std::string binary_proto; + response_message.SerializeToString(&binary_proto); + return RespondToQueryRequest(binary_proto, code); + } + + protected: + scoped_refptr<net::HttpResponseHeaders> response_headers_; + + private: + TestDelegate delegate_; + signin::IdentityTestEnvironment identity_test_env_; + std::unique_ptr<FeedNetwork> feed_network_; + network::TestURLLoaderFactory test_factory_; + scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_; + base::SimpleTestTickClock test_tick_clock_; + TestingPrefServiceSimple profile_prefs_; +}; + +TEST_F(FeedNetworkTest, SendQueryRequestEmpty) { + CallbackReceiver<QueryRequestResult> receiver; + feed_network()->SendQueryRequest(feedwire::Request(), receiver.Bind()); + RespondToQueryRequest("", net::HTTP_OK); + + ASSERT_TRUE(receiver.GetResult()); + const QueryRequestResult& result = *receiver.GetResult(); + EXPECT_EQ(net::HTTP_OK, result.status_code); + EXPECT_TRUE(result.response_body); +} + +TEST_F(FeedNetworkTest, SendQueryRequestSendsValidRequest) { + CallbackReceiver<QueryRequestResult> receiver; + feed_network()->SendQueryRequest(GetTestFeedRequest(), receiver.Bind()); + network::ResourceRequest resource_request = + RespondToQueryRequest("", net::HTTP_OK); + + EXPECT_EQ( + "https://www.google.com/httpservice/noretry/" + "DiscoverClankService/FeedQuery?reqpld=%08%01&fmt=bin&hl=en", + resource_request.url); + EXPECT_EQ("GET", resource_request.method); + EXPECT_FALSE(resource_request.headers.HasHeader("content-encoding")); + std::string authorization; + EXPECT_TRUE( + resource_request.headers.GetHeader("Authorization", &authorization)); + EXPECT_EQ(authorization, "Bearer access_token"); +} + +TEST_F(FeedNetworkTest, SendQueryRequestInvalidResponse) { + CallbackReceiver<QueryRequestResult> receiver; + feed_network()->SendQueryRequest(GetTestFeedRequest(), receiver.Bind()); + RespondToQueryRequest("invalid", net::HTTP_OK); + + ASSERT_TRUE(receiver.GetResult()); + const QueryRequestResult& result = *receiver.GetResult(); + EXPECT_EQ(net::HTTP_OK, result.status_code); + EXPECT_FALSE(result.response_body); +} + +TEST_F(FeedNetworkTest, SendQueryRequestReceivesResponse) { + CallbackReceiver<QueryRequestResult> receiver; + feed_network()->SendQueryRequest(feedwire::Request(), receiver.Bind()); + RespondToQueryRequest(GetTestFeedResponse(), net::HTTP_OK); + + ASSERT_TRUE(receiver.GetResult()); + const QueryRequestResult& result = *receiver.GetResult(); + EXPECT_EQ(net::HTTP_OK, result.status_code); + EXPECT_EQ(GetTestFeedResponse().response_version(), + result.response_body->response_version()); +} + +TEST_F(FeedNetworkTest, SendQueryRequestIgnoresBodyForNon200Response) { + CallbackReceiver<QueryRequestResult> receiver; + feed_network()->SendQueryRequest(feedwire::Request(), receiver.Bind()); + RespondToQueryRequest(GetTestFeedResponse(), net::HTTP_FORBIDDEN); + + ASSERT_TRUE(receiver.GetResult()); + const QueryRequestResult& result = *receiver.GetResult(); + EXPECT_EQ(net::HTTP_FORBIDDEN, result.status_code); + EXPECT_FALSE(result.response_body); +} + +TEST_F(FeedNetworkTest, CancelRequest) { + CallbackReceiver<QueryRequestResult> receiver; + feed_network()->SendQueryRequest(GetTestFeedRequest(), receiver.Bind()); + feed_network()->CancelRequests(); + task_environment_.FastForwardUntilNoTasksRemain(); + + EXPECT_FALSE(receiver.GetResult()); +} + +TEST_F(FeedNetworkTest, RequestTimeout) { + base::HistogramTester histogram_tester; + CallbackReceiver<QueryRequestResult> receiver; + feed_network()->SendQueryRequest(feedwire::Request(), receiver.Bind()); + task_environment_.FastForwardBy(TimeDelta::FromSeconds(30)); + + ASSERT_TRUE(receiver.GetResult()); + const QueryRequestResult& result = *receiver.GetResult(); + EXPECT_EQ(net::ERR_TIMED_OUT, result.status_code); + histogram_tester.ExpectTimeBucketCount( + "ContentSuggestions.Feed.Network.Duration", TimeDelta::FromSeconds(30), + 1); +} + +TEST_F(FeedNetworkTest, ParallelRequests) { + CallbackReceiver<QueryRequestResult> receiver1, receiver2; + feed_network()->SendQueryRequest(GetTestFeedRequest(), receiver1.Bind()); + feed_network()->SendQueryRequest(feedwire::Request(), receiver2.Bind()); + + // Respond to both requests, avoiding FastForwardUntilNoTasksRemain until + // a response is added for both requests. + ASSERT_EQ(2, test_factory()->NumPending()); + for (int i = 0; i < 2; ++i) { + network::TestURLLoaderFactory::PendingRequest* pending_request = + test_factory()->GetPendingRequest(0); + ASSERT_TRUE(pending_request) << "for request #" << i; + std::string binary_proto; + GetTestFeedResponse().SerializeToString(&binary_proto); + Respond(pending_request->request.url, binary_proto, net::HTTP_OK); + } + task_environment_.FastForwardUntilNoTasksRemain(); + + EXPECT_TRUE(receiver1.GetResult()); + EXPECT_TRUE(receiver2.GetResult()); +} + +TEST_F(FeedNetworkTest, ShouldReportRequestStatusCode) { + CallbackReceiver<QueryRequestResult> receiver; + base::HistogramTester histogram_tester; + feed_network()->SendQueryRequest(GetTestFeedRequest(), receiver.Bind()); + RespondToQueryRequest(GetTestFeedResponse(), net::HTTP_FORBIDDEN); + EXPECT_THAT( + histogram_tester.GetAllSamples( + "ContentSuggestions.Feed.Network.RequestStatusCode"), + ElementsAre(base::Bucket(/*min=*/net::HTTP_FORBIDDEN, /*count=*/1))); +} + +TEST_F(FeedNetworkTest, ShouldIncludeAPIKeyForAuthError) { + identity_env()->SetAutomaticIssueOfAccessTokens(false); + CallbackReceiver<QueryRequestResult> receiver; + base::HistogramTester histogram_tester; + + feed_network()->SendQueryRequest(GetTestFeedRequest(), receiver.Bind()); + identity_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithError( + GoogleServiceAuthError( + GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS)); + + network::ResourceRequest resource_request = + RespondToQueryRequest(GetTestFeedResponse(), net::HTTP_OK); + + EXPECT_THAT(resource_request.url.spec(), + testing::HasSubstr("key=dummy_api_key")); + + EXPECT_THAT( + histogram_tester.GetAllSamples( + "ContentSuggestions.Feed.Network.TokenFetchStatus"), + testing::ElementsAre(base::Bucket( + /*min=*/GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS, + /*count=*/1))); +} + +// Disabled for chromeos, which doesn't allow for there not to be a signed in +// user. +#if !defined(OS_CHROMEOS) +TEST_F(FeedNetworkTest, ShouldIncludeAPIKeyForNoSignedInUser) { + identity_env()->ClearPrimaryAccount(); + CallbackReceiver<QueryRequestResult> receiver; + feed_network()->SendQueryRequest(GetTestFeedRequest(), receiver.Bind()); + + network::ResourceRequest resource_request = + RespondToQueryRequest(GetTestFeedResponse(), net::HTTP_OK); + + EXPECT_THAT(resource_request.url.spec(), + testing::HasSubstr("key=dummy_api_key")); +} +#endif + +TEST_F(FeedNetworkTest, TestDurationHistogram) { + base::HistogramTester histogram_tester; + CallbackReceiver<QueryRequestResult> receiver; + const TimeDelta kDuration = TimeDelta::FromMilliseconds(12345); + + feed_network()->SendQueryRequest(GetTestFeedRequest(), receiver.Bind()); + task_environment_.FastForwardBy(kDuration); + RespondToQueryRequest(GetTestFeedResponse(), net::HTTP_OK); + + EXPECT_TRUE(receiver.GetResult()); + histogram_tester.ExpectTimeBucketCount( + "ContentSuggestions.Feed.Network.Duration", kDuration, 1); +} + +// Verify that the kHostOverrideHost pref overrides the feed host +// and updates the Bless nonce if one sent in the response. +TEST_F(FeedNetworkTest, TestHostOverrideWithAuthHeader) { + CallbackReceiver<QueryRequestResult> receiver; + profile_prefs().SetString(feed::prefs::kHostOverrideHost, + "http://www.newhost.com/"); + feed_network()->SendQueryRequest(GetTestFeedRequest(), receiver.Bind()); + + response_headers_ = base::MakeRefCounted<net::HttpResponseHeaders>( + net::HttpUtil::AssembleRawHeaders( + "HTTP/1.1 401 Unauthorized\nwww-authenticate: Foo " + "nonce=\"1234123412341234\"\n\n")); + RespondToQueryRequest(GetTestFeedResponse(), net::HTTP_FORBIDDEN); + + EXPECT_TRUE(receiver.GetResult()); + EXPECT_EQ("1234123412341234", + profile_prefs().GetString(feed::prefs::kHostOverrideBlessNonce)); +} + +TEST_F(FeedNetworkTest, SendActionRequest) { + CallbackReceiver<ActionRequestResult> receiver; + feed_network()->SendActionRequest(GetTestActionRequest(), receiver.Bind()); + RespondToActionRequest(GetTestActionResponse(), net::HTTP_OK); + + ASSERT_TRUE(receiver.GetResult()); + const ActionRequestResult& result = *receiver.GetResult(); + EXPECT_EQ(net::HTTP_OK, result.status_code); + EXPECT_TRUE(result.response_body); +} + +TEST_F(FeedNetworkTest, SendActionRequestSendsValidRequest) { + CallbackReceiver<ActionRequestResult> receiver; + feed_network()->SendActionRequest(GetTestActionRequest(), receiver.Bind()); + network::ResourceRequest resource_request = + RespondToActionRequest(GetTestActionResponse(), net::HTTP_OK); + + EXPECT_EQ( + GURL("https://www.google.com/httpservice/retry/ClankActionUploadService/" + "ClankActionUpload?fmt=bin&hl=en"), + resource_request.url); + + EXPECT_EQ("POST", resource_request.method); + std::string content_encoding; + EXPECT_TRUE(resource_request.headers.GetHeader("content-encoding", + &content_encoding)); + EXPECT_EQ("gzip", content_encoding); + std::string authorization; + EXPECT_TRUE( + resource_request.headers.GetHeader("Authorization", &authorization)); + EXPECT_EQ(authorization, "Bearer access_token"); + + // Check that the body content is correct. This requires some work to extract + // the bytes and unzip them. + auto* elements = resource_request.request_body->elements(); + ASSERT_TRUE(elements); + ASSERT_EQ(1UL, elements->size()); + std::string sent_body((*elements)[0].bytes(), (*elements)[0].length()); + std::string sent_body_uncompressed; + ASSERT_TRUE(compression::GzipUncompress(sent_body, &sent_body_uncompressed)); + std::string expected_body; + ASSERT_TRUE(GetTestActionRequest().SerializeToString(&expected_body)); + EXPECT_EQ(expected_body, sent_body_uncompressed); +} + +} // namespace +} // namespace feed
diff --git a/components/feed/core/v2/feed_stream.cc b/components/feed/core/v2/feed_stream.cc index dc98bc0..d688a39a 100644 --- a/components/feed/core/v2/feed_stream.cc +++ b/components/feed/core/v2/feed_stream.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "components/feed/core/common/pref_names.h" +#include "components/feed/core/v2/feed_network.h" #include "components/feed/core/v2/feed_stream_background.h" #include "components/prefs/pref_service.h" @@ -13,10 +14,12 @@ FeedStream::FeedStream( PrefService* profile_prefs, + FeedNetwork* feed_network, base::Clock* clock, base::TickClock* tick_clock, scoped_refptr<base::SequencedTaskRunner> background_task_runner) : profile_prefs_(profile_prefs), + feed_network_(feed_network), clock_(clock), tick_clock_(tick_clock), background_task_runner_(background_task_runner), @@ -25,6 +28,7 @@ // TODO(harringtond): Use these members. (void)clock_; (void)tick_clock_; + (void)feed_network_; } FeedStream::~FeedStream() {
diff --git a/components/feed/core/v2/feed_stream.h b/components/feed/core/v2/feed_stream.h index 75fd5ed8..24724757 100644 --- a/components/feed/core/v2/feed_stream.h +++ b/components/feed/core/v2/feed_stream.h
@@ -21,7 +21,7 @@ } // namespace base namespace feed { - +class FeedNetwork; class FeedStreamBackground; // Implements FeedStreamApi. |FeedStream| additionally exposes functionality @@ -30,6 +30,7 @@ public offline_pages::TaskQueue::Delegate { public: FeedStream(PrefService* profile_prefs, + FeedNetwork* feed_network, base::Clock* clock, base::TickClock* tick_clock, scoped_refptr<base::SequencedTaskRunner> background_task_runner); @@ -61,6 +62,7 @@ private: PrefService* profile_prefs_; + FeedNetwork* feed_network_; base::Clock* clock_; base::TickClock* tick_clock_;
diff --git a/components/feed/core/v2/feed_stream_unittest.cc b/components/feed/core/v2/feed_stream_unittest.cc index ce88341..6ee696e 100644 --- a/components/feed/core/v2/feed_stream_unittest.cc +++ b/components/feed/core/v2/feed_stream_unittest.cc
@@ -8,6 +8,7 @@ #include "base/test/simple_test_tick_clock.h" #include "base/test/task_environment.h" #include "components/feed/core/common/pref_names.h" +#include "components/feed/core/v2/feed_network.h" #include "components/feed/core/v2/feed_stream_background.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/testing_pref_service.h" @@ -15,6 +16,18 @@ namespace feed { namespace { + +class TestFeedNetwork : public FeedNetwork { + public: + void SendQueryRequest( + const feedwire::Request& request, + base::OnceCallback<void(QueryRequestResult)> callback) override {} + void SendActionRequest( + const feedwire::ActionRequest& request, + base::OnceCallback<void(ActionRequestResult)> callback) override {} + void CancelRequests() override {} +}; + class FeedStreamTest : public testing::Test { public: void SetUp() override { @@ -27,12 +40,13 @@ true); stream_ = std::make_unique<FeedStream>( - &profile_prefs_, &clock_, &tick_clock_, + &profile_prefs_, &network_, &clock_, &tick_clock_, task_environment_.GetMainThreadTaskRunner()); } protected: TestingPrefServiceSimple profile_prefs_; + TestFeedNetwork network_; base::SimpleTestClock clock_; base::SimpleTestTickClock tick_clock_;
diff --git a/components/safe_browsing/android/java/src/org/chromium/components/safe_browsing/SafeBrowsingApiBridge.java b/components/safe_browsing/android/java/src/org/chromium/components/safe_browsing/SafeBrowsingApiBridge.java index c5b3488..db042881 100644 --- a/components/safe_browsing/android/java/src/org/chromium/components/safe_browsing/SafeBrowsingApiBridge.java +++ b/components/safe_browsing/android/java/src/org/chromium/components/safe_browsing/SafeBrowsingApiBridge.java
@@ -56,7 +56,7 @@ SafeBrowsingApiBridgeJni.get().onUrlCheckDone( callbackId, resultStatus, metadata, checkDelta); } - }, SafeBrowsingApiBridgeJni.get().areLocalBlacklistsEnabled()); + }); return initSuccesssful ? handler : null; } @@ -97,7 +97,6 @@ @NativeMethods interface Natives { - boolean areLocalBlacklistsEnabled(); void onUrlCheckDone(long callbackId, int resultStatus, String metadata, long checkDelta); } }
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 5b3e1b0d..7bbc824 100644 --- a/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc +++ b/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc
@@ -106,11 +106,6 @@ } // namespace -// Java->Native call, to check whether the feature to use local blacklists is -// enabled. -jboolean JNI_SafeBrowsingApiBridge_AreLocalBlacklistsEnabled(JNIEnv* env) { - return base::FeatureList::IsEnabled(kUseLocalBlacklistsV2); -} // Respond to the URL reputation request by looking up the callback information // stored in |pending_callbacks|.
diff --git a/components/safe_browsing/content/browser/browser_url_loader_throttle.cc b/components/safe_browsing/content/browser/browser_url_loader_throttle.cc index 59b837972..58bc9aa 100644 --- a/components/safe_browsing/content/browser/browser_url_loader_throttle.cc +++ b/components/safe_browsing/content/browser/browser_url_loader_throttle.cc
@@ -323,6 +323,9 @@ // processing unsafe contents (e.g., writing unsafe contents into cache), // until we get the results. According to the results, we may resume reading // or cancel the resource load. + // For real time Safe Browsing checks, we continue reading the response body + // but, similar to hash-based checks, do not process it until we know it is + // SAFE. if (pending_slow_checks_ == 1) delegate_->PauseReadingBodyFromNet(); }
diff --git a/components/safe_browsing/content/browser/safe_browsing_url_checker_impl_content.cc b/components/safe_browsing/content/browser/safe_browsing_url_checker_impl_content.cc index 070b7374..26532e7 100644 --- a/components/safe_browsing/content/browser/safe_browsing_url_checker_impl_content.cc +++ b/components/safe_browsing/content/browser/safe_browsing_url_checker_impl_content.cc
@@ -8,7 +8,6 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros_local.h" -#include "base/strings/string_util.h" #include "base/task/post_task.h" #include "components/safe_browsing/content/web_ui/safe_browsing_ui.h" #include "components/safe_browsing/core/common/safebrowsing_constants.h" @@ -23,11 +22,7 @@ bool SafeBrowsingUrlCheckerImpl::CanPerformFullURLLookup(const GURL& url) { return real_time_lookup_enabled_ && RealTimePolicyEngine::CanPerformFullURLLookupForResourceType( - resource_type_) && - // TODO(crbug.com/1054978): PDF loading issue when full url lookup is - // enabled. - !base::EndsWith(url.path_piece(), ".pdf", - base::CompareCase::INSENSITIVE_ASCII); + resource_type_); } void SafeBrowsingUrlCheckerImpl::OnRTLookupRequest(
diff --git a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc index 0f8cd85..93457a6 100644 --- a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc +++ b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc
@@ -306,7 +306,8 @@ &SafeBrowsingUrlCheckerImpl::OnTimeout); bool safe_synchronously; - if (CanPerformFullURLLookup(url)) { + bool can_perform_full_url_lookup = CanPerformFullURLLookup(url); + if (can_perform_full_url_lookup) { UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.RT.ResourceTypes.Checked", resource_type_); safe_synchronously = false; @@ -364,10 +365,16 @@ // Only send out notification of starting a slow check if the database // manager actually supports fast checks (i.e., synchronous checks) but is - // not able to complete the check synchronously in this case. + // not able to complete the check synchronously in this case and we're doing + // hash-based checks. // Don't send out notification if the database manager doesn't support - // synchronous checks at all (e.g., on mobile). - if (!database_manager_->ChecksAreAlwaysAsync()) + // synchronous checks at all (e.g., on mobile), or if performing a full URL + // check since we don't want to block resource fetch while we perform a full + // URL lookup. Note that we won't parse the response until the Safe Browsing + // check is complete and return SAFE, so there's no Safe Browsing bypass + // risk here. + if (!can_perform_full_url_lookup && + !database_manager_->ChecksAreAlwaysAsync()) urls_[next_index_].notifier.OnStartSlowCheck(); break;
diff --git a/components/safe_browsing/core/features.cc b/components/safe_browsing/core/features.cc index 1a60d90b..ead4fad 100644 --- a/components/safe_browsing/core/features.cc +++ b/components/safe_browsing/core/features.cc
@@ -106,10 +106,6 @@ const base::Feature kTriggerThrottlerDailyQuotaFeature{ "SafeBrowsingTriggerThrottlerDailyQuota", base::FEATURE_DISABLED_BY_DEFAULT}; - -const base::Feature kUseLocalBlacklistsV2{"SafeBrowsingUseLocalBlacklistsV2", - base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kUseNewDownloadWarnings{"UseNewDownloadWarnings", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -141,7 +137,6 @@ {&kSuspiciousSiteTriggerQuotaFeature, true}, {&kThreatDomDetailsTagAndAttributeFeature, false}, {&kTriggerThrottlerDailyQuotaFeature, false}, - {&kUseLocalBlacklistsV2, true}, }; // Adds the name and the enabled/disabled status of a given feature.
diff --git a/components/safe_browsing/core/features.h b/components/safe_browsing/core/features.h index 038f310..3869156 100644 --- a/components/safe_browsing/core/features.h +++ b/components/safe_browsing/core/features.h
@@ -99,9 +99,6 @@ // trials simultaneously. extern const base::Feature kTriggerThrottlerDailyQuotaFeature; -// Controls whether Chrome on Android uses locally cached blacklists. -extern const base::Feature kUseLocalBlacklistsV2; - // Controls whether Chrome uses new download warning UX. extern const base::Feature kUseNewDownloadWarnings;
diff --git a/components/viz/common/features.cc b/components/viz/common/features.cc index 58c53a0..bf6a447 100644 --- a/components/viz/common/features.cc +++ b/components/viz/common/features.cc
@@ -72,6 +72,10 @@ } bool IsUsingSkiaForGLReadback() { + // Viz for webview requires Skia Readback. + if (IsUsingVizForWebView()) + return true; + return base::FeatureList::IsEnabled(kUseSkiaForGLReadback); } @@ -84,6 +88,10 @@ return false; #endif + // Viz for webview requires SkiaRenderer. + if (IsUsingVizForWebView()) + return true; + return base::FeatureList::IsEnabled(kUseSkiaRenderer) || base::FeatureList::IsEnabled(kVulkan); } @@ -100,6 +108,10 @@ #endif bool IsUsingVizForWebView() { + // Viz for WebView requires shared images to be enabled. + if (!base::FeatureList::IsEnabled(kEnableSharedImageForWebview)) + return false; + return base::FeatureList::IsEnabled(kVizForWebView); }
diff --git a/components/viz/service/display/frame_rate_decider.cc b/components/viz/service/display/frame_rate_decider.cc index e714f61..0f1d741 100644 --- a/components/viz/service/display/frame_rate_decider.cc +++ b/components/viz/service/display/frame_rate_decider.cc
@@ -114,15 +114,19 @@ // ideal refresh rate. base::TimeDelta new_preferred_interval = UnspecifiedFrameInterval(); if (min_frame_sink_interval != BeginFrameArgs::MinInterval()) { + constexpr float kMaxIntervalDelta = 0.05; for (auto supported_interval : supported_intervals_) { - // Pick the display interval which is closest to the preferred interval. - // TODO(khushalsagar): This should suffice for the current use-case (based - // on supported refresh rates we expect), but we should be picking a frame - // rate with the correct tradeoff between running the display at a lower - // interval to save power and getting an ideal cadence for the video's - // frame rate. - if ((min_frame_sink_interval - supported_interval).magnitude() < - (min_frame_sink_interval - new_preferred_interval).magnitude()) { + // We only use a supported interval if it is in perfect cadence with the + // desired interval. + float delta_int = 0; + float delta = std::modf(min_frame_sink_interval.InMicrosecondsF() / + supported_interval.InMicrosecondsF(), + &delta_int); + bool in_perfect_cadence = + delta < kMaxIntervalDelta || delta > (1 - kMaxIntervalDelta); + if (in_perfect_cadence && supported_interval > new_preferred_interval) { + // Make sure that we select the largest one in the + // |supported_intervals_| that meets the requirements new_preferred_interval = supported_interval; } }
diff --git a/components/viz/service/display/frame_rate_decider_unittest.cc b/components/viz/service/display/frame_rate_decider_unittest.cc index 173e2a4a..9c8a365ce 100644 --- a/components/viz/service/display/frame_rate_decider_unittest.cc +++ b/components/viz/service/display/frame_rate_decider_unittest.cc
@@ -197,6 +197,50 @@ EXPECT_EQ(display_interval_, FrameRateDecider::UnspecifiedFrameInterval()); } +TEST_F(FrameRateDeciderTest, OptimalFrameSinkIntervelIsPicked) { + base::TimeDelta min_supported_interval = base::TimeDelta::FromSeconds(1); + const std::vector<base::TimeDelta> supported_intervals = { + min_supported_interval * 2, min_supported_interval}; + frame_rate_decider_->SetSupportedFrameIntervals(supported_intervals); + EXPECT_EQ(display_interval_, FrameRateDecider::UnspecifiedFrameInterval()); + + FrameSinkId frame_sink_id1(1u, 1u); + preferred_intervals_[frame_sink_id1] = min_supported_interval * 2.5; + auto* surface1 = CreateAndDrawSurface(frame_sink_id1); + + FrameSinkId frame_sink_id2(1u, 2u); + preferred_intervals_[frame_sink_id2] = min_supported_interval * 2.03; + auto* surface2 = CreateAndDrawSurface(frame_sink_id2); + + FrameSinkId frame_sink_id3(1u, 3u); + preferred_intervals_[frame_sink_id3] = min_supported_interval * 0.5; + auto* surface3 = CreateAndDrawSurface(frame_sink_id3); + + UpdateFrame(surface1); + { + FrameRateDecider::ScopedAggregate scope(frame_rate_decider_.get()); + frame_rate_decider_->OnSurfaceWillBeDrawn(surface1); + } + EXPECT_EQ(display_interval_, FrameRateDecider::UnspecifiedFrameInterval()); + + UpdateFrame(surface2); + { + FrameRateDecider::ScopedAggregate scope(frame_rate_decider_.get()); + frame_rate_decider_->OnSurfaceWillBeDrawn(surface1); + frame_rate_decider_->OnSurfaceWillBeDrawn(surface2); + } + EXPECT_EQ(display_interval_, min_supported_interval * 2); + + UpdateFrame(surface3); + { + FrameRateDecider::ScopedAggregate scope(frame_rate_decider_.get()); + frame_rate_decider_->OnSurfaceWillBeDrawn(surface1); + frame_rate_decider_->OnSurfaceWillBeDrawn(surface2); + frame_rate_decider_->OnSurfaceWillBeDrawn(surface3); + } + EXPECT_EQ(display_interval_, FrameRateDecider::UnspecifiedFrameInterval()); +} + TEST_F(FrameRateDeciderTest, MinFrameSinkIntervalIsPicked) { base::TimeDelta min_supported_interval = base::TimeDelta::FromSeconds(1); const std::vector<base::TimeDelta> supported_intervals = { @@ -206,11 +250,11 @@ EXPECT_EQ(display_interval_, FrameRateDecider::UnspecifiedFrameInterval()); FrameSinkId frame_sink_id1(1u, 1u); - preferred_intervals_[frame_sink_id1] = min_supported_interval * 2.75; + preferred_intervals_[frame_sink_id1] = min_supported_interval * 3; auto* surface1 = CreateAndDrawSurface(frame_sink_id1); FrameSinkId frame_sink_id2(1u, 2u); - preferred_intervals_[frame_sink_id2] = min_supported_interval * 2.2; + preferred_intervals_[frame_sink_id2] = min_supported_interval * 2; auto* surface2 = CreateAndDrawSurface(frame_sink_id2); UpdateFrame(surface1);
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc index f73acfb..149855e 100644 --- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc +++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
@@ -225,6 +225,11 @@ constexpr float kMaxTimebaseDelta = 0.05; if (timebase_delta > display_frame_interval_ * kMaxTimebaseDelta) display_frame_timebase_ = timebase; + } else { + // |display_frame_timebase_| should be still updated as normal in + // preferred interval mode without a meaningful + // |preferred_frame_interval_| + display_frame_timebase_ = timebase; } } else { display_frame_timebase_ = timebase;
diff --git a/components/webcrypto/BUILD.gn b/components/webcrypto/BUILD.gn index 8ff5cb5..e3b62880 100644 --- a/components/webcrypto/BUILD.gn +++ b/components/webcrypto/BUILD.gn
@@ -26,6 +26,7 @@ "algorithms/ec.h", "algorithms/ecdh.cc", "algorithms/ecdsa.cc", + "algorithms/ed25519.cc", "algorithms/hkdf.cc", "algorithms/hmac.cc", "algorithms/pbkdf2.cc", @@ -41,6 +42,7 @@ "algorithms/sha.cc", "algorithms/util.cc", "algorithms/util.h", + "algorithms/x25519.cc", "blink_key_handle.cc", "blink_key_handle.h", "crypto_data.cc",
diff --git a/components/webcrypto/algorithm_implementations.h b/components/webcrypto/algorithm_implementations.h index 186256c..ed8ba2a 100644 --- a/components/webcrypto/algorithm_implementations.h +++ b/components/webcrypto/algorithm_implementations.h
@@ -27,6 +27,8 @@ std::unique_ptr<AlgorithmImplementation> CreateEcdhImplementation(); std::unique_ptr<AlgorithmImplementation> CreateHkdfImplementation(); std::unique_ptr<AlgorithmImplementation> CreatePbkdf2Implementation(); +std::unique_ptr<AlgorithmImplementation> CreateEd25519Implementation(); +std::unique_ptr<AlgorithmImplementation> CreateX25519Implementation(); } // namespace webcrypto
diff --git a/components/webcrypto/algorithm_registry.cc b/components/webcrypto/algorithm_registry.cc index 3ca6d3e..0095214 100644 --- a/components/webcrypto/algorithm_registry.cc +++ b/components/webcrypto/algorithm_registry.cc
@@ -30,7 +30,9 @@ ecdsa_(CreateEcdsaImplementation()), ecdh_(CreateEcdhImplementation()), hkdf_(CreateHkdfImplementation()), - pbkdf2_(CreatePbkdf2Implementation()) { + pbkdf2_(CreatePbkdf2Implementation()), + ed25519_(CreateEd25519Implementation()), + x25519_(CreateX25519Implementation()) { crypto::EnsureOpenSSLInit(); } @@ -66,6 +68,10 @@ return hkdf_.get(); case blink::kWebCryptoAlgorithmIdPbkdf2: return pbkdf2_.get(); + case blink::kWebCryptoAlgorithmIdEd25519: + return ed25519_.get(); + case blink::kWebCryptoAlgorithmIdX25519: + return x25519_.get(); default: return nullptr; } @@ -85,6 +91,8 @@ const std::unique_ptr<AlgorithmImplementation> ecdh_; const std::unique_ptr<AlgorithmImplementation> hkdf_; const std::unique_ptr<AlgorithmImplementation> pbkdf2_; + const std::unique_ptr<AlgorithmImplementation> ed25519_; + const std::unique_ptr<AlgorithmImplementation> x25519_; }; } // namespace
diff --git a/components/webcrypto/algorithms/ed25519.cc b/components/webcrypto/algorithms/ed25519.cc new file mode 100644 index 0000000..153b853 --- /dev/null +++ b/components/webcrypto/algorithms/ed25519.cc
@@ -0,0 +1,44 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/webcrypto/algorithm_implementation.h" +#include "components/webcrypto/status.h" + +namespace webcrypto { + +namespace { + +// This class implements the Ed25519 algorithm, which is a particular parameter +// choice for the EdDSA algorithm specified by RFC 8032. The underlying curve +// used by Ed25519 is equivalent to Curve25519 specified by RFC 7748. +// +// TODO(crbug.com/1032821): See also +// https://chromestatus.com/feature/4913922408710144. +class Ed25519Implementation : public AlgorithmImplementation { + public: + Status Sign(const blink::WebCryptoAlgorithm& algorithm, + const blink::WebCryptoKey& key, + const CryptoData& data, + std::vector<uint8_t>* buffer) const override { + // TODO(crbug.com/1032821): Implement this. + return Status::ErrorUnsupported(); + } + + Status Verify(const blink::WebCryptoAlgorithm& algorithm, + const blink::WebCryptoKey& key, + const CryptoData& signature, + const CryptoData& data, + bool* signature_match) const override { + // TODO(crbug.com/1032821): Implement this. + return Status::ErrorUnsupported(); + } +}; + +} // namespace + +std::unique_ptr<AlgorithmImplementation> CreateEd25519Implementation() { + return std::make_unique<Ed25519Implementation>(); +} + +} // namespace webcrypto
diff --git a/components/webcrypto/algorithms/x25519.cc b/components/webcrypto/algorithms/x25519.cc new file mode 100644 index 0000000..aba892e --- /dev/null +++ b/components/webcrypto/algorithms/x25519.cc
@@ -0,0 +1,36 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/webcrypto/algorithm_implementation.h" +#include "components/webcrypto/status.h" + +namespace webcrypto { + +namespace { + +// This class implements the key agreement algorithm using the X25519 function +// based on Curve25519 specified by RFC 7748, to which is also referred as the +// X25519 algorithm by RFC 8410. +// +// TODO(crbug.com/1032821): See also +// https://chromestatus.com/feature/4913922408710144. +class X25519Implementation : public AlgorithmImplementation { + public: + Status DeriveBits(const blink::WebCryptoAlgorithm& algorithm, + const blink::WebCryptoKey& base_key, + bool has_optional_length_bits, + unsigned int optional_length_bits, + std::vector<uint8_t>* derived_bytes) const override { + // TODO(crbug.com/1032821): Implement this. + return Status::ErrorUnsupported(); + } +}; + +} // namespace + +std::unique_ptr<AlgorithmImplementation> CreateX25519Implementation() { + return std::make_unique<X25519Implementation>(); +} + +} // namespace webcrypto
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc index fd67cb2..1456233 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.cc +++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -686,25 +686,26 @@ const bool is_selected = node->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected); - bool multiselect = false; - auto* selection_container = node->PlatformGetSelectionContainer(); - if (selection_container && - selection_container->HasState(ax::mojom::State::kMultiselectable)) - multiselect = true; - - if (multiselect) { + // Nodes that have selection container may support multiselect, for such nodes + // we add them to |selection_events_|, which FinalizeAccessibilityEvents + // handles selection item events firing. + // For nodes that do not have selection container, only single select is + // supported, selection item events firing are handled here. + if (auto* selection_container = node->PlatformGetSelectionContainer()) { if (is_selected) { - FireWinAccessibilityEvent(EVENT_OBJECT_SELECTIONADD, node); - if (::switches::IsExperimentalAccessibilityPlatformUIAEnabled()) - selection_events_[selection_container].added.push_back(node); + selection_events_[selection_container].added.push_back(node); + } else { + selection_events_[selection_container].removed.push_back(node); + } + } else { + if (is_selected) { + FireWinAccessibilityEvent(EVENT_OBJECT_SELECTION, node); + FireUiaAccessibilityEvent(UIA_SelectionItem_ElementSelectedEventId, node); } else { FireWinAccessibilityEvent(EVENT_OBJECT_SELECTIONREMOVE, node); - if (::switches::IsExperimentalAccessibilityPlatformUIAEnabled()) - selection_events_[selection_container].removed.push_back(node); + FireUiaAccessibilityEvent( + UIA_SelectionItem_ElementRemovedFromSelectionEventId, node); } - } else if (is_selected) { - FireWinAccessibilityEvent(EVENT_OBJECT_SELECTION, node); - FireUiaAccessibilityEvent(UIA_SelectionItem_ElementSelectedEventId, node); } } @@ -730,17 +731,20 @@ void BrowserAccessibilityManagerWin::FinalizeAccessibilityEvents() { BrowserAccessibilityManager::FinalizeAccessibilityEvents(); + // Finalize aria properties events. for (auto&& event_node : aria_properties_events_) { FireUiaPropertyChangedEvent(UIA_AriaPropertiesPropertyId, event_node); } aria_properties_events_.clear(); + // Finalize text selection events. for (auto&& sel_event_node : text_selection_changed_events_) { FireUiaTextContainerEvent(UIA_Text_TextSelectionChangedEventId, sel_event_node); } text_selection_changed_events_.clear(); + // Finalize selection item events. for (auto&& selected : selection_events_) { auto* container = selected.first; auto&& changes = selected.second; @@ -760,6 +764,7 @@ if (selected_count == 1) { // Fire 'ElementSelected' on the only selected child + FireWinAccessibilityEvent(EVENT_OBJECT_SELECTION, first_selected_child); FireUiaAccessibilityEvent(UIA_SelectionItem_ElementSelectedEventId, first_selected_child); } else { @@ -771,10 +776,18 @@ FireUiaAccessibilityEvent(UIA_Selection_InvalidatedEventId, container); } else { for (auto* item : changes.added) { - FireUiaAccessibilityEvent( - UIA_SelectionItem_ElementAddedToSelectionEventId, item); + if (container->HasState(ax::mojom::State::kMultiselectable)) { + FireWinAccessibilityEvent(EVENT_OBJECT_SELECTIONADD, item); + FireUiaAccessibilityEvent( + UIA_SelectionItem_ElementAddedToSelectionEventId, item); + } else { + FireWinAccessibilityEvent(EVENT_OBJECT_SELECTION, item); + FireUiaAccessibilityEvent(UIA_SelectionItem_ElementSelectedEventId, + item); + } } for (auto* item : changes.removed) { + FireWinAccessibilityEvent(EVENT_OBJECT_SELECTIONREMOVE, item); FireUiaAccessibilityEvent( UIA_SelectionItem_ElementRemovedFromSelectionEventId, item); }
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc index bc40391..4358ebb 100644 --- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -796,18 +796,8 @@ RunEventTest(FILE_PATH_LITERAL("visibility-hidden-changed.html")); } -// Even with the deflaking in WaitForAccessibilityTreeToContainNodeWithName, -// this test is still flaky on Windows. -// TODO(aboxhall, dmazzoni, meredithl): re-enable with better fix for above. -#if defined(OS_WIN) -#define MAYBE_AccessibilityEventsAriaSelectedChanged \ - DISABLED_AccessibilityEventsAriaSelectedChanged -#else -#define MAYBE_AccessibilityEventsAriaSelectedChanged \ - AccessibilityEventsAriaSelectedChanged -#endif IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest, - MAYBE_AccessibilityEventsAriaSelectedChanged) { + AccessibilityEventsAriaSelectedChanged) { RunEventTest(FILE_PATH_LITERAL("aria-selected-changed.html")); }
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index 1917eea4..c4efc75d 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -1006,9 +1006,8 @@ RunAriaTest(FILE_PATH_LITERAL("aria-sort-aria-grid.html")); } -// Flaky. http://crbug.com/952904 IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - DISABLED_AccessibilityAriaSetCountsWithTreeLevels) { + AccessibilityAriaSetCountsWithTreeLevels) { RunAriaTest(FILE_PATH_LITERAL("aria-set-counts-with-tree-levels.html")); }
diff --git a/content/browser/appcache/appcache_internals_ui.cc b/content/browser/appcache/appcache_internals_ui.cc index 05b7bef..0d23b0a 100644 --- a/content/browser/appcache/appcache_internals_ui.cc +++ b/content/browser/appcache/appcache_internals_ui.cc
@@ -368,10 +368,10 @@ source->AddResourcePath("appcache_internals.css", IDR_APPCACHE_INTERNALS_CSS); source->SetDefaultResource(IDR_APPCACHE_INTERNALS_HTML); - WebUIDataSource::Add(browser_context(), source); + WebUIDataSource::Add(GetBrowserContext(), source); BrowserContext::ForEachStoragePartition( - browser_context(), + GetBrowserContext(), base::BindRepeating(&AppCacheInternalsUI::CreateProxyForPartition, AsWeakPtr())); } @@ -434,7 +434,7 @@ scoped_refptr<AppCacheInfoCollection> collection, const base::FilePath& partition_path) { std::string incognito_path_prefix; - if (browser_context()->IsOffTheRecord()) + if (GetBrowserContext()->IsOffTheRecord()) incognito_path_prefix = "Incognito "; web_ui()->CallJavascriptFunctionUnsafe( kFunctionOnAllAppCacheInfoReady, @@ -514,6 +514,10 @@ base::Value(net_result_code)); } +BrowserContext* AppCacheInternalsUI::GetBrowserContext() { + return web_ui()->GetWebContents()->GetBrowserContext(); +} + AppCacheInternalsUI::Proxy* AppCacheInternalsUI::GetProxyForPartitionPath( const base::FilePath& partition_path) { for (const scoped_refptr<Proxy>& proxy : appcache_proxies_) {
diff --git a/content/browser/appcache/appcache_internals_ui.h b/content/browser/appcache/appcache_internals_ui.h index d2d4d55..853f8df 100644 --- a/content/browser/appcache/appcache_internals_ui.h +++ b/content/browser/appcache/appcache_internals_ui.h
@@ -120,9 +120,7 @@ void OnFileDetailsFailed(const ProxyResponseEnquiry& response_enquiry, int data_length); - BrowserContext* browser_context() { - return web_ui()->GetWebContents()->GetBrowserContext(); - } + BrowserContext* GetBrowserContext(); Proxy* GetProxyForPartitionPath(const base::FilePath& path); std::list<scoped_refptr<Proxy>> appcache_proxies_; @@ -132,4 +130,5 @@ }; } // namespace content -#endif + +#endif // CONTENT_BROWSER_APPCACHE_APPCACHE_INTERNALS_UI_H_
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index fce4c01..07eebdd7 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -243,6 +243,24 @@ return true; } +bool IsSiteInstanceCompatibleWithErrorIsolation(SiteInstance* site_instance, + bool is_main_frame, + bool is_failure) { + // With no error isolation all SiteInstances are compatible with any + // |is_failure|. + if (!SiteIsolationPolicy::IsErrorPageIsolationEnabled(is_main_frame)) + return true; + + // When error page isolation is enabled, don't reuse |site_instance| if it's + // an error page SiteInstance, but the navigation is not a failure. + // Similarly, don't reuse |site_instance| if it's not an error page + // SiteInstance but the navigation will fail and actually need an error page + // SiteInstance. + bool is_site_instance_for_failures = + site_instance->GetSiteURL() == GURL(kUnreachableWebDataURL); + return is_site_instance_for_failures == is_failure; +} + } // namespace RenderFrameHostManager::RenderFrameHostManager(FrameTreeNode* frame_tree_node, @@ -1541,18 +1559,11 @@ // If the entry has an instance already we should usually use it, unless it is // no longer suitable. if (dest_instance) { - // When error page isolation is enabled, don't reuse |dest_instance| if it's - // an error page SiteInstance, but the navigation will no longer fail. - // Similarly, don't reuse |dest_instance| if it's not an error page - // SiteInstance but the navigation will fail and actually need an error page - // SiteInstance. // Note: The later call to IsSuitableForURL does not have context about - // error page navigaions, so we cannot rely on it to return correct value + // error page navigations, so we cannot rely on it to return correct value // when error pages are involved. - if (!SiteIsolationPolicy::IsErrorPageIsolationEnabled( - frame_tree_node_->IsMainFrame()) || - ((dest_instance->GetSiteURL() == GURL(kUnreachableWebDataURL)) == - is_failure)) { + if (IsSiteInstanceCompatibleWithErrorIsolation( + dest_instance, frame_tree_node_->IsMainFrame(), is_failure)) { // TODO(nasko,creis): The check whether data: or about: URLs are allowed // to commit in the current process should be in IsSuitableForURL. // However, making this change has further implications and needs more @@ -1712,16 +1723,23 @@ // about:blank pages because the content is then controlled and/or scriptable // by the source SiteInstance. // - // One exception to this is when these URLs are - // reached via a server redirect. Normally, redirects to data: or about: - // URLs are disallowed as net::ERR_UNSAFE_REDIRECT, but extensions can still - // redirect arbitary requests to those URLs using webRequest or - // declarativeWebRequest API (for an example, see - // ExtensionWebRequestApiTest.WebRequestDeclarative1). For these cases, the - // content isn't controlled by the source SiteInstance, so we don't use the - // |source_instance| if there was a server redirect. - if (source_instance && IsDataOrAbout(dest_url) && !was_server_redirect) + // One exception to this is when these URLs are reached via a server redirect. + // Normally, redirects to data: or about: URLs are disallowed as + // net::ERR_UNSAFE_REDIRECT, but extensions can still redirect arbitrary + // requests to those URLs using webRequest or declarativeWebRequest API (for + // an example, see NavigationInitiatedByCrossSiteSubframeRedirectedTo... test + // cases in the ChromeNavigationBrowserTest test suite. For such data: URL + // redirects, the content is controlled by the extension (rather than by the + // |source_instance|), so we don't use the |source_instance| for data: URLs if + // there was a server redirect. + bool can_use_source_instance_for_dest_url = + IsDataOrAbout(dest_url) && + (!was_server_redirect || !dest_url.SchemeIs(url::kDataScheme)); + if (can_use_source_instance_for_dest_url && source_instance && + IsSiteInstanceCompatibleWithErrorIsolation( + source_instance, frame_tree_node_->IsMainFrame(), is_failure)) { return SiteInstanceDescriptor(source_instance); + } // Use the current SiteInstance for same site navigations. if (IsCurrentlySameSite(render_frame_host_.get(), dest_url))
diff --git a/content/browser/gpu/gpu_data_manager_impl.cc b/content/browser/gpu/gpu_data_manager_impl.cc index 48abe10..5e473bd 100644 --- a/content/browser/gpu/gpu_data_manager_impl.cc +++ b/content/browser/gpu/gpu_data_manager_impl.cc
@@ -30,6 +30,12 @@ return private_->GetGPUInfo(); } +gpu::GpuFeatureStatus GpuDataManagerImpl::GetFeatureStatus( + gpu::GpuFeatureType feature) { + base::AutoLock auto_lock(lock_); + return private_->GetFeatureStatus(feature); +} + bool GpuDataManagerImpl::GpuAccessAllowed(std::string* reason) { base::AutoLock auto_lock(lock_); return private_->GpuAccessAllowed(reason); @@ -57,12 +63,6 @@ return private_->IsGpuFeatureInfoAvailable(); } -gpu::GpuFeatureStatus GpuDataManagerImpl::GetFeatureStatus( - gpu::GpuFeatureType feature) const { - base::AutoLock auto_lock(lock_); - return private_->GetFeatureStatus(feature); -} - void GpuDataManagerImpl::RequestVideoMemoryUsageStatsUpdate( VideoMemoryUsageStatsCallback callback) { base::AutoLock auto_lock(lock_);
diff --git a/content/browser/gpu/gpu_data_manager_impl.h b/content/browser/gpu/gpu_data_manager_impl.h index a7d141e9..7ddcc0a 100644 --- a/content/browser/gpu/gpu_data_manager_impl.h +++ b/content/browser/gpu/gpu_data_manager_impl.h
@@ -51,6 +51,7 @@ // GpuDataManager implementation. void BlacklistWebGLForTesting() override; gpu::GPUInfo GetGPUInfo() override; + gpu::GpuFeatureStatus GetFeatureStatus(gpu::GpuFeatureType feature) override; bool GpuAccessAllowed(std::string* reason) override; void RequestDxdiagDx12VulkanGpuInfoIfNeeded(GpuInfoRequest request, bool delayed) override; @@ -73,7 +74,6 @@ bool IsDx12VulkanVersionAvailable() const; bool IsGpuFeatureInfoAvailable() const; - gpu::GpuFeatureStatus GetFeatureStatus(gpu::GpuFeatureType feature) const; void UpdateGpuInfo( const gpu::GPUInfo& gpu_info,
diff --git a/content/browser/net/network_errors_listing_ui.cc b/content/browser/net/network_errors_listing_ui.cc index 398c9a7..b892365d 100644 --- a/content/browser/net/network_errors_listing_ui.cc +++ b/content/browser/net/network_errors_listing_ui.cc
@@ -13,6 +13,7 @@ #include "base/values.h" #include "content/grit/dev_ui_content_resources.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui.h" #include "content/public/common/url_constants.h" #include "net/base/net_errors.h" #include "net/log/net_log_util.h"
diff --git a/content/browser/service_worker/service_worker_registry.cc b/content/browser/service_worker/service_worker_registry.cc index eb982386..2435d2ba 100644 --- a/content/browser/service_worker/service_worker_registry.cc +++ b/content/browser/service_worker/service_worker_registry.cc
@@ -22,13 +22,13 @@ namespace { blink::ServiceWorkerStatusCode DatabaseStatusToStatusCode( - ServiceWorkerDatabase::Status status) { + storage::mojom::ServiceWorkerDatabaseStatus status) { switch (status) { - case ServiceWorkerDatabase::Status::kOk: + case storage::mojom::ServiceWorkerDatabaseStatus::kOk: return blink::ServiceWorkerStatusCode::kOk; - case ServiceWorkerDatabase::Status::kErrorNotFound: + case storage::mojom::ServiceWorkerDatabaseStatus::kErrorNotFound: return blink::ServiceWorkerStatusCode::kErrorNotFound; - case ServiceWorkerDatabase::Status::kErrorDisabled: + case storage::mojom::ServiceWorkerDatabaseStatus::kErrorDisabled: return blink::ServiceWorkerStatusCode::kErrorAbort; NOTREACHED(); default: @@ -40,7 +40,7 @@ ServiceWorkerRegistry::StatusCallback callback) { return base::BindOnce( [](ServiceWorkerRegistry::StatusCallback callback, - ServiceWorkerDatabase::Status database_status) { + storage::mojom::ServiceWorkerDatabaseStatus database_status) { blink::ServiceWorkerStatusCode status = DatabaseStatusToStatusCode(database_status); std::move(callback).Run(status); @@ -753,9 +753,10 @@ FindRegistrationCallback callback, std::unique_ptr<ServiceWorkerDatabase::RegistrationData> data, std::unique_ptr<ResourceList> resources, - ServiceWorkerDatabase::Status database_status) { - if (database_status != ServiceWorkerDatabase::Status::kOk && - database_status != ServiceWorkerDatabase::Status::kErrorNotFound) { + storage::mojom::ServiceWorkerDatabaseStatus database_status) { + if (database_status != storage::mojom::ServiceWorkerDatabaseStatus::kOk && + database_status != + storage::mojom::ServiceWorkerDatabaseStatus::kErrorNotFound) { ScheduleDeleteAndStartOver(); } @@ -801,9 +802,10 @@ FindRegistrationCallback callback, std::unique_ptr<ServiceWorkerDatabase::RegistrationData> data, std::unique_ptr<ResourceList> resources, - ServiceWorkerDatabase::Status database_status) { - if (database_status != ServiceWorkerDatabase::Status::kOk && - database_status != ServiceWorkerDatabase::Status::kErrorNotFound) { + storage::mojom::ServiceWorkerDatabaseStatus database_status) { + if (database_status != storage::mojom::ServiceWorkerDatabaseStatus::kOk && + database_status != + storage::mojom::ServiceWorkerDatabaseStatus::kErrorNotFound) { ScheduleDeleteAndStartOver(); } @@ -825,9 +827,10 @@ FindRegistrationCallback callback, std::unique_ptr<ServiceWorkerDatabase::RegistrationData> data, std::unique_ptr<ResourceList> resources, - ServiceWorkerDatabase::Status database_status) { - if (database_status != ServiceWorkerDatabase::Status::kOk && - database_status != ServiceWorkerDatabase::Status::kErrorNotFound) { + storage::mojom::ServiceWorkerDatabaseStatus database_status) { + if (database_status != storage::mojom::ServiceWorkerDatabaseStatus::kOk && + database_status != + storage::mojom::ServiceWorkerDatabaseStatus::kErrorNotFound) { ScheduleDeleteAndStartOver(); } @@ -858,7 +861,7 @@ void ServiceWorkerRegistry::DidGetRegistrationsForOrigin( GetRegistrationsCallback callback, const GURL& origin_filter, - ServiceWorkerDatabase::Status database_status, + storage::mojom::ServiceWorkerDatabaseStatus database_status, std::unique_ptr<RegistrationList> registration_data_list, std::unique_ptr<std::vector<ResourceList>> resources_list) { DCHECK(origin_filter.is_valid()); @@ -901,7 +904,7 @@ void ServiceWorkerRegistry::DidGetAllRegistrations( GetRegistrationsInfosCallback callback, - ServiceWorkerDatabase::Status database_status, + storage::mojom::ServiceWorkerDatabaseStatus database_status, std::unique_ptr<RegistrationList> registration_data_list) { blink::ServiceWorkerStatusCode status = DatabaseStatusToStatusCode(database_status); @@ -993,7 +996,7 @@ void ServiceWorkerRegistry::DidStoreRegistration( const ServiceWorkerDatabase::RegistrationData& data, StatusCallback callback, - ServiceWorkerDatabase::Status database_status, + storage::mojom::ServiceWorkerDatabaseStatus database_status, int64_t deleted_version_id, const std::vector<int64_t>& newly_purgeable_resources) { blink::ServiceWorkerStatusCode status = @@ -1036,7 +1039,7 @@ void ServiceWorkerRegistry::DidDeleteRegistration( int64_t registration_id, StatusCallback callback, - ServiceWorkerDatabase::Status database_status, + storage::mojom::ServiceWorkerDatabaseStatus database_status, int64_t deleted_version_id, const std::vector<int64_t>& newly_purgeable_resources) { blink::ServiceWorkerStatusCode status = @@ -1062,24 +1065,24 @@ void ServiceWorkerRegistry::DidUpdateToActiveState( const GURL& origin, StatusCallback callback, - ServiceWorkerDatabase::Status status) { - if (status != ServiceWorkerDatabase::Status::kOk && - status != ServiceWorkerDatabase::Status::kErrorNotFound) { + storage::mojom::ServiceWorkerDatabaseStatus status) { + if (status != storage::mojom::ServiceWorkerDatabaseStatus::kOk && + status != storage::mojom::ServiceWorkerDatabaseStatus::kErrorNotFound) { ScheduleDeleteAndStartOver(); } std::move(callback).Run(DatabaseStatusToStatusCode(status)); } void ServiceWorkerRegistry::DidWriteUncommittedResourceIds( - ServiceWorkerDatabase::Status status) { - if (status != ServiceWorkerDatabase::Status::kOk) + storage::mojom::ServiceWorkerDatabaseStatus status) { + if (status != storage::mojom::ServiceWorkerDatabaseStatus::kOk) ScheduleDeleteAndStartOver(); } void ServiceWorkerRegistry::DidDoomUncommittedResourceIds( const std::set<int64_t>& resource_ids, - ServiceWorkerDatabase::Status status) { - if (status != ServiceWorkerDatabase::Status::kOk) { + storage::mojom::ServiceWorkerDatabaseStatus status) { + if (status != storage::mojom::ServiceWorkerDatabaseStatus::kOk) { ScheduleDeleteAndStartOver(); return; } @@ -1089,9 +1092,9 @@ void ServiceWorkerRegistry::DidGetUserData( GetUserDataCallback callback, const std::vector<std::string>& data, - ServiceWorkerDatabase::Status status) { - if (status != ServiceWorkerDatabase::Status::kOk && - status != ServiceWorkerDatabase::Status::kErrorNotFound) { + storage::mojom::ServiceWorkerDatabaseStatus status) { + if (status != storage::mojom::ServiceWorkerDatabaseStatus::kOk && + status != storage::mojom::ServiceWorkerDatabaseStatus::kErrorNotFound) { ScheduleDeleteAndStartOver(); } std::move(callback).Run(data, DatabaseStatusToStatusCode(status)); @@ -1100,9 +1103,9 @@ void ServiceWorkerRegistry::DidGetUserKeysAndData( GetUserKeysAndDataCallback callback, const base::flat_map<std::string, std::string>& data_map, - ServiceWorkerDatabase::Status status) { - if (status != ServiceWorkerDatabase::Status::kOk && - status != ServiceWorkerDatabase::Status::kErrorNotFound) { + storage::mojom::ServiceWorkerDatabaseStatus status) { + if (status != storage::mojom::ServiceWorkerDatabaseStatus::kOk && + status != storage::mojom::ServiceWorkerDatabaseStatus::kErrorNotFound) { ScheduleDeleteAndStartOver(); } std::move(callback).Run(data_map, DatabaseStatusToStatusCode(status)); @@ -1110,12 +1113,12 @@ void ServiceWorkerRegistry::DidStoreUserData( StatusCallback callback, - ServiceWorkerDatabase::Status status) { + storage::mojom::ServiceWorkerDatabaseStatus status) { // |status| can be NOT_FOUND when the associated registration did not exist in // the database. In the case, we don't have to schedule the corruption // recovery. - if (status != ServiceWorkerDatabase::Status::kOk && - status != ServiceWorkerDatabase::Status::kErrorNotFound) { + if (status != storage::mojom::ServiceWorkerDatabaseStatus::kOk && + status != storage::mojom::ServiceWorkerDatabaseStatus::kErrorNotFound) { ScheduleDeleteAndStartOver(); } std::move(callback).Run(DatabaseStatusToStatusCode(status)); @@ -1123,8 +1126,8 @@ void ServiceWorkerRegistry::DidClearUserData( StatusCallback callback, - ServiceWorkerDatabase::Status status) { - if (status != ServiceWorkerDatabase::Status::kOk) + storage::mojom::ServiceWorkerDatabaseStatus status) { + if (status != storage::mojom::ServiceWorkerDatabaseStatus::kOk) ScheduleDeleteAndStartOver(); std::move(callback).Run(DatabaseStatusToStatusCode(status)); } @@ -1132,8 +1135,8 @@ void ServiceWorkerRegistry::DidGetUserDataForAllRegistrations( GetUserDataForAllRegistrationsCallback callback, const std::vector<std::pair<int64_t, std::string>>& user_data, - ServiceWorkerDatabase::Status status) { - if (status != ServiceWorkerDatabase::Status::kOk) + storage::mojom::ServiceWorkerDatabaseStatus status) { + if (status != storage::mojom::ServiceWorkerDatabaseStatus::kOk) ScheduleDeleteAndStartOver(); std::move(callback).Run(user_data, DatabaseStatusToStatusCode(status)); }
diff --git a/content/browser/service_worker/service_worker_registry.h b/content/browser/service_worker/service_worker_registry.h index 184d481..be657aa 100644 --- a/content/browser/service_worker/service_worker_registry.h +++ b/content/browser/service_worker/service_worker_registry.h
@@ -254,64 +254,67 @@ FindRegistrationCallback callback, std::unique_ptr<ServiceWorkerDatabase::RegistrationData> data, std::unique_ptr<ResourceList> resources, - ServiceWorkerDatabase::Status database_status); + storage::mojom::ServiceWorkerDatabaseStatus database_status); void DidFindRegistrationForScope( FindRegistrationCallback callback, std::unique_ptr<ServiceWorkerDatabase::RegistrationData> data, std::unique_ptr<ResourceList> resources, - ServiceWorkerDatabase::Status database_status); + storage::mojom::ServiceWorkerDatabaseStatus database_status); void DidFindRegistrationForId( int64_t registration_id, FindRegistrationCallback callback, std::unique_ptr<ServiceWorkerDatabase::RegistrationData> data, std::unique_ptr<ResourceList> resources, - ServiceWorkerDatabase::Status database_status); + storage::mojom::ServiceWorkerDatabaseStatus database_status); void DidGetRegistrationsForOrigin( GetRegistrationsCallback callback, const GURL& origin_filter, - ServiceWorkerDatabase::Status database_status, + storage::mojom::ServiceWorkerDatabaseStatus database_status, std::unique_ptr<RegistrationList> registration_data_list, std::unique_ptr<std::vector<ResourceList>> resources_list); void DidGetAllRegistrations( GetRegistrationsInfosCallback callback, - ServiceWorkerDatabase::Status database_status, + storage::mojom::ServiceWorkerDatabaseStatus database_status, std::unique_ptr<RegistrationList> registration_data_list); void DidStoreRegistration( const ServiceWorkerDatabase::RegistrationData& data, StatusCallback callback, - ServiceWorkerDatabase::Status database_status, + storage::mojom::ServiceWorkerDatabaseStatus database_status, int64_t deleted_version_id, const std::vector<int64_t>& newly_purgeable_resources); void DidDeleteRegistration( int64_t registration_id, StatusCallback callback, - ServiceWorkerDatabase::Status database_status, + storage::mojom::ServiceWorkerDatabaseStatus database_status, int64_t deleted_version_id, const std::vector<int64_t>& newly_purgeable_resources); - void DidUpdateToActiveState(const GURL& origin, - StatusCallback callback, - ServiceWorkerDatabase::Status status); - void DidWriteUncommittedResourceIds(ServiceWorkerDatabase::Status status); - void DidDoomUncommittedResourceIds(const std::set<int64_t>& resource_ids, - ServiceWorkerDatabase::Status status); + void DidUpdateToActiveState( + const GURL& origin, + StatusCallback callback, + storage::mojom::ServiceWorkerDatabaseStatus status); + void DidWriteUncommittedResourceIds( + storage::mojom::ServiceWorkerDatabaseStatus status); + void DidDoomUncommittedResourceIds( + const std::set<int64_t>& resource_ids, + storage::mojom::ServiceWorkerDatabaseStatus status); void DidGetUserData(GetUserDataCallback callback, const std::vector<std::string>& data, - ServiceWorkerDatabase::Status status); + storage::mojom::ServiceWorkerDatabaseStatus status); void DidGetUserKeysAndData( GetUserKeysAndDataCallback callback, const base::flat_map<std::string, std::string>& data_map, - ServiceWorkerDatabase::Status status); + storage::mojom::ServiceWorkerDatabaseStatus status); void DidStoreUserData(StatusCallback callback, - ServiceWorkerDatabase::Status status); + storage::mojom::ServiceWorkerDatabaseStatus status); void DidClearUserData(StatusCallback callback, - ServiceWorkerDatabase::Status status); + storage::mojom::ServiceWorkerDatabaseStatus status); void DidGetUserDataForAllRegistrations( GetUserDataForAllRegistrationsCallback callback, const std::vector<std::pair<int64_t, std::string>>& user_data, - ServiceWorkerDatabase::Status status); + storage::mojom::ServiceWorkerDatabaseStatus status); void DidGetNewRegistrationId( blink::mojom::ServiceWorkerRegistrationOptions options,
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java index fc617d4..647fa2a3 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
@@ -16,6 +16,8 @@ import android.provider.Settings; import android.text.SpannableString; import android.text.style.URLSpan; +import android.util.SparseArray; +import android.util.SparseLongArray; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -46,8 +48,12 @@ import org.chromium.ui.base.WindowAndroid; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.HashSet; import java.util.List; import java.util.Locale; +import java.util.Set; /** * Implementation of {@link WebContentsAccessibility} interface. @@ -81,6 +87,9 @@ // Constant for no granularity selected. private static final int NO_GRANULARITY_SELECTED = 0; + // Constant for throttling delay of successive accessibility events in milliseconds. + private static final int ACCESSIBILITY_EVENT_DELAY = 100; + private final WebContentsImpl mWebContents; protected AccessibilityManager mAccessibilityManager; protected final Context mContext; @@ -126,6 +135,19 @@ // Accessibility touch exploration state. private boolean mTouchExplorationEnabled; + // Unordered list of event types we will throttle if multiple events of the given type are sent + // in quick succession. + private Set<Integer> mEventsToThrottle = new HashSet<Integer>(Arrays.asList( + AccessibilityEvent.TYPE_VIEW_SCROLLED, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED)); + + // For events being throttled (see: |mEventsToThrottle|), this array will map the eventType + // to the last time (long in milliseconds) such an event has been sent. + private SparseLongArray mEventLastFiredTimes = new SparseLongArray(); + + // For events being throttled (see: |mEventsToThrottle|), this array will map the eventType + // to a single Runnable that will send an event after some delay. + private SparseArray<Runnable> mPendingEvents = new SparseArray<>(); + /** * Create a WebContentsAccessibilityImpl object. */ @@ -323,7 +345,7 @@ public void setObscuredByAnotherView(boolean isObscured) { if (isObscured != mIsObscuredByAnotherView) { mIsObscuredByAnotherView = isObscured; - mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); + sendAccessibilityEvent(View.NO_ID, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); } } @@ -676,7 +698,7 @@ // Invalidate the container view, since the chrome accessibility tree is now // ready and listed as the child of the container view. - sendWindowContentChangedOnView(); + sendAccessibilityEvent(View.NO_ID, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); // (Re-) focus focused element, since we weren't able to create an // AccessibilityNodeInfo for this element before. @@ -943,28 +965,7 @@ */ @CalledByNative private void sendDelayedWindowContentChangedEvent() { - if (mSendWindowContentChangedRunnable != null) return; - - mSendWindowContentChangedRunnable = new Runnable() { - @Override - public void run() { - sendWindowContentChangedOnView(); - } - }; - - mView.postDelayed(mSendWindowContentChangedRunnable, WINDOW_CONTENT_CHANGED_DELAY_MS); - } - - private void sendWindowContentChangedOnView() { - if (mSendWindowContentChangedRunnable != null) { - mView.removeCallbacks(mSendWindowContentChangedRunnable); - mSendWindowContentChangedRunnable = null; - } - mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); - } - - private void sendWindowContentChangedOnVirtualView(int virtualViewId) { - sendAccessibilityEvent(virtualViewId, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); + sendAccessibilityEvent(View.NO_ID, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); } private void sendAccessibilityEvent(int virtualViewId, int eventType) { @@ -983,8 +984,49 @@ } AccessibilityEvent event = buildAccessibilityEvent(virtualViewId, eventType); - if (event != null) { + if (event == null) return; + + // Check whether this type of event is one we want to throttle, and if not then send it + if (!mEventsToThrottle.contains(eventType)) { mView.requestSendAccessibilityEvent(mView, event); + return; + } + + // Check when we last fired an event. If we have not fired an event of this type, or the + // last time was longer than |ACCESSIBILITY_EVENT_DELAY| ago, then we allow this event + // to be sent immediately and record the time and clear any lingering callbacks. + long now = Calendar.getInstance().getTimeInMillis(); + if (now - mEventLastFiredTimes.get(eventType, 0) >= ACCESSIBILITY_EVENT_DELAY) { + mView.requestSendAccessibilityEvent(mView, event); + mView.removeCallbacks(mPendingEvents.get(eventType)); + mPendingEvents.remove(eventType); + mEventLastFiredTimes.put(eventType, now); + } else { + // We have fired an event within our |ACCESSIBILITY_EVENT_DELAY| delay window. + // Store this event, replacing any events in |mPendingEvents| of the same type, + // and set a delay equal to remaining time in our delay. + mView.removeCallbacks(mPendingEvents.get(eventType)); + + Runnable myRunnable = () -> { + // We have delayed firing this event, so accessibility may not be enabled or the + // node may be invalid. Only fire if neither of these are the case. + if (isAccessibilityEnabled() + && WebContentsAccessibilityImplJni.get().isNodeValid( + mNativeObj, WebContentsAccessibilityImpl.this, virtualViewId)) { + mView.requestSendAccessibilityEvent(mView, event); + + // After sending event, record time it was sent + mEventLastFiredTimes.put(eventType, Calendar.getInstance().getTimeInMillis()); + } + + // Remove callbacks and pending event + mView.removeCallbacks(mPendingEvents.get(eventType)); + mPendingEvents.remove(eventType); + }; + + mView.postDelayed(myRunnable, + (mEventLastFiredTimes.get(eventType, 0) + ACCESSIBILITY_EVENT_DELAY) - now); + mPendingEvents.put(eventType, myRunnable); } } @@ -1141,9 +1183,9 @@ mNativeObj, WebContentsAccessibilityImpl.this); if (rootId != mCurrentRootId) { mCurrentRootId = rootId; - sendWindowContentChangedOnView(); + sendAccessibilityEvent(View.NO_ID, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); } else { - sendWindowContentChangedOnVirtualView(id); + sendAccessibilityEvent(id, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); } } @@ -1153,7 +1195,7 @@ mAccessibilityFocusRect = null; mUserHasTouchExplored = false; // Invalidate the host, since its child is now gone. - sendWindowContentChangedOnView(); + sendAccessibilityEvent(View.NO_ID, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); } @CalledByNative
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 4669e9f..a996e9d 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -1488,7 +1488,7 @@ virtual std::vector<base::FilePath> GetNetworkContextsParentDirectory(); #if defined(OS_ANDROID) - // Only used by Android WebView. + // Only used by Android WebView/WebLayer. // Returns: // true - The check was successfully performed without throwing a // Java exception. |*ignore_navigation| is set to the
diff --git a/content/public/browser/gpu_data_manager.h b/content/public/browser/gpu_data_manager.h index 2bbb8ade..a2436294 100644 --- a/content/public/browser/gpu_data_manager.h +++ b/content/public/browser/gpu_data_manager.h
@@ -11,6 +11,8 @@ #include "base/callback_forward.h" #include "base/process/process.h" #include "content/common/content_export.h" +#include "gpu/config/gpu_feature_info.h" +#include "gpu/config/gpu_feature_type.h" namespace base { class CommandLine; @@ -50,6 +52,9 @@ virtual gpu::GPUInfo GetGPUInfo() = 0; + virtual gpu::GpuFeatureStatus GetFeatureStatus( + gpu::GpuFeatureType feature) = 0; + // This indicator might change because we could collect more GPU info or // because the GPU blacklist could be updated. // If this returns false, any further GPU access, including establishing GPU
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index 5ea3ee9..338ac21a 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h
@@ -29,7 +29,6 @@ #include "content/public/browser/screen_orientation_delegate.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/visibility.h" -#include "content/public/browser/web_ui.h" #include "content/public/common/stop_find_action.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/metrics/public/cpp/ukm_source_id.h" @@ -82,6 +81,7 @@ class RenderWidgetHost; class RenderWidgetHostView; class WebContentsDelegate; +class WebUI; struct CustomContextMenuContext; struct DropData; struct MHTMLGenerationParams;
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc index d66a7df..1fe6796 100644 --- a/content/renderer/accessibility/render_accessibility_impl.cc +++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -824,6 +824,8 @@ Scroll(target.get(), data.action); break; case ax::mojom::Action::kCustomAction: + case ax::mojom::Action::kCollapse: + case ax::mojom::Action::kExpand: case ax::mojom::Action::kReplaceSelectedText: case ax::mojom::Action::kNone: NOTREACHED();
diff --git a/content/shell/browser/web_test/blink_test_controller.cc b/content/shell/browser/web_test/blink_test_controller.cc index 9ca2e45f..546b4cc 100644 --- a/content/shell/browser/web_test/blink_test_controller.cc +++ b/content/shell/browser/web_test/blink_test_controller.cc
@@ -436,6 +436,7 @@ all_observed_render_process_hosts_.clear(); main_window_render_process_hosts_.clear(); accumulated_web_test_runtime_flags_changes_.Clear(); + blink_test_control_map_.clear(); web_test_control_map_.clear(); ShellBrowserContext* browser_context = @@ -923,6 +924,7 @@ RenderProcessHost* render_process_host) { render_process_host_observer_.Remove(render_process_host); all_observed_render_process_hosts_.erase(render_process_host); + web_test_control_map_.erase(render_process_host); main_window_render_process_hosts_.erase(render_process_host); } @@ -1052,12 +1054,12 @@ render_process_host_observer_.Add(process_host); all_observed_render_process_hosts_.insert(process_host); - if (!main_window) { + if (!main_window) GetBlinkTestControlRemote(frame)->SetupSecondaryRenderer(); - } - process_host->Send(new WebTestMsg_ReplicateWebTestRuntimeFlagsChanges( - accumulated_web_test_runtime_flags_changes_)); + GetWebTestControlRemote(process_host) + ->ReplicateWebTestRuntimeFlagsChanges( + accumulated_web_test_runtime_flags_changes_.Clone()); } } @@ -1240,8 +1242,8 @@ if (process->GetID() == sender_process_host_id) continue; - process->Send(new WebTestMsg_ReplicateWebTestRuntimeFlagsChanges( - changed_web_test_runtime_flags)); + GetWebTestControlRemote(process)->ReplicateWebTestRuntimeFlagsChanges( + changed_web_test_runtime_flags.Clone()); } } @@ -1502,20 +1504,42 @@ mojo::AssociatedRemote<mojom::BlinkTestControl>& BlinkTestController::GetBlinkTestControlRemote(RenderFrameHost* frame) { GlobalFrameRoutingId key(frame->GetProcess()->GetID(), frame->GetRoutingID()); - if (web_test_control_map_.find(key) == web_test_control_map_.end()) { + if (blink_test_control_map_.find(key) == blink_test_control_map_.end()) { mojo::AssociatedRemote<mojom::BlinkTestControl>& new_ptr = - web_test_control_map_[key]; + blink_test_control_map_[key]; frame->GetRemoteAssociatedInterfaces()->GetInterface(&new_ptr); new_ptr.set_disconnect_handler( base::BindOnce(&BlinkTestController::HandleBlinkTestControlError, weak_factory_.GetWeakPtr(), key)); } - DCHECK(web_test_control_map_[key].get()); - return web_test_control_map_[key]; + DCHECK(blink_test_control_map_[key].get()); + return blink_test_control_map_[key]; +} + +mojo::AssociatedRemote<mojom::WebTestControl>& +BlinkTestController::GetWebTestControlRemote(RenderProcessHost* process) { + if (web_test_control_map_.find(process) == web_test_control_map_.end()) { + IPC::ChannelProxy* channel = process->GetChannel(); + // channel might be null in tests. + if (process->IsInitializedAndNotDead() && channel) { + mojo::AssociatedRemote<mojom::WebTestControl>& new_ptr = + web_test_control_map_[process]; + channel->GetRemoteAssociatedInterface(&new_ptr); + new_ptr.set_disconnect_handler( + base::BindOnce(&BlinkTestController::HandleWebTestControlError, + weak_factory_.GetWeakPtr(), process)); + } + } + DCHECK(web_test_control_map_[process].get()); + return web_test_control_map_[process]; } void BlinkTestController::HandleBlinkTestControlError( const GlobalFrameRoutingId& key) { + blink_test_control_map_.erase(key); +} + +void BlinkTestController::HandleWebTestControlError(RenderProcessHost* key) { web_test_control_map_.erase(key); }
diff --git a/content/shell/browser/web_test/blink_test_controller.h b/content/shell/browser/web_test/blink_test_controller.h index c9689ea..5b772a27 100644 --- a/content/shell/browser/web_test/blink_test_controller.h +++ b/content/shell/browser/web_test/blink_test_controller.h
@@ -34,6 +34,7 @@ #include "content/public/common/web_preferences.h" #include "content/shell/browser/web_test/leak_detector.h" #include "content/shell/common/blink_test.mojom.h" +#include "content/shell/common/web_test.mojom.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "ui/gfx/geometry/size.h" @@ -240,9 +241,6 @@ void OnTestFinished(); void OnCaptureSessionHistory(); void OnLeakDetectionDone(const LeakDetector::LeakDetectionReport& report); - mojo::AssociatedRemote<mojom::BlinkTestControl>& GetBlinkTestControlRemote( - RenderFrameHost* frame); - void HandleBlinkTestControlError(const GlobalFrameRoutingId& key); void OnCleanupFinished(); void OnCaptureDumpCompleted(mojom::BlinkTestDumpPtr dump); @@ -250,6 +248,13 @@ void ReportResults(); void EnqueueSurfaceCopyRequest(); + mojo::AssociatedRemote<mojom::BlinkTestControl>& GetBlinkTestControlRemote( + RenderFrameHost* frame); + mojo::AssociatedRemote<mojom::WebTestControl>& GetWebTestControlRemote( + RenderProcessHost* process); + void HandleBlinkTestControlError(const GlobalFrameRoutingId& key); + void HandleWebTestControlError(RenderProcessHost* key); + // CompositeAllFramesThen() first builds a frame tree based on // frame->GetParent(). Then, it builds a queue of frames in depth-first order, // so that compositing happens from the leaves up. Finally, @@ -342,6 +347,9 @@ // Map from one frame to one mojo pipe. std::map<GlobalFrameRoutingId, mojo::AssociatedRemote<mojom::BlinkTestControl>> + blink_test_control_map_; + + std::map<RenderProcessHost*, mojo::AssociatedRemote<mojom::WebTestControl>> web_test_control_map_; base::ScopedTempDir writable_directory_for_tests_;
diff --git a/content/shell/common/web_test.mojom b/content/shell/common/web_test.mojom index cb6b07c..1156dd6d 100644 --- a/content/shell/common/web_test.mojom +++ b/content/shell/common/web_test.mojom
@@ -10,6 +10,15 @@ import "third_party/blink/public/mojom/permissions/permission_status.mojom"; import "url/mojom/url.mojom"; +// Web test messages sent from the browser process to the renderer. +interface WebTestControl { + // Used send flag changes to renderers - either when + // 1) broadcasting change happening in one renderer to all other renderers, or + // 2) sending accumulated changes to a single new renderer. + ReplicateWebTestRuntimeFlagsChanges( + mojo_base.mojom.DictionaryValue changed_layout_test_runtime_flags); +}; + // Web test messages sent from the renderer process to the browser. interface WebTestClient { // Start to inspect a secondary window.
diff --git a/content/shell/common/web_test/web_test_messages.h b/content/shell/common/web_test/web_test_messages.h index 79ef2c8..fbb8e14 100644 --- a/content/shell/common/web_test/web_test_messages.h +++ b/content/shell/common/web_test/web_test_messages.h
@@ -21,10 +21,4 @@ bool /* should dump navigation history */, bool /* should dump pixels */) -// Used send flag changes to renderers - either when -// 1) broadcasting change happening in one renderer to all other renderers, or -// 2) sending accumulated changes to a single new renderer. -IPC_MESSAGE_CONTROL1(WebTestMsg_ReplicateWebTestRuntimeFlagsChanges, - base::DictionaryValue /* changed_web_test_runtime_flags */) - #endif // CONTENT_SHELL_COMMON_WEB_TEST_WEB_TEST_MESSAGES_H_
diff --git a/content/shell/renderer/web_test/web_test_render_thread_observer.cc b/content/shell/renderer/web_test/web_test_render_thread_observer.cc index 6191d8e..3363d9f 100644 --- a/content/shell/renderer/web_test/web_test_render_thread_observer.cc +++ b/content/shell/renderer/web_test/web_test_render_thread_observer.cc
@@ -7,11 +7,11 @@ #include "content/public/common/content_client.h" #include "content/public/renderer/render_thread.h" #include "content/public/test/web_test_support.h" -#include "content/shell/common/web_test/web_test_messages.h" #include "content/shell/common/web_test/web_test_switches.h" #include "content/shell/test_runner/test_interfaces.h" #include "content/shell/test_runner/web_test_interfaces.h" #include "content/shell/test_runner/web_test_runner.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" namespace content { @@ -39,22 +39,32 @@ g_instance = nullptr; } -bool WebTestRenderThreadObserver::OnControlMessageReceived( - const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(WebTestRenderThreadObserver, message) - IPC_MESSAGE_HANDLER(WebTestMsg_ReplicateWebTestRuntimeFlagsChanges, - OnReplicateWebTestRuntimeFlagsChanges) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - - return handled; +void WebTestRenderThreadObserver::RegisterMojoInterfaces( + blink::AssociatedInterfaceRegistry* associated_interfaces) { + associated_interfaces->AddInterface(base::BindRepeating( + &WebTestRenderThreadObserver::OnWebTestControlAssociatedRequest, + base::Unretained(this))); } -void WebTestRenderThreadObserver::OnReplicateWebTestRuntimeFlagsChanges( - const base::DictionaryValue& changed_web_test_runtime_flags) { +void WebTestRenderThreadObserver::UnregisterMojoInterfaces( + blink::AssociatedInterfaceRegistry* associated_interfaces) { + associated_interfaces->RemoveInterface(mojom::WebTestControl::Name_); +} + +void WebTestRenderThreadObserver::OnWebTestControlAssociatedRequest( + mojo::PendingAssociatedReceiver<mojom::WebTestControl> receiver) { + receiver_.reset(); + receiver_.Bind(std::move(receiver)); +} + +void WebTestRenderThreadObserver::ReplicateWebTestRuntimeFlagsChanges( + base::Value changed_layout_test_runtime_flags) { + base::DictionaryValue* changed_web_test_runtime_flags_dictionary = nullptr; + bool ok = changed_layout_test_runtime_flags.GetAsDictionary( + &changed_web_test_runtime_flags_dictionary); + DCHECK(ok); test_interfaces()->TestRunner()->ReplicateWebTestRuntimeFlagsChanges( - changed_web_test_runtime_flags); + *changed_web_test_runtime_flags_dictionary); } } // namespace content
diff --git a/content/shell/renderer/web_test/web_test_render_thread_observer.h b/content/shell/renderer/web_test/web_test_render_thread_observer.h index a168111..e828696 100644 --- a/content/shell/renderer/web_test/web_test_render_thread_observer.h +++ b/content/shell/renderer/web_test/web_test_render_thread_observer.h
@@ -7,15 +7,11 @@ #include <memory> -#include "base/compiler_specific.h" -#include "base/files/file_path.h" #include "base/macros.h" #include "content/public/renderer/render_thread_observer.h" -#include "ipc/ipc_platform_file.h" - -namespace base { -class DictionaryValue; -} +#include "content/shell/common/web_test.mojom.h" +#include "mojo/public/cpp/bindings/associated_receiver.h" +#include "mojo/public/cpp/bindings/pending_associated_receiver.h" namespace test_runner { class WebTestInterfaces; @@ -23,27 +19,35 @@ namespace content { -class WebTestRenderThreadObserver : public RenderThreadObserver { +class WebTestRenderThreadObserver : public RenderThreadObserver, + public mojom::WebTestControl { public: static WebTestRenderThreadObserver* GetInstance(); WebTestRenderThreadObserver(); ~WebTestRenderThreadObserver() override; - // RenderThreadObserver implementation. - bool OnControlMessageReceived(const IPC::Message& message) override; - test_runner::WebTestInterfaces* test_interfaces() const { return test_interfaces_.get(); } + // content::RenderThreadObserver: + void RegisterMojoInterfaces( + blink::AssociatedInterfaceRegistry* associated_interfaces) override; + void UnregisterMojoInterfaces( + blink::AssociatedInterfaceRegistry* associated_interfaces) override; + + void ReplicateWebTestRuntimeFlagsChanges( + base::Value changed_layout_test_runtime_flags) override; + private: - // Message handlers. - void OnReplicateWebTestRuntimeFlagsChanges( - const base::DictionaryValue& changed_layout_test_runtime_flags); + void OnWebTestControlAssociatedRequest( + mojo::PendingAssociatedReceiver<mojom::WebTestControl> receiver); std::unique_ptr<test_runner::WebTestInterfaces> test_interfaces_; + mojo::AssociatedReceiver<mojom::WebTestControl> receiver_{this}; + DISALLOW_COPY_AND_ASSIGN(WebTestRenderThreadObserver); };
diff --git a/content/test/data/accessibility/aria/aria-set-counts-with-tree-levels-expected-blink.txt b/content/test/data/accessibility/aria/aria-set-counts-with-tree-levels-expected-blink.txt index d313e6f..2f36c1b71 100644 --- a/content/test/data/accessibility/aria/aria-set-counts-with-tree-levels-expected-blink.txt +++ b/content/test/data/accessibility/aria/aria-set-counts-with-tree-levels-expected-blink.txt
@@ -1,26 +1,27 @@ rootWebArea -++tree setSize=2 -++++treeItem name='Item A' hierarchicalLevel=1 setSize=2 posInSet=1 selected=false -++++++staticText name='Item A' -++++++++inlineTextBox name='Item A' -++++treeItem name='Item A1' hierarchicalLevel=2 setSize=2 posInSet=1 selected=false -++++++staticText name='Item A1' -++++++++inlineTextBox name='Item A1' -++++treeItem name='Item A1x' hierarchicalLevel=3 setSize=3 posInSet=1 selected=false -++++++staticText name='Item A1x' -++++++++inlineTextBox name='Item A1x' -++++treeItem name='Item A1y' hierarchicalLevel=3 setSize=3 posInSet=2 selected=false -++++++staticText name='Item A1y' -++++++++inlineTextBox name='Item A1y' -++++treeItem name='Item A1z' hierarchicalLevel=3 setSize=3 posInSet=3 selected=false -++++++staticText name='Item A1z' -++++++++inlineTextBox name='Item A1z' -++++treeItem name='Item A2' hierarchicalLevel=2 setSize=2 posInSet=2 selected=false -++++++staticText name='Item A2' -++++++++inlineTextBox name='Item A2' -++++treeItem name='Item B' hierarchicalLevel=1 setSize=2 posInSet=2 selected=false -++++++staticText name='Item B' -++++++++inlineTextBox name='Item B' -++++treeItem name='Item B1' hierarchicalLevel=2 setSize=1 posInSet=1 selected=false -++++++staticText name='Item B1' -++++++++inlineTextBox name='Item B1' +++genericContainer ignored +++++tree setSize=2 +++++++treeItem name='Item A' hierarchicalLevel=1 setSize=2 posInSet=1 +++++++++staticText name='Item A' +++++++++++inlineTextBox name='Item A' +++++++treeItem name='Item A1' hierarchicalLevel=2 setSize=2 posInSet=1 +++++++++staticText name='Item A1' +++++++++++inlineTextBox name='Item A1' +++++++treeItem name='Item A1x' hierarchicalLevel=3 setSize=3 posInSet=1 +++++++++staticText name='Item A1x' +++++++++++inlineTextBox name='Item A1x' +++++++treeItem name='Item A1y' hierarchicalLevel=3 setSize=3 posInSet=2 +++++++++staticText name='Item A1y' +++++++++++inlineTextBox name='Item A1y' +++++++treeItem name='Item A1z' hierarchicalLevel=3 setSize=3 posInSet=3 +++++++++staticText name='Item A1z' +++++++++++inlineTextBox name='Item A1z' +++++++treeItem name='Item A2' hierarchicalLevel=2 setSize=2 posInSet=2 +++++++++staticText name='Item A2' +++++++++++inlineTextBox name='Item A2' +++++++treeItem name='Item B' hierarchicalLevel=1 setSize=2 posInSet=2 +++++++++staticText name='Item B' +++++++++++inlineTextBox name='Item B' +++++++treeItem name='Item B1' hierarchicalLevel=2 setSize=1 posInSet=1 +++++++++staticText name='Item B1' +++++++++++inlineTextBox name='Item B1'
diff --git a/content/test/data/accessibility/aria/aria-set-counts-with-tree-levels.html b/content/test/data/accessibility/aria/aria-set-counts-with-tree-levels.html index 0a48def..6e75811 100644 --- a/content/test/data/accessibility/aria/aria-set-counts-with-tree-levels.html +++ b/content/test/data/accessibility/aria/aria-set-counts-with-tree-levels.html
@@ -1,14 +1,10 @@ <!-- +@BLINK-ALLOW:hierarchicalLevel* @BLINK-ALLOW:setSize* @BLINK-ALLOW:posInSet* @BLINK-DENY:setSize=0 @BLINK-DENY:posInSet=0 --> -<!-- According to CORE-AAM: - For role="treeitem", walk the tree backward and forward until the explicit or - computed level becomes less than the current item's level. Count items only - if they are at the same level as the current item. ---> <html> <body> <div role="tree">
diff --git a/content/test/data/accessibility/aria/aria-tablist-expected-blink.txt b/content/test/data/accessibility/aria/aria-tablist-expected-blink.txt index 3400f6f..2dc129f 100644 --- a/content/test/data/accessibility/aria/aria-tablist-expected-blink.txt +++ b/content/test/data/accessibility/aria/aria-tablist-expected-blink.txt
@@ -11,4 +11,3 @@ ++++++++++tabList horizontal hierarchicalLevel=3 setSize=1 ++++++++++++tab name='Tab 1, level 3' setSize=1 posInSet=1 selected=false ++++++tab name='Tab 3, level 1' setSize=3 posInSet=3 selected=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/event/aria-selected-changed-expected-uia-win.txt b/content/test/data/accessibility/event/aria-selected-changed-expected-uia-win.txt new file mode 100644 index 0000000..432ded82 --- /dev/null +++ b/content/test/data/accessibility/event/aria-selected-changed-expected-uia-win.txt
@@ -0,0 +1,23 @@ +AriaProperties changed on role=gridcell, name=Grid1, GridCell1 +SelectionItem_ElementRemovedFromSelection on role=gridcell, name=Grid1, GridCell1 +=== Start Continuation === +AriaProperties changed on role=gridcell, name=Grid2, GridCell2 +SelectionItem_ElementAddedToSelection on role=gridcell, name=Grid2, GridCell2 +=== Start Continuation === +AriaProperties changed on role=gridcell, name=Grid3, GridCell1 +SelectionItem_ElementRemovedFromSelection on role=gridcell, name=Grid3, GridCell1 +=== Start Continuation === +AriaProperties changed on role=gridcell, name=Grid4, GridCell1 +AriaProperties changed on role=gridcell, name=Grid4, GridCell2 +SelectionItem_ElementRemovedFromSelection on role=gridcell, name=Grid4, GridCell1 +SelectionItem_ElementSelected on role=gridcell, name=Grid4, GridCell2 +=== Start Continuation === +=== Start Continuation === +AriaProperties changed on role=listitem, name=Select2, Option1 +AriaProperties changed on role=listitem, name=Select2, Option2 +SelectionItem_ElementSelected on role=listitem, name=Select2, Option2 +ValueValue changed on role=combobox +=== Start Continuation === +AriaProperties changed on role=option, name=DivSelect, Option1 +AriaProperties changed on role=option, name=DivSelect, Option2 +SelectionItem_ElementSelected on role=option, name=DivSelect, Option2
diff --git a/content/test/data/accessibility/event/aria-selected-changed-expected-win.txt b/content/test/data/accessibility/event/aria-selected-changed-expected-win.txt index e3e48bf4..88da2d29 100644 --- a/content/test/data/accessibility/event/aria-selected-changed-expected-win.txt +++ b/content/test/data/accessibility/event/aria-selected-changed-expected-win.txt
@@ -6,10 +6,12 @@ EVENT_OBJECT_SELECTIONWITHIN on <table#Grid2> role=ROLE_SYSTEM_TABLE MULTISELECTABLE,EXTSELECTABLE EVENT_OBJECT_STATECHANGE on <td#GridCell2> role=ROLE_SYSTEM_CELL name="Grid2, GridCell2" SELECTED,FOCUSABLE,SELECTABLE === Start Continuation === +EVENT_OBJECT_SELECTIONREMOVE on <td#GridCell1> role=ROLE_SYSTEM_CELL name="Grid3, GridCell1" FOCUSABLE,SELECTABLE EVENT_OBJECT_SELECTIONWITHIN on <table#Grid3> role=ROLE_SYSTEM_TABLE EVENT_OBJECT_STATECHANGE on <td#GridCell1> role=ROLE_SYSTEM_CELL name="Grid3, GridCell1" FOCUSABLE,SELECTABLE === Start Continuation === EVENT_OBJECT_SELECTION on <td#GridCell2> role=ROLE_SYSTEM_CELL name="Grid4, GridCell2" SELECTED,FOCUSABLE,SELECTABLE +EVENT_OBJECT_SELECTIONREMOVE on <td#GridCell1> role=ROLE_SYSTEM_CELL name="Grid4, GridCell1" FOCUSABLE,SELECTABLE EVENT_OBJECT_SELECTIONWITHIN on <table#Grid4> role=ROLE_SYSTEM_TABLE EVENT_OBJECT_STATECHANGE on <td#GridCell1> role=ROLE_SYSTEM_CELL name="Grid4, GridCell1" FOCUSABLE,SELECTABLE EVENT_OBJECT_STATECHANGE on <td#GridCell2> role=ROLE_SYSTEM_CELL name="Grid4, GridCell2" SELECTED,FOCUSABLE,SELECTABLE @@ -19,7 +21,7 @@ EVENT_OBJECT_SELECTIONWITHIN on role=ROLE_SYSTEM_LIST INVISIBLE SetSize=2 EVENT_OBJECT_STATECHANGE on <option#Option1> role=ROLE_SYSTEM_LISTITEM name="Select2, Option1" INVISIBLE,FOCUSABLE,SELECTABLE PosInSet=1 SetSize=2 EVENT_OBJECT_STATECHANGE on <option#Option2> role=ROLE_SYSTEM_LISTITEM name="Select2, Option2" SELECTED,FOCUSABLE,SELECTABLE PosInSet=2 SetSize=2 -EVENT_OBJECT_VALUECHANGE on <select#Select2> role=ROLE_SYSTEM_COMBOBOX value="Select2, Option2" COLLAPSED,FOCUSABLE,HASPOPUP +EVENT_OBJECT_VALUECHANGE on <select#Select2> role=ROLE_SYSTEM_COMBOBOX value="Select2, Option2" COLLAPSED,FOCUSABLE,HASPOPUP SetSize=2 === Start Continuation === EVENT_OBJECT_SELECTION on <div#Option2> role=ROLE_SYSTEM_LISTITEM name="DivSelect, Option2" SELECTED,FOCUSED,FOCUSABLE,SELECTABLE PosInSet=2 SetSize=2 EVENT_OBJECT_SELECTIONWITHIN on <div#DivSelect> role=ROLE_SYSTEM_LIST IA2_STATE_VERTICAL SetSize=2
diff --git a/content/test/data/accessibility/event/aria-selected-changed.html b/content/test/data/accessibility/event/aria-selected-changed.html index 0c055e6..2de7db4 100644 --- a/content/test/data/accessibility/event/aria-selected-changed.html +++ b/content/test/data/accessibility/event/aria-selected-changed.html
@@ -1,3 +1,7 @@ +<!-- + @UIA-WIN-DENY:Text_TextChanged* + @UIA-WIN-DENY:Invoke_Invoked* +--> <!DOCTYPE html> <table id='Grid1' role='grid' aria-multiselectable='true'><tbody> <tr>
diff --git a/content/test/data/accessibility/event/focus-listbox-multiselect-expected-uia-win.txt b/content/test/data/accessibility/event/focus-listbox-multiselect-expected-uia-win.txt index f85e13b8..2759253 100644 --- a/content/test/data/accessibility/event/focus-listbox-multiselect-expected-uia-win.txt +++ b/content/test/data/accessibility/event/focus-listbox-multiselect-expected-uia-win.txt
@@ -2,4 +2,4 @@ AriaProperties changed on role=option, name=c AutomationFocusChanged on role=option, name=c AutomationFocusChanged on role=option, name=c -SelectionItem_ElementSelected on role=option, name=c \ No newline at end of file +SelectionItem_ElementSelected on role=option, name=c
diff --git a/content/test/data/accessibility/event/focus-listbox-multiselect-expected-win.txt b/content/test/data/accessibility/event/focus-listbox-multiselect-expected-win.txt index d8ed5e0..e96d278 100644 --- a/content/test/data/accessibility/event/focus-listbox-multiselect-expected-win.txt +++ b/content/test/data/accessibility/event/focus-listbox-multiselect-expected-win.txt
@@ -1,7 +1,6 @@ EVENT_OBJECT_FOCUS on <option#c> role=ROLE_SYSTEM_LISTITEM name="c" SELECTED,FOCUSED,FOCUSABLE,SELECTABLE PosInSet=3 SetSize=3 -EVENT_OBJECT_SELECTIONADD on <option#c> role=ROLE_SYSTEM_LISTITEM name="c" SELECTED,FOCUSED,FOCUSABLE,SELECTABLE PosInSet=3 SetSize=3 -EVENT_OBJECT_SELECTIONREMOVE on <option> role=ROLE_SYSTEM_LISTITEM name="b" FOCUSABLE,SELECTABLE PosInSet=2 SetSize=3 +EVENT_OBJECT_SELECTION on <option#c> role=ROLE_SYSTEM_LISTITEM name="c" SELECTED,FOCUSED,FOCUSABLE,SELECTABLE PosInSet=3 SetSize=3 EVENT_OBJECT_SELECTIONWITHIN on <select> role=ROLE_SYSTEM_LIST FOCUSABLE,MULTISELECTABLE,EXTSELECTABLE IA2_STATE_VERTICAL SetSize=3 EVENT_OBJECT_STATECHANGE on <option#c> role=ROLE_SYSTEM_LISTITEM name="c" SELECTED,FOCUSED,FOCUSABLE,SELECTABLE PosInSet=3 SetSize=3 EVENT_OBJECT_STATECHANGE on <option> role=ROLE_SYSTEM_LISTITEM name="b" FOCUSABLE,SELECTABLE PosInSet=2 SetSize=3 -IA2_EVENT_ACTIVE_DESCENDANT_CHANGED on <select> role=ROLE_SYSTEM_LIST FOCUSABLE,MULTISELECTABLE,EXTSELECTABLE IA2_STATE_VERTICAL SetSize=3 \ No newline at end of file +IA2_EVENT_ACTIVE_DESCENDANT_CHANGED on <select> role=ROLE_SYSTEM_LIST FOCUSABLE,MULTISELECTABLE,EXTSELECTABLE IA2_STATE_VERTICAL SetSize=3
diff --git a/content/test/data/accessibility/event/menulist-collapse-expected-uia-win.txt b/content/test/data/accessibility/event/menulist-collapse-expected-uia-win.txt index acfe5c5d4..4cd300f 100644 --- a/content/test/data/accessibility/event/menulist-collapse-expected-uia-win.txt +++ b/content/test/data/accessibility/event/menulist-collapse-expected-uia-win.txt
@@ -1,2 +1,3 @@ AriaProperties changed on role=listitem, name=Apple +SelectionItem_ElementRemovedFromSelection on role=listitem, name=Apple ValueValue changed on role=combobox
diff --git a/content/test/data/accessibility/event/menulist-collapse-expected-win.txt b/content/test/data/accessibility/event/menulist-collapse-expected-win.txt index bdd3285..286e043 100644 --- a/content/test/data/accessibility/event/menulist-collapse-expected-win.txt +++ b/content/test/data/accessibility/event/menulist-collapse-expected-win.txt
@@ -1,3 +1,4 @@ +EVENT_OBJECT_SELECTIONREMOVE on <option> role=ROLE_SYSTEM_LISTITEM name="Apple" INVISIBLE,FOCUSABLE,SELECTABLE PosInSet=1 SetSize=3 EVENT_OBJECT_SELECTIONWITHIN on role=ROLE_SYSTEM_LIST INVISIBLE SetSize=3 EVENT_OBJECT_STATECHANGE on <option> role=ROLE_SYSTEM_LISTITEM name="Apple" INVISIBLE,FOCUSABLE,SELECTABLE PosInSet=1 SetSize=3 -EVENT_OBJECT_VALUECHANGE on <select> role=ROLE_SYSTEM_COMBOBOX FOCUSED,COLLAPSED,FOCUSABLE,HASPOPUP SetSize=3 +EVENT_OBJECT_VALUECHANGE on <select> role=ROLE_SYSTEM_COMBOBOX FOCUSED,COLLAPSED,FOCUSABLE,HASPOPUP SetSize=3 \ No newline at end of file
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index 4de85b3..0a49a64 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -601,6 +601,7 @@ # Intel failed issues crbug.com/950552 [ linux intel no-passthrough ] conformance2/textures/misc/tex-3d-size-limit.html [ Failure ] +crbug.com/1056845 [ linux intel no-passthrough ] conformance/extensions/webgl-compressed-texture-astc.html [ Failure ] # Intel driver issues crbug.com/950552 [ linux intel mesa_lt_19.1.2 ] conformance2/textures/misc/tex-base-level-bug.html [ Failure ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt index 7d740cc..9899ecf 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -489,8 +489,6 @@ crbug.com/610951 [ android qualcomm-adreno-(tm)-418 ] conformance/uniforms/uniform-samplers-test.html [ Skip ] crbug.com/914631 [ android qualcomm-adreno-(tm)-418 passthrough ] conformance/limits/gl-max-texture-dimensions.html [ RetryOnFailure ] crbug.com/951628 [ android qualcomm-adreno-(tm)-418 no-passthrough ] conformance/rendering/blending.html [ Failure ] -# This test is skipped because it is crashing. -crbug.com/1052344 [ android qualcomm-adreno-(tm)-418 ] conformance/context/context-release-upon-reload.html [ Skip ] # Nexus 6 (Adreno 420) and 6P (Adreno 430) crbug.com/499555 [ android qualcomm-adreno-(tm)-420 ] conformance/context/context-attributes-alpha-depth-stencil-antialias.html [ Failure ]
diff --git a/extensions/browser/api/automation_internal/automation_internal_api.cc b/extensions/browser/api/automation_internal/automation_internal_api.cc index aafeba1..2b089c6 100644 --- a/extensions/browser/api/automation_internal/automation_internal_api.cc +++ b/extensions/browser/api/automation_internal/automation_internal_api.cc
@@ -499,6 +499,12 @@ case api::automation::ACTION_TYPE_HIDETOOLTIP: action->action = ax::mojom::Action::kHideTooltip; break; + case api::automation::ACTION_TYPE_COLLAPSE: + action->action = ax::mojom::Action::kCollapse; + break; + case api::automation::ACTION_TYPE_EXPAND: + action->action = ax::mojom::Action::kExpand; + break; case api::automation::ACTION_TYPE_ANNOTATEPAGEIMAGES: case api::automation::ACTION_TYPE_SIGNALENDOFTEST: case api::automation::ACTION_TYPE_INTERNALINVALIDATETREE:
diff --git a/extensions/browser/api/declarative_net_request/constants.cc b/extensions/browser/api/declarative_net_request/constants.cc index 0405f8be..7ccfa04 100644 --- a/extensions/browser/api/declarative_net_request/constants.cc +++ b/extensions/browser/api/declarative_net_request/constants.cc
@@ -57,6 +57,12 @@ "Rule with id * is an \"allowAllRequests\" rule and must specify the " "\"resourceTypes\" key. It may only include the \"main_frame\" and " "\"sub_frame\" resource types."; +const char kErrorRegexTooLarge[] = + "Rule with id * specified a more complex regex than allowed as part of the " + "\"*\" key."; +const char kErrorRegexesTooLarge[] = + "Rules with ids [*] specified a more complex regex than allowed as part of " + "the \"*\" key."; const char kErrorListNotPassed[] = "Rules file must contain a list."; const char kRuleCountExceeded[] =
diff --git a/extensions/browser/api/declarative_net_request/constants.h b/extensions/browser/api/declarative_net_request/constants.h index 98ad0853..9c9c6d56 100644 --- a/extensions/browser/api/declarative_net_request/constants.h +++ b/extensions/browser/api/declarative_net_request/constants.h
@@ -16,6 +16,7 @@ // The result of parsing JSON rules provided by an extension. Can correspond to // a single or multiple rules. enum class ParseResult { + NONE, SUCCESS, ERROR_RESOURCE_TYPE_DUPLICATED, ERROR_INVALID_RULE_ID, @@ -47,6 +48,7 @@ ERROR_EMPTY_REGEX_FILTER, ERROR_NON_ASCII_REGEX_FILTER, ERROR_INVALID_REGEX_FILTER, + ERROR_REGEX_TOO_LARGE, ERROR_MULTIPLE_FILTERS_SPECIFIED, ERROR_REGEX_SUBSTITUTION_WITHOUT_FILTER, ERROR_INVALID_REGEX_SUBSTITUTION, @@ -71,10 +73,11 @@ kErrorCreateMatcher_FileReadError = 11, kErrorCreateMatcher_ChecksumMismatch = 12, kErrorCreateMatcher_VersionMismatch = 13, + kErrorRegexTooLarge = 14, // Magic constant used by histograms code. Should be equal to the largest enum // value. - kMaxValue = kErrorCreateMatcher_VersionMismatch, + kMaxValue = kErrorRegexTooLarge, }; // Schemes which can be used as part of url transforms. @@ -99,6 +102,8 @@ extern const char kErrorMultipleFilters[]; extern const char kErrorRegexSubstitutionWithoutFilter[]; extern const char kErrorInvalidAllowAllRequestsResourceType[]; +extern const char kErrorRegexTooLarge[]; +extern const char kErrorRegexesTooLarge[]; extern const char kErrorListNotPassed[];
diff --git a/extensions/browser/api/declarative_net_request/file_sequence_helper.cc b/extensions/browser/api/declarative_net_request/file_sequence_helper.cc index 8056c1c1..82f61f1 100644 --- a/extensions/browser/api/declarative_net_request/file_sequence_helper.cc +++ b/extensions/browser/api/declarative_net_request/file_sequence_helper.cc
@@ -13,6 +13,7 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/stl_util.h" +#include "base/strings/string_number_conversions.h" #include "base/task/post_task.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -21,6 +22,7 @@ #include "extensions/browser/api/declarative_net_request/utils.h" #include "extensions/browser/extension_file_task_runner.h" #include "extensions/common/api/declarative_net_request.h" +#include "extensions/common/error_utils.h" #include "services/data_decoder/public/cpp/data_decoder.h" namespace extensions { @@ -204,17 +206,20 @@ // Returns true on success and populates |ruleset_checksum|. Returns false on // failure and populates |error| and |status|. -bool UpdateAndIndexDynamicRules( - const RulesetSource& source, - std::vector<int> rule_ids_to_remove, - std::vector<api::declarative_net_request::Rule> rules_to_add, - int* ruleset_checksum, - std::string* error, - UpdateDynamicRulesStatus* status) { +bool UpdateAndIndexDynamicRules(const RulesetSource& source, + std::vector<int> rule_ids_to_remove, + std::vector<dnr_api::Rule> rules_to_add, + int* ruleset_checksum, + std::string* error, + UpdateDynamicRulesStatus* status) { DCHECK(ruleset_checksum); DCHECK(error); DCHECK(status); + std::set<int> rule_ids_to_add; + for (const dnr_api::Rule& rule : rules_to_add) + rule_ids_to_add.insert(rule.id); + std::vector<dnr_api::Rule> new_rules; if (!GetNewDynamicRules(source, std::move(rule_ids_to_remove), std::move(rules_to_add), &new_rules, error, status)) { @@ -243,14 +248,30 @@ // Index and persist the indexed ruleset. ParseInfo info = temporary_source->IndexAndPersistRules(std::move(new_rules), ruleset_checksum); - if (info.result() != ParseResult::SUCCESS) { - *error = info.GetErrorDescription(); - *status = info.result() == ParseResult::ERROR_PERSISTING_RULESET + if (info.has_error()) { + *error = info.error(); + *status = info.error_reason() == ParseResult::ERROR_PERSISTING_RULESET ? UpdateDynamicRulesStatus::kErrorWriteTemporaryIndexedRuleset : UpdateDynamicRulesStatus::kErrorInvalidRules; return false; } + // Treat rules which exceed the regex memory limit as errors if these are new + // rules. Just surface an error for the first such rule. + for (int rule_id : info.regex_limit_exceeded_rules()) { + if (!base::Contains(rule_ids_to_add, rule_id)) { + // Any rule added earlier which is ignored now (say due to exceeding the + // regex memory limit), will be silently ignored. + // TODO(crbug.com/1050780): Notify the extension about the same. + continue; + } + + *error = ErrorUtils::FormatErrorMessage( + kErrorRegexTooLarge, base::NumberToString(rule_id), kRegexFilterKey); + *status = UpdateDynamicRulesStatus::kErrorRegexTooLarge; + return false; + } + // Dynamic JSON and indexed rulesets for an extension are stored in the same // directory. DCHECK_EQ(source.indexed_path().DirName(), source.json_path().DirName());
diff --git a/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc b/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc index 368f672..42ec3af22 100644 --- a/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc +++ b/extensions/browser/api/declarative_net_request/file_sequence_helper_unittest.cc
@@ -272,13 +272,15 @@ rule.priority.reset(); api_rules.clear(); api_rules.push_back(GetAPIRule(rule)); - TestAddDynamicRules( - source.Clone(), std::move(api_rules), - ReadJSONRulesResult::Status::kSuccess, - UpdateDynamicRulesStatus::kErrorInvalidRules, - ParseInfo(ParseResult::ERROR_EMPTY_RULE_PRIORITY, kMinValidID + 1) - .GetErrorDescription(), - false /* expected_did_load_successfully */); + + ParseInfo info; + int rule_id = kMinValidID + 1; + info.SetError(ParseResult::ERROR_EMPTY_RULE_PRIORITY, &rule_id); + TestAddDynamicRules(source.Clone(), std::move(api_rules), + ReadJSONRulesResult::Status::kSuccess, + UpdateDynamicRulesStatus::kErrorInvalidRules, + info.error(), + false /* expected_did_load_successfully */); } // Write invalid JSON to the JSON rules file. The update should still succeed.
diff --git a/extensions/browser/api/declarative_net_request/indexed_rule.cc b/extensions/browser/api/declarative_net_request/indexed_rule.cc index 63bd8b81..21c0da6 100644 --- a/extensions/browser/api/declarative_net_request/indexed_rule.cc +++ b/extensions/browser/api/declarative_net_request/indexed_rule.cc
@@ -490,6 +490,9 @@ *parsed_rule.condition.regex_filter, CreateRE2Options(IsCaseSensitive(parsed_rule), require_capturing)); + if (regex.error_code() == re2::RE2::ErrorPatternTooLarge) + return ParseResult::ERROR_REGEX_TOO_LARGE; + if (!regex.ok()) return ParseResult::ERROR_INVALID_REGEX_FILTER;
diff --git a/extensions/browser/api/declarative_net_request/parse_info.cc b/extensions/browser/api/declarative_net_request/parse_info.cc index d23841b..9c6eec7c 100644 --- a/extensions/browser/api/declarative_net_request/parse_info.cc +++ b/extensions/browser/api/declarative_net_request/parse_info.cc
@@ -5,7 +5,6 @@ #include "extensions/browser/api/declarative_net_request/parse_info.h" #include "base/containers/span.h" -#include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "extensions/common/error_utils.h" @@ -26,164 +25,174 @@ } // namespace -ParseInfo::ParseInfo(ParseResult result) : result_(result) {} -ParseInfo::ParseInfo(ParseResult result, int rule_id) - : result_(result), rule_id_(rule_id) {} -ParseInfo::ParseInfo(const ParseInfo&) = default; -ParseInfo& ParseInfo::operator=(const ParseInfo&) = default; +ParseInfo::ParseInfo() = default; +ParseInfo::ParseInfo(ParseInfo&&) = default; +ParseInfo& ParseInfo::operator=(ParseInfo&&) = default; +ParseInfo::~ParseInfo() = default; -std::string ParseInfo::GetErrorDescription() const { - // Every error except ERROR_PERSISTING_RULESET requires |rule_id_|. - DCHECK_EQ(!rule_id_.has_value(), - result_ == ParseResult::ERROR_PERSISTING_RULESET); +void ParseInfo::AddRegexLimitExceededRule(int rule_id) { + DCHECK(!has_error_); + regex_limit_exceeded_rules_.push_back(rule_id); +} - std::string error; - switch (result_) { +void ParseInfo::SetError(ParseResult error_reason, const int* rule_id) { + has_error_ = true; + error_reason_ = error_reason; + + // Every error except ERROR_PERSISTING_RULESET requires |rule_id|. + DCHECK_EQ(!rule_id, error_reason == ParseResult::ERROR_PERSISTING_RULESET); + + switch (error_reason) { + case ParseResult::NONE: + NOTREACHED(); + break; case ParseResult::SUCCESS: NOTREACHED(); break; case ParseResult::ERROR_RESOURCE_TYPE_DUPLICATED: - error = ErrorUtils::FormatErrorMessage(kErrorResourceTypeDuplicated, - base::NumberToString(*rule_id_)); + error_ = ErrorUtils::FormatErrorMessage(kErrorResourceTypeDuplicated, + base::NumberToString(*rule_id)); break; case ParseResult::ERROR_INVALID_RULE_ID: - error = ErrorUtils::FormatErrorMessage( - kErrorInvalidRuleKey, base::NumberToString(*rule_id_), kIDKey, + error_ = ErrorUtils::FormatErrorMessage( + kErrorInvalidRuleKey, base::NumberToString(*rule_id), kIDKey, base::NumberToString(kMinValidID)); break; case ParseResult::ERROR_EMPTY_RULE_PRIORITY: - error = ErrorUtils::FormatErrorMessage(kErrorEmptyRulePriority, - base::NumberToString(*rule_id_)); + error_ = ErrorUtils::FormatErrorMessage(kErrorEmptyRulePriority, + base::NumberToString(*rule_id)); break; case ParseResult::ERROR_INVALID_RULE_PRIORITY: - error = ErrorUtils::FormatErrorMessage( - kErrorInvalidRuleKey, base::NumberToString(*rule_id_), kPriorityKey, + error_ = ErrorUtils::FormatErrorMessage( + kErrorInvalidRuleKey, base::NumberToString(*rule_id), kPriorityKey, base::NumberToString(kMinValidPriority)); break; case ParseResult::ERROR_NO_APPLICABLE_RESOURCE_TYPES: - error = ErrorUtils::FormatErrorMessage(kErrorNoApplicableResourceTypes, + error_ = ErrorUtils::FormatErrorMessage(kErrorNoApplicableResourceTypes, - base::NumberToString(*rule_id_)); + base::NumberToString(*rule_id)); break; case ParseResult::ERROR_EMPTY_DOMAINS_LIST: - error = ErrorUtils::FormatErrorMessage( - kErrorEmptyList, base::NumberToString(*rule_id_), kDomainsKey); + error_ = ErrorUtils::FormatErrorMessage( + kErrorEmptyList, base::NumberToString(*rule_id), kDomainsKey); break; case ParseResult::ERROR_EMPTY_RESOURCE_TYPES_LIST: - error = ErrorUtils::FormatErrorMessage( - kErrorEmptyList, base::NumberToString(*rule_id_), kResourceTypesKey); + error_ = ErrorUtils::FormatErrorMessage( + kErrorEmptyList, base::NumberToString(*rule_id), kResourceTypesKey); break; case ParseResult::ERROR_EMPTY_URL_FILTER: - error = ErrorUtils::FormatErrorMessage( - kErrorEmptyKey, base::NumberToString(*rule_id_), kUrlFilterKey); + error_ = ErrorUtils::FormatErrorMessage( + kErrorEmptyKey, base::NumberToString(*rule_id), kUrlFilterKey); break; case ParseResult::ERROR_INVALID_REDIRECT_URL: - error = ErrorUtils::FormatErrorMessage(kErrorInvalidRedirectUrl, - base::NumberToString(*rule_id_), - kRedirectUrlPath); + error_ = ErrorUtils::FormatErrorMessage(kErrorInvalidRedirectUrl, + base::NumberToString(*rule_id), + kRedirectUrlPath); break; case ParseResult::ERROR_DUPLICATE_IDS: - error = ErrorUtils::FormatErrorMessage(kErrorDuplicateIDs, - base::NumberToString(*rule_id_)); + error_ = ErrorUtils::FormatErrorMessage(kErrorDuplicateIDs, + base::NumberToString(*rule_id)); break; case ParseResult::ERROR_PERSISTING_RULESET: - error = kErrorPersisting; + error_ = kErrorPersisting; break; case ParseResult::ERROR_NON_ASCII_URL_FILTER: - error = ErrorUtils::FormatErrorMessage( - kErrorNonAscii, base::NumberToString(*rule_id_), kUrlFilterKey); + error_ = ErrorUtils::FormatErrorMessage( + kErrorNonAscii, base::NumberToString(*rule_id), kUrlFilterKey); break; case ParseResult::ERROR_NON_ASCII_DOMAIN: - error = ErrorUtils::FormatErrorMessage( - kErrorNonAscii, base::NumberToString(*rule_id_), kDomainsKey); + error_ = ErrorUtils::FormatErrorMessage( + kErrorNonAscii, base::NumberToString(*rule_id), kDomainsKey); break; case ParseResult::ERROR_NON_ASCII_EXCLUDED_DOMAIN: - error = ErrorUtils::FormatErrorMessage( - kErrorNonAscii, base::NumberToString(*rule_id_), kExcludedDomainsKey); + error_ = ErrorUtils::FormatErrorMessage( + kErrorNonAscii, base::NumberToString(*rule_id), kExcludedDomainsKey); break; case ParseResult::ERROR_INVALID_URL_FILTER: - error = ErrorUtils::FormatErrorMessage( - kErrorInvalidKey, base::NumberToString(*rule_id_), kUrlFilterKey); + error_ = ErrorUtils::FormatErrorMessage( + kErrorInvalidKey, base::NumberToString(*rule_id), kUrlFilterKey); break; case ParseResult::ERROR_EMPTY_REMOVE_HEADERS_LIST: - error = ErrorUtils::FormatErrorMessage(kErrorEmptyRemoveHeadersList, - base::NumberToString(*rule_id_), - kRemoveHeadersListKey); + error_ = ErrorUtils::FormatErrorMessage(kErrorEmptyRemoveHeadersList, + base::NumberToString(*rule_id), + kRemoveHeadersListKey); break; case ParseResult::ERROR_INVALID_REDIRECT: - error = ErrorUtils::FormatErrorMessage( - kErrorInvalidKey, base::NumberToString(*rule_id_), kRedirectPath); + error_ = ErrorUtils::FormatErrorMessage( + kErrorInvalidKey, base::NumberToString(*rule_id), kRedirectPath); break; case ParseResult::ERROR_INVALID_EXTENSION_PATH: - error = ErrorUtils::FormatErrorMessage(kErrorInvalidKey, - base::NumberToString(*rule_id_), - kExtensionPathPath); + error_ = ErrorUtils::FormatErrorMessage( + kErrorInvalidKey, base::NumberToString(*rule_id), kExtensionPathPath); break; case ParseResult::ERROR_INVALID_TRANSFORM_SCHEME: - error = ErrorUtils::FormatErrorMessage( - kErrorInvalidTransformScheme, base::NumberToString(*rule_id_), + error_ = ErrorUtils::FormatErrorMessage( + kErrorInvalidTransformScheme, base::NumberToString(*rule_id), kTransformSchemePath, JoinString(base::span<const char* const>(kAllowedTransformSchemes))); break; case ParseResult::ERROR_INVALID_TRANSFORM_PORT: - error = ErrorUtils::FormatErrorMessage(kErrorInvalidKey, - base::NumberToString(*rule_id_), - kTransformPortPath); + error_ = ErrorUtils::FormatErrorMessage( + kErrorInvalidKey, base::NumberToString(*rule_id), kTransformPortPath); break; case ParseResult::ERROR_INVALID_TRANSFORM_QUERY: - error = ErrorUtils::FormatErrorMessage(kErrorInvalidKey, - base::NumberToString(*rule_id_), - kTransformQueryPath); + error_ = ErrorUtils::FormatErrorMessage(kErrorInvalidKey, + base::NumberToString(*rule_id), + kTransformQueryPath); break; case ParseResult::ERROR_INVALID_TRANSFORM_FRAGMENT: - error = ErrorUtils::FormatErrorMessage(kErrorInvalidKey, - base::NumberToString(*rule_id_), - kTransformFragmentPath); + error_ = ErrorUtils::FormatErrorMessage(kErrorInvalidKey, + base::NumberToString(*rule_id), + kTransformFragmentPath); break; case ParseResult::ERROR_QUERY_AND_TRANSFORM_BOTH_SPECIFIED: - error = ErrorUtils::FormatErrorMessage( - kErrorQueryAndTransformBothSpecified, base::NumberToString(*rule_id_), + error_ = ErrorUtils::FormatErrorMessage( + kErrorQueryAndTransformBothSpecified, base::NumberToString(*rule_id), kTransformQueryPath, kTransformQueryTransformPath); break; case ParseResult::ERROR_JAVASCRIPT_REDIRECT: - error = ErrorUtils::FormatErrorMessage(kErrorJavascriptRedirect, - base::NumberToString(*rule_id_), - kRedirectUrlPath); + error_ = ErrorUtils::FormatErrorMessage(kErrorJavascriptRedirect, + base::NumberToString(*rule_id), + kRedirectUrlPath); break; case ParseResult::ERROR_EMPTY_REGEX_FILTER: - error = ErrorUtils::FormatErrorMessage( - kErrorEmptyKey, base::NumberToString(*rule_id_), kRegexFilterKey); + error_ = ErrorUtils::FormatErrorMessage( + kErrorEmptyKey, base::NumberToString(*rule_id), kRegexFilterKey); break; case ParseResult::ERROR_NON_ASCII_REGEX_FILTER: - error = ErrorUtils::FormatErrorMessage( - kErrorNonAscii, base::NumberToString(*rule_id_), kRegexFilterKey); + error_ = ErrorUtils::FormatErrorMessage( + kErrorNonAscii, base::NumberToString(*rule_id), kRegexFilterKey); break; case ParseResult::ERROR_INVALID_REGEX_FILTER: - error = ErrorUtils::FormatErrorMessage( - kErrorInvalidKey, base::NumberToString(*rule_id_), kRegexFilterKey); + error_ = ErrorUtils::FormatErrorMessage( + kErrorInvalidKey, base::NumberToString(*rule_id), kRegexFilterKey); + break; + case ParseResult::ERROR_REGEX_TOO_LARGE: + // These rules are ignored while indexing and so SetError won't be called + // for them. See AddRegexLimitExceededRule(). + NOTREACHED(); break; case ParseResult::ERROR_MULTIPLE_FILTERS_SPECIFIED: - error = ErrorUtils::FormatErrorMessage(kErrorMultipleFilters, - base::NumberToString(*rule_id_), - kUrlFilterKey, kRegexFilterKey); + error_ = ErrorUtils::FormatErrorMessage(kErrorMultipleFilters, + base::NumberToString(*rule_id), + kUrlFilterKey, kRegexFilterKey); break; case ParseResult::ERROR_REGEX_SUBSTITUTION_WITHOUT_FILTER: - error = ErrorUtils::FormatErrorMessage( - kErrorRegexSubstitutionWithoutFilter, base::NumberToString(*rule_id_), + error_ = ErrorUtils::FormatErrorMessage( + kErrorRegexSubstitutionWithoutFilter, base::NumberToString(*rule_id), kRegexSubstitutionKey, kRegexFilterKey); break; case ParseResult::ERROR_INVALID_REGEX_SUBSTITUTION: - error = ErrorUtils::FormatErrorMessage(kErrorInvalidKey, - base::NumberToString(*rule_id_), - kRegexSubstitutionPath); + error_ = ErrorUtils::FormatErrorMessage(kErrorInvalidKey, + base::NumberToString(*rule_id), + kRegexSubstitutionPath); break; case ParseResult::ERROR_INVALID_ALLOW_ALL_REQUESTS_RESOURCE_TYPE: - error = ErrorUtils::FormatErrorMessage( + error_ = ErrorUtils::FormatErrorMessage( kErrorInvalidAllowAllRequestsResourceType, - base::NumberToString(*rule_id_)); + base::NumberToString(*rule_id)); break; } - return error; } } // namespace declarative_net_request
diff --git a/extensions/browser/api/declarative_net_request/parse_info.h b/extensions/browser/api/declarative_net_request/parse_info.h index 292c44c9..33179f3b 100644 --- a/extensions/browser/api/declarative_net_request/parse_info.h +++ b/extensions/browser/api/declarative_net_request/parse_info.h
@@ -7,33 +7,53 @@ #include <stddef.h> #include <string> +#include <vector> +#include "base/logging.h" #include "base/optional.h" #include "extensions/browser/api/declarative_net_request/constants.h" namespace extensions { namespace declarative_net_request { -// Holds the ParseResult together with the id of the rule at which the error -// occurred, if any. +// Holds the result of indexing a JSON ruleset. class ParseInfo { public: - explicit ParseInfo(ParseResult result); - ParseInfo(ParseResult result, int rule_id); - ParseInfo(const ParseInfo&); - ParseInfo& operator=(const ParseInfo&); + // Creates a ParseInfo for a successful parse. + ParseInfo(); - ParseResult result() const { return result_; } + ParseInfo(ParseInfo&&); + ParseInfo& operator=(ParseInfo&&); + ~ParseInfo(); - // Returns the error string corresponding to this ParseInfo. Should not be - // called on a successful parse. - std::string GetErrorDescription() const; + // Rules which exceed the per rule regex memory limit. These are ignored + // during indexing. + void AddRegexLimitExceededRule(int rule_id); + const std::vector<int>& regex_limit_exceeded_rules() const { + return regex_limit_exceeded_rules_; + } + + // |rule_id| is null when invalid. + void SetError(ParseResult error_reason, const int* rule_id); + + bool has_error() const { return has_error_; } + ParseResult error_reason() const { + DCHECK(has_error_); + return error_reason_; + } + const std::string& error() const { + DCHECK(has_error_); + return error_; + } private: - ParseResult result_; - // When set, denotes the id of the rule with which the |result_| is - // associated. - base::Optional<int> rule_id_; + bool has_error_ = false; + + std::vector<int> regex_limit_exceeded_rules_; + + // Only valid iff |has_error_| is true. + std::string error_; + ParseResult error_reason_ = ParseResult::NONE; }; } // namespace declarative_net_request
diff --git a/extensions/browser/api/declarative_net_request/regex_rules_matcher.cc b/extensions/browser/api/declarative_net_request/regex_rules_matcher.cc index 7929fc7..0bec0781 100644 --- a/extensions/browser/api/declarative_net_request/regex_rules_matcher.cc +++ b/extensions/browser/api/declarative_net_request/regex_rules_matcher.cc
@@ -218,6 +218,7 @@ // regular expression while indexing the ruleset. That said, there are cases // possible where this may happen, for example, the library's implementation // may change etc. + // TODO(crbug.com/1050780): Notify the extension about the same. if (error_code != re2::RE2::NoError) continue;
diff --git a/extensions/browser/api/declarative_net_request/ruleset_source.cc b/extensions/browser/api/declarative_net_request/ruleset_source.cc index 8c3d2d7..943aad04 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_source.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_source.cc
@@ -16,6 +16,7 @@ #include "base/json/json_string_value_serializer.h" #include "base/logging.h" #include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/timer/elapsed_timer.h" @@ -69,6 +70,32 @@ manifest_keys::kDeclarativeRuleResourcesKey); } +// Adds install warnings for rules which exceed the per-rule regex memory limit. +void AddRegexLimitExceededWarnings( + std::vector<InstallWarning>* warnings, + const std::vector<int>& regex_limit_exceeded_rule_ids) { + DCHECK(warnings); + + std::vector<std::string> rule_ids; + rule_ids.reserve(regex_limit_exceeded_rule_ids.size()); + for (int rule_id : regex_limit_exceeded_rule_ids) + rule_ids.push_back(base::NumberToString(rule_id)); + + constexpr size_t kMaxRegexLimitExceededWarnings = 10; + if (rule_ids.size() <= kMaxRegexLimitExceededWarnings) { + for (const std::string& rule_id: rule_ids) { + warnings->push_back(CreateInstallWarning(ErrorUtils::FormatErrorMessage( + kErrorRegexTooLarge, rule_id, kRegexFilterKey))); + } + + return; + } + + warnings->push_back(CreateInstallWarning(ErrorUtils::FormatErrorMessage( + kErrorRegexesTooLarge, base::JoinString(rule_ids, ", " /* separator */), + kRegexFilterKey))); +} + ReadJSONRulesResult ParseRulesFromJSON(const base::Value& rules, size_t rule_limit) { ReadJSONRulesResult result; @@ -138,6 +165,43 @@ return result; } +IndexAndPersistJSONRulesetResult IndexAndPersistRuleset( + const RulesetSource& source, + ReadJSONRulesResult read_result, + const base::ElapsedTimer& timer) { + if (read_result.status != Status::kSuccess) { + return IndexAndPersistJSONRulesetResult::CreateErrorResult( + GetErrorWithFilename(source.json_path(), read_result.error)); + } + + int ruleset_checksum; + size_t rules_count = read_result.rules.size(); + const ParseInfo info = source.IndexAndPersistRules( + std::move(read_result.rules), &ruleset_checksum); + + if (info.has_error()) { + std::string error = GetErrorWithFilename(source.json_path(), info.error()); + return IndexAndPersistJSONRulesetResult::CreateErrorResult( + std::move(error)); + } + + // Don't cause a hard error if the regex failed compilation due to + // exceeding the memory limit. This is because it's not a syntactical + // error and the developers don't have an easy way to determine whether + // the regex filter will exceed the memory limit or not. Also, the re2 + // implementation can change causing the memory consumption of a regex to + // change as well. + // TODO(crbug.com/974391): Add UMA to find how often regex rules exceed memory + // limit. + std::vector<InstallWarning> warnings = + std::move(read_result.rule_parse_warnings); + AddRegexLimitExceededWarnings(&warnings, info.regex_limit_exceeded_rules()); + rules_count -= info.regex_limit_exceeded_rules().size(); + + return IndexAndPersistJSONRulesetResult::CreateSuccessResult( + ruleset_checksum, std::move(warnings), rules_count, timer.Elapsed()); +} + void OnSafeJSONParse(const base::FilePath& json_path, const RulesetSource& source, RulesetSource::IndexAndPersistJSONRulesetCallback callback, @@ -151,28 +215,9 @@ base::ElapsedTimer timer; ReadJSONRulesResult read_result = ParseRulesFromJSON(*result.value, source.rule_count_limit()); - if (read_result.status != Status::kSuccess) { - std::move(callback).Run(IndexAndPersistJSONRulesetResult::CreateErrorResult( - GetErrorWithFilename(source.json_path(), read_result.error))); - return; - } - int ruleset_checksum; - size_t rules_count = read_result.rules.size(); - const ParseInfo info = source.IndexAndPersistRules( - std::move(read_result.rules), &ruleset_checksum); - if (info.result() == ParseResult::SUCCESS) { - std::move(callback).Run( - IndexAndPersistJSONRulesetResult::CreateSuccessResult( - ruleset_checksum, std::move(read_result.rule_parse_warnings), - rules_count, timer.Elapsed())); - return; - } - - std::string error = - GetErrorWithFilename(source.json_path(), info.GetErrorDescription()); - std::move(callback).Run( - IndexAndPersistJSONRulesetResult::CreateErrorResult(std::move(error))); + std::move(callback).Run(IndexAndPersistRuleset( + source, std::move(read_result), timer)); } } // namespace @@ -296,25 +341,8 @@ DCHECK(IsAPIAvailable()); base::ElapsedTimer timer; - ReadJSONRulesResult result = ReadJSONRulesUnsafe(); - if (result.status != Status::kSuccess) { - return IndexAndPersistJSONRulesetResult::CreateErrorResult( - GetErrorWithFilename(json_path_, result.error)); - } - - int ruleset_checksum; - size_t rules_count = result.rules.size(); - const ParseInfo info = - IndexAndPersistRules(std::move(result.rules), &ruleset_checksum); - if (info.result() == ParseResult::SUCCESS) { - return IndexAndPersistJSONRulesetResult::CreateSuccessResult( - ruleset_checksum, std::move(result.rule_parse_warnings), rules_count, - timer.Elapsed()); - } - - std::string error = - GetErrorWithFilename(json_path_, info.GetErrorDescription()); - return IndexAndPersistJSONRulesetResult::CreateErrorResult(std::move(error)); + return IndexAndPersistRuleset(*this, ReadJSONRulesUnsafe(), + timer); } void RulesetSource::IndexAndPersistJSONRuleset( @@ -348,20 +376,31 @@ FlatRulesetIndexer indexer; + ParseInfo info; { std::set<int> id_set; // Ensure all ids are distinct. const GURL base_url = Extension::GetBaseURLFromExtensionId(extension_id_); for (auto& rule : rules) { int rule_id = rule.id; bool inserted = id_set.insert(rule_id).second; - if (!inserted) - return ParseInfo(ParseResult::ERROR_DUPLICATE_IDS, rule_id); + if (!inserted) { + info.SetError(ParseResult::ERROR_DUPLICATE_IDS, &rule_id); + return info; + } IndexedRule indexed_rule; ParseResult parse_result = IndexedRule::CreateIndexedRule( std::move(rule), base_url, &indexed_rule); - if (parse_result != ParseResult::SUCCESS) - return ParseInfo(parse_result, rule_id); + + if (parse_result == ParseResult::ERROR_REGEX_TOO_LARGE) { + info.AddRegexLimitExceededRule(rule_id); + continue; + } + + if (parse_result != ParseResult::SUCCESS) { + info.SetError(parse_result, &rule_id); + return info; + } indexer.AddUrlRule(indexed_rule); } @@ -370,10 +409,11 @@ if (!PersistIndexedRuleset(indexed_path_, indexer.GetData(), ruleset_checksum)) { - return ParseInfo(ParseResult::ERROR_PERSISTING_RULESET); + info.SetError(ParseResult::ERROR_PERSISTING_RULESET, nullptr /* rule_id */); + return info; } - return ParseInfo(ParseResult::SUCCESS); + return info; } ReadJSONRulesResult RulesetSource::ReadJSONRulesUnsafe() const {
diff --git a/extensions/browser/api/declarative_net_request/test_utils.cc b/extensions/browser/api/declarative_net_request/test_utils.cc index 729bf10..7df08892e 100644 --- a/extensions/browser/api/declarative_net_request/test_utils.cc +++ b/extensions/browser/api/declarative_net_request/test_utils.cc
@@ -135,6 +135,9 @@ std::ostream& operator<<(std::ostream& output, const ParseResult& result) { switch (result) { + case ParseResult::NONE: + output << "NONE"; + break; case ParseResult::SUCCESS: output << "SUCCESS"; break; @@ -219,6 +222,9 @@ case ParseResult::ERROR_INVALID_REGEX_FILTER: output << "ERROR_INVALID_REGEX_FILTER"; break; + case ParseResult::ERROR_REGEX_TOO_LARGE: + output << "ERROR_REGEX_TOO_LARGE"; + break; case ParseResult::ERROR_MULTIPLE_FILTERS_SPECIFIED: output << "ERROR_MULTIPLE_FILTERS_SPECIFIED"; break;
diff --git a/extensions/browser/api/declarative_net_request/utils.cc b/extensions/browser/api/declarative_net_request/utils.cc index 240d02a..0516a20b 100644 --- a/extensions/browser/api/declarative_net_request/utils.cc +++ b/extensions/browser/api/declarative_net_request/utils.cc
@@ -237,6 +237,12 @@ // Don't capture unless needed, for efficiency. options.set_never_capture(!require_capturing); + options.set_log_errors(false); + + // Limit the maximum memory per regex to 2 Kb. This means given 1024 rules, + // the total usage would be 2 Mb. + options.set_max_mem(2 << 10); + return options; }
diff --git a/extensions/common/api/automation.idl b/extensions/common/api/automation.idl index a507dc87..ef148b9 100644 --- a/extensions/common/api/automation.idl +++ b/extensions/common/api/automation.idl
@@ -307,9 +307,11 @@ annotatePageImages, blur, clearAccessibilityFocus, + collapse, customAction, decrement, doDefault, + expand, focus, getImageData, getTextLocation,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 46b7270..bc03e62 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -14647,48 +14647,104 @@ const CompressedFormatInfo kCompressedFormatInfoArray[] = { { - GL_COMPRESSED_R11_EAC, 4, 8, CheckETCFormatSupport, - angle::LoadEACR11ToR8, GL_R8, GL_RED, GL_UNSIGNED_BYTE, - }, - { - GL_COMPRESSED_SIGNED_R11_EAC, 4, 8, CheckETCFormatSupport, - angle::LoadEACR11SToR8, GL_R8_SNORM, GL_RED, GL_BYTE, - }, - { - GL_COMPRESSED_RG11_EAC, 4, 16, CheckETCFormatSupport, - angle::LoadEACRG11ToRG8, GL_RG8, GL_RG, GL_UNSIGNED_BYTE, - }, - { - GL_COMPRESSED_SIGNED_RG11_EAC, 4, 16, CheckETCFormatSupport, - angle::LoadEACRG11SToRG8, GL_RG8_SNORM, GL_RG, GL_BYTE, - }, - { - GL_COMPRESSED_RGB8_ETC2, 4, 8, CheckETCFormatSupport, - angle::LoadETC2RGB8ToRGBA8, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, - }, - { - GL_COMPRESSED_SRGB8_ETC2, 4, 8, CheckETCFormatSupport, - angle::LoadETC2SRGB8ToRGBA8, GL_SRGB8_ALPHA8, GL_SRGB_ALPHA, + GL_COMPRESSED_R11_EAC, + 4, + 8, + CheckETCFormatSupport, + angle::LoadEACR11ToR8, + GL_R8, + GL_RED, GL_UNSIGNED_BYTE, }, { - GL_COMPRESSED_RGBA8_ETC2_EAC, 4, 16, CheckETCFormatSupport, - angle::LoadETC2RGBA8ToRGBA8, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, + GL_COMPRESSED_SIGNED_R11_EAC, + 4, + 8, + CheckETCFormatSupport, + angle::LoadEACR11SToR8, + GL_R8_SNORM, + GL_RED, + GL_BYTE, }, { - GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 8, - CheckETCFormatSupport, angle::LoadETC2RGB8A1ToRGBA8, GL_RGBA8, GL_RGBA, + GL_COMPRESSED_RG11_EAC, + 4, + 16, + CheckETCFormatSupport, + angle::LoadEACRG11ToRG8, + GL_RG8, + GL_RG, GL_UNSIGNED_BYTE, }, { - GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 4, 16, CheckETCFormatSupport, - angle::LoadETC2SRGBA8ToSRGBA8, GL_SRGB8_ALPHA8, GL_SRGB_ALPHA, + GL_COMPRESSED_SIGNED_RG11_EAC, + 4, + 16, + CheckETCFormatSupport, + angle::LoadEACRG11SToRG8, + GL_RG8_SNORM, + GL_RG, + GL_BYTE, + }, + { + GL_COMPRESSED_RGB8_ETC2, + 4, + 8, + CheckETCFormatSupport, + angle::LoadETC2RGB8ToRGBA8, + GL_RGBA8, + GL_RGBA, GL_UNSIGNED_BYTE, }, { - GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 8, - CheckETCFormatSupport, angle::LoadETC2SRGB8A1ToRGBA8, GL_SRGB8_ALPHA8, - GL_SRGB_ALPHA, GL_UNSIGNED_BYTE, + GL_COMPRESSED_SRGB8_ETC2, + 4, + 8, + CheckETCFormatSupport, + angle::LoadETC2SRGB8ToRGBA8, + GL_SRGB8_ALPHA8, + GL_SRGB_ALPHA, + GL_UNSIGNED_BYTE, + }, + { + GL_COMPRESSED_RGBA8_ETC2_EAC, + 4, + 16, + CheckETCFormatSupport, + angle::LoadETC2RGBA8ToRGBA8, + GL_RGBA8, + GL_RGBA, + GL_UNSIGNED_BYTE, + }, + { + GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, + 4, + 8, + CheckETCFormatSupport, + angle::LoadETC2RGB8A1ToRGBA8, + GL_RGBA8, + GL_RGBA, + GL_UNSIGNED_BYTE, + }, + { + GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, + 4, + 16, + CheckETCFormatSupport, + angle::LoadETC2SRGBA8ToSRGBA8, + GL_SRGB8_ALPHA8, + GL_SRGB_ALPHA, + GL_UNSIGNED_BYTE, + }, + { + GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, + 4, + 8, + CheckETCFormatSupport, + angle::LoadETC2SRGB8A1ToRGBA8, + GL_SRGB8_ALPHA8, + GL_SRGB_ALPHA, + GL_UNSIGNED_BYTE, }, };
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index 68ef394..7ce9ad5 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc
@@ -4125,6 +4125,78 @@ return GL_HALF_FLOAT_OES; case GL_BGRA8_EXT: return GL_UNSIGNED_BYTE; + // Compressed Formats + // S3TC + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + // ASTC + case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: + case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: + case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: + case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: + case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: + case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: + case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: + // BPTC + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT: + case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT: + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: + // RGTC + case GL_COMPRESSED_RED_RGTC1_EXT: + case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: + case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: + // ETC2/EAC + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + // ETC1 + case GL_ETC1_RGB8_OES: + // PVRTC + case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: + case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: + case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: + case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: + // ATC + case GL_ATC_RGB_AMD: + case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: + case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: + return GL_UNSIGNED_BYTE; default: return GL_NONE; }
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc index ec7a01c5..624905b 100644 --- a/gpu/config/gpu_finch_features.cc +++ b/gpu/config/gpu_finch_features.cc
@@ -113,7 +113,7 @@ // Used to enable shared image mailbox and disable legacy texture mailbox on // webview. const base::Feature kEnableSharedImageForWebview{ - "EnableSharedImageForWebview", base::FEATURE_ENABLED_BY_DEFAULT}; + "EnableSharedImageForWebview", base::FEATURE_DISABLED_BY_DEFAULT}; #if defined(OS_ANDROID) bool IsAndroidSurfaceControlEnabled() {
diff --git a/infra/config/buckets/ci.star b/infra/config/buckets/ci.star index c41c359..ee8e16a 100644 --- a/infra/config/buckets/ci.star +++ b/infra/config/buckets/ci.star
@@ -133,6 +133,11 @@ ) ci.android_builder( + name = 'Android WebView L (dbg)', + triggered_by = ['ci/Android arm Builder (dbg)'], +) + +ci.android_builder( name = 'Android WebView M (dbg)', triggered_by = ['Android arm64 Builder (dbg)'], ) @@ -180,6 +185,43 @@ ) ci.android_builder( + name = 'KitKat Phone Tester (dbg)', + triggered_by = ['ci/Android arm Builder (dbg)'], +) + +ci.android_builder( + name = 'KitKat Tablet Tester', + # We have limited tablet capacity and thus limited ability to run + # tests in parallel, hence the high timeout. + execution_timeout = 20 * time.hour, + triggered_by = ['ci/Android arm Builder (dbg)'], +) + +ci.android_builder( + name = 'Lollipop Phone Tester', + # We have limited phone capacity and thus limited ability to run + # tests in parallel, hence the high timeout. + execution_timeout = 6 * time.hour, + triggered_by = ['ci/Android arm Builder (dbg)'], +) + +ci.android_builder( + name = 'Lollipop Tablet Tester', + # We have limited tablet capacity and thus limited ability to run + # tests in parallel, hence the high timeout. + execution_timeout = 20 * time.hour, + triggered_by = ['ci/Android arm Builder (dbg)'], +) + +ci.android_builder( + name = 'Marshmallow Tablet Tester', + # We have limited tablet capacity and thus limited ability to run + # tests in parallel, hence the high timeout. + execution_timeout = 12 * time.hour, + triggered_by = ['ci/Android arm Builder (dbg)'], +) + +ci.android_builder( name = 'Marshmallow 64 bit Tester', triggered_by = ['Android arm64 Builder (dbg)'], )
diff --git a/infra/config/consoles/main-beta.star b/infra/config/consoles/main-beta.star index 8977fe5..c3defb6 100644 --- a/infra/config/consoles/main-beta.star +++ b/infra/config/consoles/main-beta.star
@@ -175,36 +175,6 @@ short_name = '32', ), luci.console_view_entry( - builder = 'ci-beta/KitKat Phone Tester (dbg)', - category = 'chromium.android|tester|phone', - short_name = 'K', - ), - luci.console_view_entry( - builder = 'ci-beta/Lollipop Phone Tester', - category = 'chromium.android|tester|phone', - short_name = 'L', - ), - luci.console_view_entry( - builder = 'ci-beta/KitKat Tablet Tester', - category = 'chromium.android|tester|tablet', - short_name = 'K', - ), - luci.console_view_entry( - builder = 'ci-beta/Lollipop Tablet Tester', - category = 'chromium.android|tester|tablet', - short_name = 'L', - ), - luci.console_view_entry( - builder = 'ci-beta/Marshmallow Tablet Tester', - category = 'chromium.android|tester|tablet', - short_name = 'M', - ), - luci.console_view_entry( - builder = 'ci-beta/Android WebView L (dbg)', - category = 'chromium.android|tester|webview', - short_name = 'L', - ), - luci.console_view_entry( builder = 'ci-beta/android-cronet-arm-rel', category = 'chromium.android|cronet|arm', short_name = 'rel',
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 537328e..9df03b2 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -557,7 +557,6 @@ name: "chromium" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.android\"" @@ -2109,7 +2108,6 @@ name: "chromium" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.android\"" @@ -2131,7 +2129,6 @@ name: "chromium" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.android\"" @@ -3259,7 +3256,6 @@ name: "chromium" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.android\"" @@ -3281,7 +3277,6 @@ name: "chromium" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.android\"" @@ -4007,7 +4002,6 @@ name: "chromium" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"chromium.android\"" @@ -8109,29 +8103,6 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" > builders: < - name: "Android WebView L (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - recipe: < - name: "chromium" - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" - properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" - properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" - properties_j: "mastername:\"chromium.android\"" - > - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - builders: < name: "Android arm Builder (dbg)" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -8314,52 +8285,6 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" > builders: < - name: "KitKat Phone Tester (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - recipe: < - name: "chromium" - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" - properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" - properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" - properties_j: "mastername:\"chromium.android\"" - > - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - builders: < - name: "KitKat Tablet Tester" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - recipe: < - name: "chromium" - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" - properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" - properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" - properties_j: "mastername:\"chromium.android\"" - > - execution_timeout_secs: 72000 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - builders: < name: "Linux ASan LSan Builder" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -8544,52 +8469,6 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" > builders: < - name: "Lollipop Phone Tester" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - recipe: < - name: "chromium" - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" - properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" - properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" - properties_j: "mastername:\"chromium.android\"" - > - execution_timeout_secs: 21600 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - builders: < - name: "Lollipop Tablet Tester" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - recipe: < - name: "chromium" - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" - properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" - properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" - properties_j: "mastername:\"chromium.android\"" - > - execution_timeout_secs: 72000 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - builders: < name: "Mac Builder" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -8783,29 +8662,6 @@ service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" > builders: < - name: "Marshmallow Tablet Tester" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - recipe: < - name: "chromium" - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" - properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" - properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" - properties_j: "mastername:\"chromium.android\"" - > - execution_timeout_secs: 43200 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - builders: < name: "WebKit Mac10.13 (retina)" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -11917,7 +11773,6 @@ name: "binary_size_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.android\"" @@ -12034,7 +11889,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.android\"" @@ -12093,7 +11947,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/code_coverage:{\"use_java_coverage\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" @@ -12815,7 +12668,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.android\"" @@ -12903,7 +12755,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.android\"" @@ -13078,7 +12929,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.android\"" @@ -13137,7 +12987,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -13225,7 +13074,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.chromiumos\"" @@ -13284,7 +13132,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.chromiumos\"" @@ -13372,7 +13219,6 @@ name: "presubmit" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$depot_tools/presubmit:{\"runhooks\":true,\"timeout_s\":480}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -13742,7 +13588,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -13772,7 +13617,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -15584,7 +15428,6 @@ name: "ios/try" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.mac\"" > @@ -16059,7 +15902,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.chromiumos\"" @@ -16118,7 +15960,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/code_coverage:{\"use_clang_coverage\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" @@ -16349,7 +16190,6 @@ name: "chromium_libfuzzer_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -16379,7 +16219,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -16409,7 +16248,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -16439,7 +16277,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/code_coverage:{\"use_clang_coverage\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" @@ -16932,7 +16769,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -17136,7 +16972,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -17261,7 +17096,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -17631,7 +17465,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.mac\"" @@ -17996,7 +17829,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.mac\"" @@ -18428,7 +18260,6 @@ name: "chromium_libfuzzer_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.win\"" @@ -18720,7 +18551,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.win\"" @@ -18865,7 +18695,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.win\"" @@ -19129,7 +18958,6 @@ name: "binary_size_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.android\"" @@ -19160,7 +18988,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$build/test_utils:{\"should_exonerate_flaky_failures\":true}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" @@ -19192,7 +19019,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/code_coverage:{\"use_java_coverage\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" @@ -19224,7 +19050,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.android\"" @@ -19255,7 +19080,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.android\"" @@ -19286,7 +19110,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.android\"" @@ -19317,7 +19140,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -19348,7 +19170,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.chromiumos\"" @@ -19379,7 +19200,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.chromiumos\"" @@ -19410,7 +19230,6 @@ name: "presubmit" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$depot_tools/presubmit:{\"runhooks\":true,\"timeout_s\":480}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -19442,7 +19261,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -19473,7 +19291,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -19502,7 +19319,6 @@ name: "ios/try" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.mac\"" > @@ -19536,7 +19352,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.chromiumos\"" @@ -19567,7 +19382,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/code_coverage:{\"use_clang_coverage\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" @@ -19599,7 +19413,6 @@ name: "chromium_libfuzzer_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -19630,7 +19443,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -19661,7 +19473,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/code_coverage:{\"use_clang_coverage\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$build/test_utils:{\"should_exonerate_flaky_failures\":true}" @@ -19694,7 +19505,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -19725,7 +19535,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -19760,7 +19569,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -19790,7 +19598,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$build/test_utils:{\"should_exonerate_flaky_failures\":true}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" @@ -19821,7 +19628,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.mac\"" @@ -19851,7 +19657,6 @@ name: "chromium_libfuzzer_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.win\"" @@ -19882,7 +19687,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$build/test_utils:{\"should_exonerate_flaky_failures\":true}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" @@ -19914,7 +19718,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.win\"" @@ -19977,7 +19780,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.android\"" @@ -20008,7 +19810,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/code_coverage:{\"use_java_coverage\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" @@ -20040,7 +19841,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.chromiumos\"" @@ -20071,7 +19871,6 @@ name: "presubmit" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$depot_tools/presubmit:{\"runhooks\":true,\"timeout_s\":480}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.linux\"" @@ -20101,7 +19900,6 @@ name: "ios/try" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.mac\"" > @@ -20135,7 +19933,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/code_coverage:{\"use_clang_coverage\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" @@ -20167,7 +19964,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/code_coverage:{\"use_clang_coverage\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" @@ -20198,7 +19994,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.mac\"" @@ -20229,7 +20024,6 @@ name: "chromium_trybot" cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" cipd_version: "refs/heads/master" - properties_j: "$build/chromium_tests:{\"bucketed_triggers\":true}" properties_j: "$build/goma:{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"}" properties_j: "$kitchen:{\"devshell\":true,\"git_auth\":true}" properties_j: "mastername:\"tryserver.chromium.win\""
diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg index c4aaff6..fd330e8c 100644 --- a/infra/config/generated/luci-milo.cfg +++ b/infra/config/generated/luci-milo.cfg
@@ -11345,36 +11345,6 @@ short_name: "32" > builders: < - name: "buildbucket/luci.chromium.ci-beta/KitKat Phone Tester (dbg)" - category: "chromium.android|tester|phone" - short_name: "K" - > - builders: < - name: "buildbucket/luci.chromium.ci-beta/Lollipop Phone Tester" - category: "chromium.android|tester|phone" - short_name: "L" - > - builders: < - name: "buildbucket/luci.chromium.ci-beta/KitKat Tablet Tester" - category: "chromium.android|tester|tablet" - short_name: "K" - > - builders: < - name: "buildbucket/luci.chromium.ci-beta/Lollipop Tablet Tester" - category: "chromium.android|tester|tablet" - short_name: "L" - > - builders: < - name: "buildbucket/luci.chromium.ci-beta/Marshmallow Tablet Tester" - category: "chromium.android|tester|tablet" - short_name: "M" - > - builders: < - name: "buildbucket/luci.chromium.ci-beta/Android WebView L (dbg)" - category: "chromium.android|tester|webview" - short_name: "L" - > - builders: < name: "buildbucket/luci.chromium.ci-beta/android-cronet-arm-rel" category: "chromium.android|cronet|arm" short_name: "rel"
diff --git a/infra/config/generated/luci-scheduler.cfg b/infra/config/generated/luci-scheduler.cfg index 6e9a3b4..c715dfb 100644 --- a/infra/config/generated/luci-scheduler.cfg +++ b/infra/config/generated/luci-scheduler.cfg
@@ -253,6 +253,19 @@ > > job: < + id: "ci-Android WebView L (dbg)" + acls: < + role: TRIGGERER + granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + > + acl_sets: "ci" + buildbucket: < + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "Android WebView L (dbg)" + > +> +job: < id: "Android WebView M (dbg)" acls: < role: TRIGGERER @@ -1210,6 +1223,32 @@ > > job: < + id: "ci-KitKat Phone Tester (dbg)" + acls: < + role: TRIGGERER + granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + > + acl_sets: "ci" + buildbucket: < + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "KitKat Phone Tester (dbg)" + > +> +job: < + id: "ci-KitKat Tablet Tester" + acls: < + role: TRIGGERER + granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + > + acl_sets: "ci" + buildbucket: < + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "KitKat Tablet Tester" + > +> +job: < id: "Leak Detection Linux" acl_sets: "ci" buildbucket: < @@ -1775,6 +1814,32 @@ > > job: < + id: "ci-Lollipop Phone Tester" + acls: < + role: TRIGGERER + granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + > + acl_sets: "ci" + buildbucket: < + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "Lollipop Phone Tester" + > +> +job: < + id: "ci-Lollipop Tablet Tester" + acls: < + role: TRIGGERER + granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + > + acl_sets: "ci" + buildbucket: < + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "Lollipop Tablet Tester" + > +> +job: < id: "MSAN Release (chained origins)" acl_sets: "ci" triggering_policy: < @@ -2169,6 +2234,19 @@ > > job: < + id: "ci-Marshmallow Tablet Tester" + acls: < + role: TRIGGERER + granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + > + acl_sets: "ci" + buildbucket: < + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "Marshmallow Tablet Tester" + > +> +job: < id: "Mojo Android" acl_sets: "ci" buildbucket: < @@ -3800,19 +3878,6 @@ > > job: < - id: "ci-Android WebView L (dbg)" - acls: < - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - acl_sets: "ci" - buildbucket: < - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "Android WebView L (dbg)" - > -> -job: < id: "ci-Android arm Builder (dbg)" acl_sets: "ci" buildbucket: < @@ -3885,32 +3950,6 @@ > > job: < - id: "ci-KitKat Phone Tester (dbg)" - acls: < - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - acl_sets: "ci" - buildbucket: < - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "KitKat Phone Tester (dbg)" - > -> -job: < - id: "ci-KitKat Tablet Tester" - acls: < - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - acl_sets: "ci" - buildbucket: < - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "KitKat Tablet Tester" - > -> -job: < id: "ci-Linux ASan LSan Builder" acl_sets: "ci" buildbucket: < @@ -4007,32 +4046,6 @@ > > job: < - id: "ci-Lollipop Phone Tester" - acls: < - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - acl_sets: "ci" - buildbucket: < - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "Lollipop Phone Tester" - > -> -job: < - id: "ci-Lollipop Tablet Tester" - acls: < - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - acl_sets: "ci" - buildbucket: < - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "Lollipop Tablet Tester" - > -> -job: < id: "ci-Mac Builder" acl_sets: "ci" buildbucket: < @@ -4142,19 +4155,6 @@ > > job: < - id: "ci-Marshmallow Tablet Tester" - acls: < - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - acl_sets: "ci" - buildbucket: < - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "Marshmallow Tablet Tester" - > -> -job: < id: "ci-WebKit Mac10.13 (retina)" acls: < role: TRIGGERER @@ -4313,19 +4313,6 @@ > > job: < - id: "ci-beta-Android WebView L (dbg)" - acls: < - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - acl_sets: "ci-beta" - buildbucket: < - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci-beta" - builder: "Android WebView L (dbg)" - > -> -job: < id: "ci-beta-Android arm Builder (dbg)" acl_sets: "ci-beta" buildbucket: < @@ -4398,32 +4385,6 @@ > > job: < - id: "ci-beta-KitKat Phone Tester (dbg)" - acls: < - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - acl_sets: "ci-beta" - buildbucket: < - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci-beta" - builder: "KitKat Phone Tester (dbg)" - > -> -job: < - id: "ci-beta-KitKat Tablet Tester" - acls: < - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - acl_sets: "ci-beta" - buildbucket: < - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci-beta" - builder: "KitKat Tablet Tester" - > -> -job: < id: "ci-beta-Linux ASan LSan Builder" acl_sets: "ci-beta" buildbucket: < @@ -4520,32 +4481,6 @@ > > job: < - id: "ci-beta-Lollipop Phone Tester" - acls: < - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - acl_sets: "ci-beta" - buildbucket: < - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci-beta" - builder: "Lollipop Phone Tester" - > -> -job: < - id: "ci-beta-Lollipop Tablet Tester" - acls: < - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - acl_sets: "ci-beta" - buildbucket: < - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci-beta" - builder: "Lollipop Tablet Tester" - > -> -job: < id: "ci-beta-Mac Builder" acl_sets: "ci-beta" buildbucket: < @@ -4655,19 +4590,6 @@ > > job: < - id: "ci-beta-Marshmallow Tablet Tester" - acls: < - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - > - acl_sets: "ci-beta" - buildbucket: < - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci-beta" - builder: "Marshmallow Tablet Tester" - > -> -job: < id: "ci-beta-WebKit Mac10.13 (retina)" acls: < role: TRIGGERER @@ -6189,6 +6111,78 @@ acl_sets: "ci" noop: <> > +job: < + id: "ci-beta-Android WebView L (dbg)" + schedule: "triggered" + acl_sets: "ci-beta" + noop: <> +> +job: < + id: "ci-stable-Android WebView L (dbg)" + schedule: "triggered" + acl_sets: "ci-stable" + noop: <> +> +job: < + id: "ci-beta-KitKat Phone Tester (dbg)" + schedule: "triggered" + acl_sets: "ci-beta" + noop: <> +> +job: < + id: "ci-stable-KitKat Phone Tester (dbg)" + schedule: "triggered" + acl_sets: "ci-stable" + noop: <> +> +job: < + id: "ci-beta-KitKat Tablet Tester" + schedule: "triggered" + acl_sets: "ci-beta" + noop: <> +> +job: < + id: "ci-stable-KitKat Tablet Tester" + schedule: "triggered" + acl_sets: "ci-stable" + noop: <> +> +job: < + id: "ci-beta-Lollipop Phone Tester" + schedule: "triggered" + acl_sets: "ci-beta" + noop: <> +> +job: < + id: "ci-stable-Lollipop Phone Tester" + schedule: "triggered" + acl_sets: "ci-stable" + noop: <> +> +job: < + id: "ci-beta-Lollipop Tablet Tester" + schedule: "triggered" + acl_sets: "ci-beta" + noop: <> +> +job: < + id: "ci-stable-Lollipop Tablet Tester" + schedule: "triggered" + acl_sets: "ci-stable" + noop: <> +> +job: < + id: "ci-beta-Marshmallow Tablet Tester" + schedule: "triggered" + acl_sets: "ci-beta" + noop: <> +> +job: < + id: "ci-stable-Marshmallow Tablet Tester" + schedule: "triggered" + acl_sets: "ci-stable" + noop: <> +> trigger: < id: "beta-gitiles-trigger" acl_sets: "ci-beta"
diff --git a/infra/config/generators/scheduler-noop-jobs.star b/infra/config/generators/scheduler-noop-jobs.star index a288243c..d5487dc 100644 --- a/infra/config/generators/scheduler-noop-jobs.star +++ b/infra/config/generators/scheduler-noop-jobs.star
@@ -28,9 +28,37 @@ 'Win7 ANGLE Tryserver (AMD)', )] +# Android testers which are triggered by Android arm Builder (dbg) +# on master, but not on branches. +_ANDROID_NON_BRANCHED_TESTERS = ( + 'Android WebView L (dbg)', + 'KitKat Phone Tester (dbg)', + 'KitKat Tablet Tester', + 'Lollipop Phone Tester', + 'Lollipop Tablet Tester', + 'Marshmallow Tablet Tester', +) +_ANDROID_TEST_NOOP_JOBS = [scheduler_pb.Job( + id = bucket + '-' + builder, + schedule = 'triggered', + acl_sets = [bucket], + noop = scheduler_pb.NoopTask(), +) for builder in _ANDROID_NON_BRANCHED_TESTERS for bucket in ( + 'ci-beta', + 'ci-stable', +)] + + def _add_noop_jobs(ctx): cfg = ctx.output['luci-scheduler.cfg'] - for j in _GPU_NOOP_JOBS: + for j in _GPU_NOOP_JOBS + _ANDROID_TEST_NOOP_JOBS: cfg.job.append(j) +def _munge_trunk_only_jobs(ctx): + cfg = ctx.output['luci-scheduler.cfg'] + for j in cfg.job: + if j.id in _ANDROID_NON_BRANCHED_TESTERS: + j.id = 'ci-' + j.id + lucicfg.generator(_add_noop_jobs) +lucicfg.generator(_munge_trunk_only_jobs)
diff --git a/infra/config/versioned/milestones/m80/buckets/try.star b/infra/config/versioned/milestones/m80/buckets/try.star index cbe1a589..a74315f 100644 --- a/infra/config/versioned/milestones/m80/buckets/try.star +++ b/infra/config/versioned/milestones/m80/buckets/try.star
@@ -53,7 +53,6 @@ ) try_.defaults.bucket.set(vars.bucket.get()) -try_.defaults.bucketed_triggers.set(True) try_.defaults.cq_group.set(vars.cq_group.get())
diff --git a/infra/config/versioned/milestones/m81/buckets/ci.star b/infra/config/versioned/milestones/m81/buckets/ci.star index 4816b614..7da19bf 100644 --- a/infra/config/versioned/milestones/m81/buckets/ci.star +++ b/infra/config/versioned/milestones/m81/buckets/ci.star
@@ -41,11 +41,6 @@ ci.android_builder( - name = 'Android WebView L (dbg)', - triggered_by = [vars.bucket.builder('Android arm Builder (dbg)')], -) - -ci.android_builder( name = 'Android arm Builder (dbg)', execution_timeout = 4 * time.hour, ) @@ -55,43 +50,6 @@ ) ci.android_builder( - name = 'KitKat Phone Tester (dbg)', - triggered_by = [vars.bucket.builder('Android arm Builder (dbg)')], -) - -ci.android_builder( - name = 'KitKat Tablet Tester', - # We have limited tablet capacity and thus limited ability to run - # tests in parallel, hence the high timeout. - execution_timeout = 20 * time.hour, - triggered_by = [vars.bucket.builder('Android arm Builder (dbg)')], -) - -ci.android_builder( - name = 'Lollipop Phone Tester', - # We have limited phone capacity and thus limited ability to run - # tests in parallel, hence the high timeout. - execution_timeout = 6 * time.hour, - triggered_by = [vars.bucket.builder('Android arm Builder (dbg)')], -) - -ci.android_builder( - name = 'Lollipop Tablet Tester', - # We have limited tablet capacity and thus limited ability to run - # tests in parallel, hence the high timeout. - execution_timeout = 20 * time.hour, - triggered_by = [vars.bucket.builder('Android arm Builder (dbg)')], -) - -ci.android_builder( - name = 'Marshmallow Tablet Tester', - # We have limited tablet capacity and thus limited ability to run - # tests in parallel, hence the high timeout. - execution_timeout = 12 * time.hour, - triggered_by = [vars.bucket.builder('Android arm Builder (dbg)')], -) - -ci.android_builder( name = 'android-cronet-arm-rel', notifies = ['cronet'], )
diff --git a/infra/config/versioned/milestones/m81/buckets/try.star b/infra/config/versioned/milestones/m81/buckets/try.star index 038cfa5..5de9c48f 100644 --- a/infra/config/versioned/milestones/m81/buckets/try.star +++ b/infra/config/versioned/milestones/m81/buckets/try.star
@@ -53,7 +53,6 @@ ) try_.defaults.bucket.set(vars.bucket.get()) -try_.defaults.bucketed_triggers.set(True) try_.defaults.cq_group.set(vars.cq_group.get())
diff --git a/infra/config/versioned/trunk/buckets/ci.star b/infra/config/versioned/trunk/buckets/ci.star index f683599..e61c8c16 100644 --- a/infra/config/versioned/trunk/buckets/ci.star +++ b/infra/config/versioned/trunk/buckets/ci.star
@@ -41,11 +41,6 @@ ci.android_builder( - name = 'Android WebView L (dbg)', - triggered_by = [vars.bucket.builder('Android arm Builder (dbg)')], -) - -ci.android_builder( name = 'Android arm Builder (dbg)', execution_timeout = 4 * time.hour, ) @@ -55,43 +50,6 @@ ) ci.android_builder( - name = 'KitKat Phone Tester (dbg)', - triggered_by = [vars.bucket.builder('Android arm Builder (dbg)')], -) - -ci.android_builder( - name = 'KitKat Tablet Tester', - # We have limited tablet capacity and thus limited ability to run - # tests in parallel, hence the high timeout. - execution_timeout = 20 * time.hour, - triggered_by = [vars.bucket.builder('Android arm Builder (dbg)')], -) - -ci.android_builder( - name = 'Lollipop Phone Tester', - # We have limited phone capacity and thus limited ability to run - # tests in parallel, hence the high timeout. - execution_timeout = 6 * time.hour, - triggered_by = [vars.bucket.builder('Android arm Builder (dbg)')], -) - -ci.android_builder( - name = 'Lollipop Tablet Tester', - # We have limited tablet capacity and thus limited ability to run - # tests in parallel, hence the high timeout. - execution_timeout = 20 * time.hour, - triggered_by = [vars.bucket.builder('Android arm Builder (dbg)')], -) - -ci.android_builder( - name = 'Marshmallow Tablet Tester', - # We have limited tablet capacity and thus limited ability to run - # tests in parallel, hence the high timeout. - execution_timeout = 12 * time.hour, - triggered_by = [vars.bucket.builder('Android arm Builder (dbg)')], -) - -ci.android_builder( name = 'android-cronet-arm-rel', notifies = ['cronet'], )
diff --git a/infra/config/versioned/trunk/buckets/try.star b/infra/config/versioned/trunk/buckets/try.star index 6dbfa3d..b1e3c354 100644 --- a/infra/config/versioned/trunk/buckets/try.star +++ b/infra/config/versioned/trunk/buckets/try.star
@@ -54,7 +54,6 @@ ) try_.defaults.bucket.set(vars.bucket.get()) -try_.defaults.bucketed_triggers.set(True) try_.defaults.cq_group.set(vars.cq_group.get())
diff --git a/ios/build/bots/scripts/iossim_util_test.py b/ios/build/bots/scripts/iossim_util_test.py index d2efd15..5b9253d 100644 --- a/ios/build/bots/scripts/iossim_util_test.py +++ b/ios/build/bots/scripts/iossim_util_test.py
@@ -5,7 +5,6 @@ import iossim_util import mock - import test_runner import test_runner_test @@ -15,21 +14,17 @@ def setUp(self): super(GetiOSSimUtil, self).setUp() - self.mock(iossim_util, 'get_simulator_list', - lambda: test_runner_test.SIMULATORS_LIST) def test_get_simulator_runtime_by_version(self): """Ensures correctness of filter.""" self.assertEqual( 'com.apple.CoreSimulator.SimRuntime.iOS-13-2', - iossim_util.get_simulator_runtime_by_version( - test_runner_test.SIMULATORS_LIST, '13.2.2')) + iossim_util.get_simulator_runtime_by_version(SIMULATORS_LIST, '13.2.2')) def test_get_simulator_runtime_by_version_not_found(self): """Ensures that SimulatorNotFoundError raises if no runtime.""" with self.assertRaises(test_runner.SimulatorNotFoundError) as context: - iossim_util.get_simulator_runtime_by_version( - test_runner_test.SIMULATORS_LIST, '13.2') + iossim_util.get_simulator_runtime_by_version(SIMULATORS_LIST, '13.2') expected_message = ('Simulator does not exist: Not found ' '"13.2" SDK in runtimes') self.assertTrue(expected_message in str(context.exception)) @@ -38,14 +33,14 @@ """Ensures correctness of filter.""" self.assertEqual( 'com.apple.CoreSimulator.SimDeviceType.iPhone-11', - iossim_util.get_simulator_runtime_by_platform( - test_runner_test.SIMULATORS_LIST, 'iPhone 11')) + iossim_util.get_simulator_runtime_by_platform(SIMULATORS_LIST, + 'iPhone 11')) def test_get_simulator_runtime_by_platform_not_found(self): """Ensures that SimulatorNotFoundError raises if no platform.""" with self.assertRaises(test_runner.SimulatorNotFoundError) as context: - iossim_util.get_simulator_runtime_by_platform( - test_runner_test.SIMULATORS_LIST, 'iPhone XI') + iossim_util.get_simulator_runtime_by_platform(SIMULATORS_LIST, + 'iPhone XI') expected_message = ('Simulator does not exist: Not found device ' '"iPhone XI" in devicetypes') self.assertTrue(expected_message in str(context.exception))
diff --git a/ios/build/bots/scripts/run.py b/ios/build/bots/scripts/run.py index 1ea3243..555a54cd 100755 --- a/ios/build/bots/scripts/run.py +++ b/ios/build/bots/scripts/run.py
@@ -140,6 +140,7 @@ tr = xcodebuild_runner.SimulatorParallelTestRunner( self.args.app, self.args.host_app, + self.args.iossim, self.args.version, self.args.platform, out_dir=self.args.out_dir, @@ -153,6 +154,7 @@ tr = wpr_runner.WprProxySimulatorTestRunner( self.args.app, self.args.host_app, + self.args.iossim, self.args.replay_path, self.args.platform, self.args.version, @@ -165,9 +167,10 @@ test_cases=self.args.test_cases, xctest=self.args.xctest, ) - elif self.args.platform and self.args.version: + elif self.args.iossim and self.args.platform and self.args.version: tr = test_runner.SimulatorTestRunner( self.args.app, + self.args.iossim, self.args.platform, self.args.version, self.args.out_dir, @@ -192,7 +195,6 @@ else: tr = test_runner.DeviceTestRunner( self.args.app, - self.args.xcode_build_version, self.args.out_dir, env_vars=self.args.env_var, restart=self.args.restart, @@ -279,6 +281,12 @@ metavar='host_app', ) parser.add_argument( + '-i', + '--iossim', + help='Compiled iossim to run the app on.', + metavar='iossim', + ) + parser.add_argument( '-j', '--args-json', default='{}', @@ -412,12 +420,12 @@ Runs argument validation """ if (not (args.xcode_parallelization or args.xcodebuild_device_runner) and - (args.platform or args.version)): - # If --platform or --version are specified then - # they must all be specified. - if not (args.platform and args.version): + (args.iossim or args.platform or args.version)): + # If any of --iossim, --platform, or --version + # are specified then they must all be specified. + if not (args.iossim and args.platform and args.version): parser.error('must specify all or none of ' - '-p/--platform, -v/--version') + '-i/--iossim, -p/--platform, -v/--version') if args.xcode_parallelization and not (args.platform and args.version): parser.error('--xcode-parallelization also requires '
diff --git a/ios/build/bots/scripts/run_test.py b/ios/build/bots/scripts/run_test.py index c092aa04..a4cff30 100755 --- a/ios/build/bots/scripts/run_test.py +++ b/ios/build/bots/scripts/run_test.py
@@ -31,6 +31,69 @@ runner.parse_args(cmd) self.assertTrue(runner.args.app == './foo-Runner.app') + def test_parse_args_iossim_platform_version(self): + """ + iossim, platforma and version should all be set. + missing iossim + """ + test_cases = [ + { + 'error': + 2, + 'cmd': [ + '--platform', + 'iPhone X', + '--version', + '13.2.2', + + # Required + '--xcode-build-version', + '123abc', + '--out-dir', + 'some/dir' + ], + }, + { + 'error': + 2, + 'cmd': [ + '--iossim', + 'path/to/iossim', + '--version', + '13.2.2', + + # Required + '--xcode-build-version', + '123abc', + '--out-dir', + 'some/dir' + ], + }, + { + 'error': + 2, + 'cmd': [ + '--iossim', + 'path/to/iossim', + '--platform', + 'iPhone X', + + # Required + '--xcode-build-version', + '123abc', + '--out-dir', + 'some/dir' + ], + }, + ] + + runner = run.Runner() + for test_case in test_cases: + with self.assertRaises(SystemExit) as ctx: + runner.parse_args(test_case['cmd']) + self.assertTrue(re.match('must specify all or none of *', ctx.message)) + self.assertEqual(ctx.exception.code, test_case['error']) + def test_parse_args_xcode_parallelization_requirements(self): """ xcode parallelization set requires both platform and version
diff --git a/ios/build/bots/scripts/test_runner.py b/ios/build/bots/scripts/test_runner.py index f8bbe2c..34e997c0 100644 --- a/ios/build/bots/scripts/test_runner.py +++ b/ios/build/bots/scripts/test_runner.py
@@ -685,11 +685,12 @@ class SimulatorTestRunner(TestRunner): - """Class for running tests on iOS Simulators.""" + """Class for running tests on iossim.""" def __init__( self, app_path, + iossim_path, platform, version, out_dir, @@ -706,10 +707,11 @@ Args: app_path: Path to the compiled .app or .ipa to run. + iossim_path: Path to the compiled iossim binary to use. platform: Name of the platform to simulate. Supported values can be found - by running "xcrun simctl list". e.g. "iPhone 5s", "iPad Retina". + by running "iossim -l". e.g. "iPhone 5s", "iPad Retina". version: Version of iOS the platform should be running. Supported values - can be found by running "xcrun simctl list". e.g. "9.3", "8.2", "7.1". + can be found by running "iossim -l". e.g. "9.3", "8.2", "7.1". out_dir: Directory to emit test data into. env_vars: List of environment variables to pass to the test itself. retries: Number of times to retry failed test cases. @@ -736,7 +738,13 @@ test_cases=test_cases, xctest=xctest, ) + + iossim_path = os.path.abspath(iossim_path) + if not os.path.exists(iossim_path): + raise SimulatorNotFoundError(iossim_path) + self.homedir = '' + self.iossim_path = iossim_path self.platform = platform self.start_time = None self.version = version
diff --git a/ios/build/bots/scripts/test_runner_test.py b/ios/build/bots/scripts/test_runner_test.py index 16e2353..fef4902d 100755 --- a/ios/build/bots/scripts/test_runner_test.py +++ b/ios/build/bots/scripts/test_runner_test.py
@@ -161,6 +161,7 @@ with self.assertRaises(test_runner.AppNotFoundError): test_runner.SimulatorTestRunner( 'fake-app', + 'fake-iossim', 'platform', 'os', 'xcode-version', @@ -168,10 +169,26 @@ 'out-dir', ) + def test_iossim_not_found(self): + """Ensures SimulatorNotFoundError is raised.""" + self.mock(os.path, 'exists', lambda p: not p.endswith('fake-iossim')) + + with self.assertRaises(test_runner.SimulatorNotFoundError): + test_runner.SimulatorTestRunner( + 'fake-app', + 'fake-iossim', + 'iPhone X', + '11.4', + 'xcode-version', + 'xcode-build', + 'out-dir', + ) + def test_init(self): """Ensures instance is created.""" tr = test_runner.SimulatorTestRunner( 'fake-app', + 'fake-iossim', 'iPhone X', '11.4', 'xcode-version', @@ -200,6 +217,7 @@ tr = test_runner.SimulatorTestRunner( 'fake-app', + 'fake-iossim', 'iPhone X', '11.4', 'xcode-version', @@ -225,6 +243,7 @@ tr = test_runner.SimulatorTestRunner( 'fake-app', + 'fake-iossim', 'iPhone X', '11.4', 'xcode-version', @@ -249,6 +268,7 @@ with self.assertRaises(test_runner.SystemAlertPresentError): tr = test_runner.SimulatorTestRunner( 'fake-app', + 'fake-iossim', 'iPhone X', '11.4', 'xcode-version', @@ -265,6 +285,7 @@ test_cases.""" tr = test_runner.SimulatorTestRunner( 'fake-app', + 'fake-iossim', 'iPhone X', '11.4', 'xcode-version', @@ -338,6 +359,7 @@ tr = test_runner.SimulatorTestRunner( 'fake-app', + 'fake-iossim', 'iPhone X', '11.4', 'xcode-version',
diff --git a/ios/build/bots/scripts/wpr_runner.py b/ios/build/bots/scripts/wpr_runner.py index c9408327..ec70eee 100644 --- a/ios/build/bots/scripts/wpr_runner.py +++ b/ios/build/bots/scripts/wpr_runner.py
@@ -50,6 +50,7 @@ self, app_path, host_app_path, + iossim_path, replay_path, platform, version, @@ -67,11 +68,12 @@ Args: app_path: Path to the compiled .app or .ipa to run. host_app_path: A path to the host app for EG2. + iossim_path: Path to the compiled iossim binary to use. replay_path: Path to the folder where WPR replay and recipe files live. platform: Name of the platform to simulate. Supported values can be found - by running "xcrun simctl list". e.g. "iPhone 5s", "iPad Retina". + by running "iossim -l". e.g. "iPhone 5s", "iPad Retina". version: Version of iOS the platform should be running. Supported values - can be found by running "xcrun simctl list". e.g. "9.3", "8.2", "7.1". + can be found by running "iossim -l". e.g. "9.3", "8.2", "7.1". wpr_tools_path: Path to pre-installed (from CIPD) WPR-related tools out_dir: Directory to emit test data into. env_vars: List of environment variables to pass to the test itself. @@ -89,6 +91,7 @@ """ super(WprProxySimulatorTestRunner, self).__init__( app_path, + iossim_path, platform, version, out_dir,
diff --git a/ios/build/bots/scripts/wpr_runner_test.py b/ios/build/bots/scripts/wpr_runner_test.py index bb2221f..2284b1a 100644 --- a/ios/build/bots/scripts/wpr_runner_test.py +++ b/ios/build/bots/scripts/wpr_runner_test.py
@@ -51,6 +51,7 @@ wpr_runner.WprProxySimulatorTestRunner( 'fake-app', 'bad-host-app-path', + 'fake-iossim', 'replay-path', 'platform', 'os', @@ -69,6 +70,7 @@ wpr_runner.WprProxySimulatorTestRunner( 'fake-app', 'fake-host-app', + 'fake-iossim', 'bad-replay-path', 'platform', 'os', @@ -87,6 +89,7 @@ wpr_runner.WprProxySimulatorTestRunner( 'fake-app', 'fake-host-app', + 'fake-iossim', 'replay-path', 'platform', 'os', @@ -101,6 +104,7 @@ tr = wpr_runner.WprProxySimulatorTestRunner( 'fake-app', 'fake-host-app', + 'fake-iossim', 'replay-path', 'platform', 'os', @@ -156,6 +160,7 @@ tr = wpr_runner.WprProxySimulatorTestRunner( 'fake-app', 'fake-host-app', + 'fake-iossim', 'replay-path', 'platform', 'os',
diff --git a/ios/build/bots/scripts/xcodebuild_runner.py b/ios/build/bots/scripts/xcodebuild_runner.py index 3d1a3d71..f42bd66 100644 --- a/ios/build/bots/scripts/xcodebuild_runner.py +++ b/ios/build/bots/scripts/xcodebuild_runner.py
@@ -260,6 +260,7 @@ def __init__(self, app_path, host_app_path, + iossim_path, version, platform, out_dir, @@ -274,6 +275,8 @@ Args: app_path: (str) A path to egtests_app. host_app_path: (str) A path to the host app for EG2. + iossim_path: Path to the compiled iossim binary to use. + Not used, but is required by the base class. version: (str) iOS version to run simulator on. platform: (str) Name of device. out_dir: (str) A directory to emit test data into. @@ -294,6 +297,7 @@ """ super(SimulatorParallelTestRunner, self).__init__( app_path, + iossim_path, platform, version, out_dir,
diff --git a/ios/chrome/browser/application_context_impl.cc b/ios/chrome/browser/application_context_impl.cc index 6112a45b..a9e6266 100644 --- a/ios/chrome/browser/application_context_impl.cc +++ b/ios/chrome/browser/application_context_impl.cc
@@ -132,6 +132,20 @@ void ApplicationContextImpl::PreMainMessageLoopRun() { DCHECK(thread_checker_.CalledOnValidThread()); + + // BrowserPolicyConnectorIOS is created very early because local_state() + // needs policy to be initialized with the managed preference values. + // However, policy fetches from the network and loading of disk caches + // requires that threads are running; this Init() call lets the connector + // resume its initialization now that the loops are spinning and the + // system request context is available for the fetchers. + BrowserPolicyConnectorIOS* browser_policy_connector = + GetBrowserPolicyConnector(); + if (browser_policy_connector) { + DCHECK(IsEnterprisePolicyEnabled()); + browser_policy_connector->Init(GetLocalState(), + GetSharedURLLoaderFactory()); + } } void ApplicationContextImpl::StartTearDown() {
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc b/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc index 2e3d833f..91de3d5 100644 --- a/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc +++ b/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc
@@ -101,7 +101,8 @@ DCHECK(connector); policy_schema_registry_ = BuildSchemaRegistryForBrowserState( this, connector->GetChromeSchema(), connector->GetSchemaRegistry()); - policy_connector_ = BuildBrowserStatePolicyConnector(connector); + policy_connector_ = BuildBrowserStatePolicyConnector( + policy_schema_registry_.get(), connector); } RegisterBrowserStatePrefs(pref_registry_.get());
diff --git a/ios/chrome/browser/policy/BUILD.gn b/ios/chrome/browser/policy/BUILD.gn index 42424b2..e0abaedc 100644 --- a/ios/chrome/browser/policy/BUILD.gn +++ b/ios/chrome/browser/policy/BUILD.gn
@@ -12,6 +12,8 @@ "browser_state_policy_connector_factory.mm", "configuration_policy_handler_list_factory.h", "configuration_policy_handler_list_factory.mm", + "policy_conversions_client_ios.h", + "policy_conversions_client_ios.mm", "schema_registry_factory.h", "schema_registry_factory.mm", ] @@ -20,6 +22,7 @@ "//base", "//components/policy:generated", "//components/policy/core/common", + "//ios/chrome/browser", "//ios/chrome/browser/browser_state", "//services/network/public/cpp", ]
diff --git a/ios/chrome/browser/policy/browser_policy_connector_ios.mm b/ios/chrome/browser/policy/browser_policy_connector_ios.mm index c96337eb..c2b19d3 100644 --- a/ios/chrome/browser/policy/browser_policy_connector_ios.mm +++ b/ios/chrome/browser/policy/browser_policy_connector_ios.mm
@@ -48,7 +48,7 @@ void BrowserPolicyConnectorIOS::Init( PrefService* local_state, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { - InitInternal(local_state, nullptr); + InitInternal(local_state, /*device_management_service=*/nullptr); } bool BrowserPolicyConnectorIOS::IsEnterpriseManaged() const {
diff --git a/ios/chrome/browser/policy/browser_state_policy_connector.h b/ios/chrome/browser/policy/browser_state_policy_connector.h index 2841c29..94f037a 100644 --- a/ios/chrome/browser/policy/browser_state_policy_connector.h +++ b/ios/chrome/browser/policy/browser_state_policy_connector.h
@@ -13,6 +13,7 @@ namespace policy { class ConfigurationPolicyProvider; class PolicyService; +class SchemaRegistry; } // namespace policy // BrowserStatePolicyConnector creates and manages the per-BrowserState policy @@ -26,7 +27,8 @@ delete; // Initializes this connector. - void Init(BrowserPolicyConnectorIOS* browser_policy_connector); + void Init(policy::SchemaRegistry* schema_registry, + BrowserPolicyConnectorIOS* browser_policy_connector); // Shuts this connector down in preparation for destruction. void Shutdown(); @@ -37,6 +39,9 @@ return policy_service_.get(); } + // Returns the SchemaRegistry associated with this connector. + policy::SchemaRegistry* GetSchemaRegistry() const { return schema_registry_; } + private: // |policy_providers_| contains a list of the policy providers available for // the PolicyService of this connector, in decreasing order of priority. @@ -48,7 +53,11 @@ // result is true, so take care if a provider overrides that. std::vector<policy::ConfigurationPolicyProvider*> policy_providers_; + // The PolicyService that manages policy for this connector's BrowserState. std::unique_ptr<policy::PolicyService> policy_service_; + + // The SchemaRegistry associated with this connector's BrowserState. + policy::SchemaRegistry* schema_registry_; }; #endif // IOS_CHROME_BROWSER_POLICY_BROWSER_STATE_POLICY_CONNECTOR_H_
diff --git a/ios/chrome/browser/policy/browser_state_policy_connector.mm b/ios/chrome/browser/policy/browser_state_policy_connector.mm index d8e3ffda..23be84a 100644 --- a/ios/chrome/browser/policy/browser_state_policy_connector.mm +++ b/ios/chrome/browser/policy/browser_state_policy_connector.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/policy/browser_state_policy_connector.h" #include "components/policy/core/common/policy_service_impl.h" +#include "components/policy/core/common/schema_registry.h" #include "ios/chrome/browser/policy/browser_policy_connector_ios.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -15,7 +16,9 @@ BrowserStatePolicyConnector::~BrowserStatePolicyConnector() = default; void BrowserStatePolicyConnector::Init( + policy::SchemaRegistry* schema_registry, BrowserPolicyConnectorIOS* browser_policy_connector) { + schema_registry_ = schema_registry; policy_providers_ = browser_policy_connector->GetPolicyProviders(); policy_service_ = std::make_unique<policy::PolicyServiceImpl>(policy_providers_);
diff --git a/ios/chrome/browser/policy/browser_state_policy_connector_factory.h b/ios/chrome/browser/policy/browser_state_policy_connector_factory.h index 641ea717..14a408a 100644 --- a/ios/chrome/browser/policy/browser_state_policy_connector_factory.h +++ b/ios/chrome/browser/policy/browser_state_policy_connector_factory.h
@@ -10,7 +10,12 @@ class BrowserPolicyConnectorIOS; class BrowserStatePolicyConnector; +namespace policy { +class SchemaRegistry; +} // namespace policy + std::unique_ptr<BrowserStatePolicyConnector> BuildBrowserStatePolicyConnector( + policy::SchemaRegistry* schema_registry, BrowserPolicyConnectorIOS* browser_policy_connector); #endif // IOS_CHROME_BROWSER_POLICY_BROWSER_STATE_POLICY_CONNECTOR_FACTORY_H_
diff --git a/ios/chrome/browser/policy/browser_state_policy_connector_factory.mm b/ios/chrome/browser/policy/browser_state_policy_connector_factory.mm index 22c258ae..0609e66 100644 --- a/ios/chrome/browser/policy/browser_state_policy_connector_factory.mm +++ b/ios/chrome/browser/policy/browser_state_policy_connector_factory.mm
@@ -13,11 +13,17 @@ #endif std::unique_ptr<BrowserStatePolicyConnector> BuildBrowserStatePolicyConnector( + policy::SchemaRegistry* schema_registry, BrowserPolicyConnectorIOS* browser_policy_connector) { DCHECK(IsEnterprisePolicyEnabled()); auto connector = std::make_unique<BrowserStatePolicyConnector>(); - connector->Init(browser_policy_connector); + // Since extensions are not supported on iOS, the |schema_registry| here has + // the same registered components as the registry owned by + // |browser_policy_connector|, despite being a separate instance. The two + // levels of registry (owned by ApplicationContext vs owned by BrowserState) + // are maintained to keep a parallel structure with Desktop. + connector->Init(schema_registry, browser_policy_connector); return connector; }
diff --git a/ios/chrome/browser/policy/policy_conversions_client_ios.h b/ios/chrome/browser/policy/policy_conversions_client_ios.h new file mode 100644 index 0000000..fddbfd2 --- /dev/null +++ b/ios/chrome/browser/policy/policy_conversions_client_ios.h
@@ -0,0 +1,41 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_POLICY_POLICY_CONVERSIONS_CLIENT_IOS_H_ +#define IOS_CHROME_BROWSER_POLICY_POLICY_CONVERSIONS_CLIENT_IOS_H_ + +#include "components/policy/core/browser/policy_conversions_client.h" + +class ChromeBrowserState; + +namespace web { +class BrowserState; +} + +// PolicyConversionsClientIOS provides an implementation of the +// PolicyConversionsClient interface that is based on ChromeBrowserState and is +// suitable for use in //ios/chrome. +class PolicyConversionsClientIOS : public policy::PolicyConversionsClient { + public: + // Creates a PolicyConversionsClientIOS which retrieves BrowserState-specific + // policy information from the given |browser_state|. + explicit PolicyConversionsClientIOS(web::BrowserState* browser_state); + + PolicyConversionsClientIOS(const PolicyConversionsClientIOS&) = delete; + PolicyConversionsClientIOS& operator=(const PolicyConversionsClientIOS&) = + delete; + ~PolicyConversionsClientIOS() override; + + // PolicyConversionsClient. + policy::PolicyService* GetPolicyService() const override; + policy::SchemaRegistry* GetPolicySchemaRegistry() const override; + const policy::ConfigurationPolicyHandlerList* GetHandlerList() const override; + bool HasUserPolicies() const override; + base::Value GetExtensionPolicies(policy::PolicyDomain policy_domain) override; + + private: + ChromeBrowserState* browser_state_; +}; + +#endif // IOS_CHROME_BROWSER_POLICY_POLICY_CONVERSIONS_CLIENT_IOS_H_
diff --git a/ios/chrome/browser/policy/policy_conversions_client_ios.mm b/ios/chrome/browser/policy/policy_conversions_client_ios.mm new file mode 100644 index 0000000..ba3b7ce --- /dev/null +++ b/ios/chrome/browser/policy/policy_conversions_client_ios.mm
@@ -0,0 +1,51 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/policy/policy_conversions_client_ios.h" + +#include "base/logging.h" +#include "base/values.h" +#include "components/policy/core/browser/policy_conversions_client.h" +#include "ios/chrome/browser/application_context.h" +#include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/policy/browser_policy_connector_ios.h" +#include "ios/chrome/browser/policy/browser_state_policy_connector.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +PolicyConversionsClientIOS::PolicyConversionsClientIOS( + web::BrowserState* browser_state) { + DCHECK(browser_state); + browser_state_ = ChromeBrowserState::FromBrowserState( + GetBrowserStateRedirectedInIncognito(browser_state)); +} + +PolicyConversionsClientIOS::~PolicyConversionsClientIOS() = default; + +policy::PolicyService* PolicyConversionsClientIOS::GetPolicyService() const { + return browser_state_->GetPolicyConnector()->GetPolicyService(); +} + +policy::SchemaRegistry* PolicyConversionsClientIOS::GetPolicySchemaRegistry() + const { + return browser_state_->GetPolicyConnector()->GetSchemaRegistry(); +} + +const policy::ConfigurationPolicyHandlerList* +PolicyConversionsClientIOS::GetHandlerList() const { + return GetApplicationContext()->GetBrowserPolicyConnector()->GetHandlerList(); +} + +bool PolicyConversionsClientIOS::HasUserPolicies() const { + return browser_state_ != nullptr; +} + +base::Value PolicyConversionsClientIOS::GetExtensionPolicies( + policy::PolicyDomain policy_domain) { + // Return an empty list since extensions are not supported on iOS. + return base::Value(base::Value::Type::LIST); +}
diff --git a/ios/chrome/browser/prefs/BUILD.gn b/ios/chrome/browser/prefs/BUILD.gn index eeea0a1d..6aa3c7d7 100644 --- a/ios/chrome/browser/prefs/BUILD.gn +++ b/ios/chrome/browser/prefs/BUILD.gn
@@ -48,6 +48,8 @@ "//components/omnibox/browser", "//components/password_manager/core/browser", "//components/payments/core", + "//components/policy/core/browser", + "//components/policy/core/common", "//components/pref_registry", "//components/prefs", "//components/proxy_config",
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm index b8c35ab..31a47a4 100644 --- a/ios/chrome/browser/prefs/browser_prefs.mm +++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -28,6 +28,8 @@ #include "components/omnibox/browser/zero_suggest_provider.h" #include "components/password_manager/core/browser/password_manager.h" #include "components/payments/core/payment_prefs.h" +#include "components/policy/core/browser/browser_policy_connector.h" +#include "components/policy/core/common/policy_statistics_collector.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" #include "components/proxy_config/pref_proxy_config_tracker_impl.h" @@ -94,6 +96,8 @@ IOSChromeMetricsServiceClient::RegisterPrefs(registry); network_time::NetworkTimeTracker::RegisterPrefs(registry); ios::NotificationPromo::RegisterPrefs(registry); + policy::BrowserPolicyConnector::RegisterPrefs(registry); + policy::PolicyStatisticsCollector::RegisterPrefs(registry); PrefProxyConfigTrackerImpl::RegisterPrefs(registry); rappor::RapporServiceImpl::RegisterPrefs(registry); sessions::SessionIdGenerator::RegisterPrefs(registry);
diff --git a/ios/chrome/browser/ui/ui_feature_flags.cc b/ios/chrome/browser/ui/ui_feature_flags.cc index eeadc93..3d5c776 100644 --- a/ios/chrome/browser/ui/ui_feature_flags.cc +++ b/ios/chrome/browser/ui/ui_feature_flags.cc
@@ -29,7 +29,7 @@ base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kContainedBVC{"ContainedBVC", - base::FEATURE_ENABLED_BY_DEFAULT}; + base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kTestFeature{"TestFeature", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ui/webui/BUILD.gn b/ios/chrome/browser/ui/webui/BUILD.gn index a1e13e0f..8507e22 100644 --- a/ios/chrome/browser/ui/webui/BUILD.gn +++ b/ios/chrome/browser/ui/webui/BUILD.gn
@@ -103,9 +103,11 @@ "//ios/chrome/browser", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/omaha", + "//ios/chrome/browser/policy:feature_flags", "//ios/chrome/browser/signin", "//ios/chrome/browser/ui/webui/gcm", "//ios/chrome/browser/ui/webui/net_export", + "//ios/chrome/browser/ui/webui/policy", "//ios/chrome/browser/ui/webui/sync_internals", "//ios/chrome/browser/ui/webui/translate_internals", "//url",
diff --git a/ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.mm b/ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.mm index 102d978..a2f30484 100644 --- a/ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.mm +++ b/ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.mm
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/location.h" #include "ios/chrome/browser/chrome_url_constants.h" +#include "ios/chrome/browser/policy/policy_features.h" #include "ios/chrome/browser/system_flags.h" #include "ios/chrome/browser/ui/webui/about_ui.h" #include "ios/chrome/browser/ui/webui/autofill_and_password_manager_internals/autofill_internals_ui_ios.h" @@ -20,6 +21,7 @@ #include "ios/chrome/browser/ui/webui/net_export/net_export_ui.h" #include "ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.h" #include "ios/chrome/browser/ui/webui/omaha_ui.h" +#include "ios/chrome/browser/ui/webui/policy/policy_ui.h" #include "ios/chrome/browser/ui/webui/prefs_internals_ui.h" #include "ios/chrome/browser/ui/webui/signin_internals_ui_ios.h" #include "ios/chrome/browser/ui/webui/suggestions_ui.h" @@ -109,6 +111,10 @@ if (url_host == kChromeUIVersionHost) return &NewWebUIIOS<VersionUI>; + if (IsEnterprisePolicyEnabled() && url_host == kChromeUIPolicyHost) { + return &NewWebUIIOS<PolicyUI>; + } + return nullptr; }
diff --git a/ios/chrome/browser/ui/webui/policy/BUILD.gn b/ios/chrome/browser/ui/webui/policy/BUILD.gn new file mode 100644 index 0000000..cde2d419 --- /dev/null +++ b/ios/chrome/browser/ui/webui/policy/BUILD.gn
@@ -0,0 +1,28 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("policy") { + configs += [ "//build/config/compiler:enable_arc" ] + + sources = [ + "policy_ui.h", + "policy_ui.mm", + "policy_ui_handler.h", + "policy_ui_handler.mm", + ] + + deps = [ + "//base", + "//components/policy:generated", + "//components/policy/core/browser", + "//components/policy/core/common", + "//components/resources", + "//components/strings", + "//ios/chrome/browser:chrome_url_constants", + "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/policy", + "//ios/web/public/webui", + "//ui/base", + ] +}
diff --git a/ios/chrome/browser/ui/webui/policy/policy_ui.h b/ios/chrome/browser/ui/webui/policy/policy_ui.h new file mode 100644 index 0000000..f4c1cb4 --- /dev/null +++ b/ios/chrome/browser/ui/webui/policy/policy_ui.h
@@ -0,0 +1,23 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_WEBUI_POLICY_POLICY_UI_H_ +#define IOS_CHROME_BROWSER_UI_WEBUI_POLICY_POLICY_UI_H_ + +#include "ios/web/public/webui/web_ui_ios_controller.h" + +namespace web { +class WebUIIOS; +} + +// The Web UI controller for the chrome://policy page. +class PolicyUI : public web::WebUIIOSController { + public: + explicit PolicyUI(web::WebUIIOS* web_ui); + ~PolicyUI() override; + PolicyUI(const PolicyUI&) = delete; + PolicyUI& operator=(const PolicyUI&) = delete; +}; + +#endif // IOS_CHROME_BROWSER_UI_WEBUI_POLICY_POLICY_UI_H_
diff --git a/ios/chrome/browser/ui/webui/policy/policy_ui.mm b/ios/chrome/browser/ui/webui/policy/policy_ui.mm new file mode 100644 index 0000000..14c9b4a --- /dev/null +++ b/ios/chrome/browser/ui/webui/policy/policy_ui.mm
@@ -0,0 +1,96 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/ui/webui/policy/policy_ui.h" + +#include <memory> + +#include "components/grit/dev_ui_components_resources.h" +#include "components/strings/grit/components_strings.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/chrome_url_constants.h" +#include "ios/chrome/browser/ui/webui/policy/policy_ui_handler.h" +#include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" +#include "ios/web/public/webui/web_ui_ios_message_handler.h" +#include "ui/base/webui/web_ui_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +web::WebUIIOSDataSource* CreatePolicyUIHtmlSource() { + web::WebUIIOSDataSource* source = + web::WebUIIOSDataSource::Create(kChromeUIPolicyHost); + PolicyUIHandler::AddCommonLocalizedStringsToSource(source); + + static constexpr webui::LocalizedString kStrings[] = { + // Localized strings (alphabetical order). + {"exportPoliciesJSON", IDS_EXPORT_POLICIES_JSON}, + {"filterPlaceholder", IDS_POLICY_FILTER_PLACEHOLDER}, + {"hideExpandedStatus", IDS_POLICY_HIDE_EXPANDED_STATUS}, + {"isAffiliatedYes", IDS_POLICY_IS_AFFILIATED_YES}, + {"isAffiliatedNo", IDS_POLICY_IS_AFFILIATED_NO}, + {"labelAssetId", IDS_POLICY_LABEL_ASSET_ID}, + {"labelClientId", IDS_POLICY_LABEL_CLIENT_ID}, + {"labelDirectoryApiId", IDS_POLICY_LABEL_DIRECTORY_API_ID}, + {"labelEnterpriseDisplayDomain", + IDS_POLICY_LABEL_ENTERPRISE_DISPLAY_DOMAIN}, + {"labelEnterpriseEnrollmentDomain", + IDS_POLICY_LABEL_ENTERPRISE_ENROLLMENT_DOMAIN}, + {"labelGaiaId", IDS_POLICY_LABEL_GAIA_ID}, + {"labelIsAffiliated", IDS_POLICY_LABEL_IS_AFFILIATED}, + {"labelLocation", IDS_POLICY_LABEL_LOCATION}, + {"labelMachineEnrollmentDomain", + IDS_POLICY_LABEL_MACHINE_ENROLLMENT_DOMAIN}, + {"labelMachineEnrollmentMachineName", + IDS_POLICY_LABEL_MACHINE_ENROLLMENT_MACHINE_NAME}, + {"labelMachineEnrollmentToken", + IDS_POLICY_LABEL_MACHINE_ENROLLMENT_TOKEN}, + {"labelMachineEntrollmentDeviceId", + IDS_POLICY_LABEL_MACHINE_ENROLLMENT_DEVICE_ID}, + {"labelIsOffHoursActive", IDS_POLICY_LABEL_IS_OFFHOURS_ACTIVE}, + {"labelPoliciesPush", IDS_POLICY_LABEL_PUSH_POLICIES}, + {"labelRefreshInterval", IDS_POLICY_LABEL_REFRESH_INTERVAL}, + {"labelStatus", IDS_POLICY_LABEL_STATUS}, + {"labelTimeSinceLastRefresh", IDS_POLICY_LABEL_TIME_SINCE_LAST_REFRESH}, + {"labelUsername", IDS_POLICY_LABEL_USERNAME}, + {"noPoliciesSet", IDS_POLICY_NO_POLICIES_SET}, + {"offHoursActive", IDS_POLICY_OFFHOURS_ACTIVE}, + {"offHoursNotActive", IDS_POLICY_OFFHOURS_NOT_ACTIVE}, + {"policiesPushOff", IDS_POLICY_PUSH_POLICIES_OFF}, + {"policiesPushOn", IDS_POLICY_PUSH_POLICIES_ON}, + {"policyLearnMore", IDS_POLICY_LEARN_MORE}, + {"reloadPolicies", IDS_POLICY_RELOAD_POLICIES}, + {"showExpandedStatus", IDS_POLICY_SHOW_EXPANDED_STATUS}, + {"showLess", IDS_POLICY_SHOW_LESS}, + {"showMore", IDS_POLICY_SHOW_MORE}, + {"showUnset", IDS_POLICY_SHOW_UNSET}, + {"signinProfile", IDS_POLICY_SIGNIN_PROFILE}, + {"status", IDS_POLICY_STATUS}, + {"statusDevice", IDS_POLICY_STATUS_DEVICE}, + {"statusMachine", IDS_POLICY_STATUS_MACHINE}, + {"statusUser", IDS_POLICY_STATUS_USER}, + }; + source->AddLocalizedStrings(kStrings); + source->UseStringsJs(); + + source->AddResourcePath("policy.css", IDR_POLICY_CSS); + source->AddResourcePath("policy_base.js", IDR_POLICY_BASE_JS); + source->AddResourcePath("policy.js", IDR_POLICY_JS); + source->SetDefaultResource(IDR_POLICY_HTML); + return source; +} + +} // namespace + +PolicyUI::PolicyUI(web::WebUIIOS* web_ui) : web::WebUIIOSController(web_ui) { + web_ui->AddMessageHandler(std::make_unique<PolicyUIHandler>()); + web::WebUIIOSDataSource::Add(ChromeBrowserState::FromWebUIIOS(web_ui), + CreatePolicyUIHtmlSource()); +} + +PolicyUI::~PolicyUI() {}
diff --git a/ios/chrome/browser/ui/webui/policy/policy_ui_handler.h b/ios/chrome/browser/ui/webui/policy/policy_ui_handler.h new file mode 100644 index 0000000..2488b0e --- /dev/null +++ b/ios/chrome/browser/ui/webui/policy/policy_ui_handler.h
@@ -0,0 +1,74 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_WEBUI_POLICY_POLICY_UI_HANDLER_H_ +#define IOS_CHROME_BROWSER_UI_WEBUI_POLICY_POLICY_UI_HANDLER_H_ + +#include "base/memory/weak_ptr.h" +#include "base/values.h" +#include "components/policy/core/common/policy_service.h" +#include "components/policy/core/common/schema_registry.h" +#include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" +#include "ios/web/public/webui/web_ui_ios_message_handler.h" + +namespace policy { +class PolicyMap; +struct PolicyNamespace; +} // namespace policy + +// The JavaScript message handler for the chrome://policy page. +class PolicyUIHandler : public web::WebUIIOSMessageHandler, + public policy::PolicyService::Observer, + public policy::SchemaRegistry::Observer { + public: + PolicyUIHandler(); + ~PolicyUIHandler() override; + PolicyUIHandler(const PolicyUIHandler&) = delete; + PolicyUIHandler& operator=(const PolicyUIHandler&) = delete; + + static void AddCommonLocalizedStringsToSource( + web::WebUIIOSDataSource* source); + + // web::WebUIIOSMessageHandler. + void RegisterMessages() override; + + // policy::PolicyService::Observer. + void OnPolicyUpdated(const policy::PolicyNamespace& ns, + const policy::PolicyMap& previous, + const policy::PolicyMap& current) override; + + // policy::SchemaRegistry::Observer. + void OnSchemaRegistryUpdated(bool has_new_schemas) override; + + private: + // Returns a dictionary containing the policies supported by Chrome. + base::Value GetPolicyNames() const; + + // Returns a dictionary containing the current values of the policies + // supported by Chrome. + base::Value GetPolicyValues() const; + + // Called to handle the "listenPoliciesUpdates" WebUI message. + void HandleListenPoliciesUpdates(const base::ListValue* args); + + // Called to handle the "reloadPolicies" WebUI message. + void HandleReloadPolicies(const base::ListValue* args); + + // Send information about the current policy values to the UI. For each policy + // whose value has been set, dictionaries containing the value and additional + // metadata are sent. + void SendPolicies(); + + // The callback invoked by PolicyService::RefreshPolicies(). + void OnRefreshPoliciesDone(); + + // Returns the PolicyService associated with this WebUI's BrowserState. + policy::PolicyService* GetPolicyService() const; + + // Vends WeakPtrs for this object. + base::WeakPtrFactory<PolicyUIHandler> weak_factory_{this}; +}; + +#endif // IOS_CHROME_BROWSER_UI_WEBUI_POLICY_POLICY_UI_HANDLER_H_
diff --git a/ios/chrome/browser/ui/webui/policy/policy_ui_handler.mm b/ios/chrome/browser/ui/webui/policy/policy_ui_handler.mm new file mode 100644 index 0000000..4fba478 --- /dev/null +++ b/ios/chrome/browser/ui/webui/policy/policy_ui_handler.mm
@@ -0,0 +1,158 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/ui/webui/policy/policy_ui_handler.h" + +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/callback.h" +#include "base/values.h" +#include "components/policy/core/browser/policy_conversions.h" +#include "components/policy/core/common/policy_map.h" +#include "components/policy/core/common/policy_types.h" +#include "components/policy/core/common/schema.h" +#include "components/policy/core/common/schema_map.h" +#include "components/policy/policy_constants.h" +#include "components/strings/grit/components_strings.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/policy/browser_state_policy_connector.h" +#include "ios/chrome/browser/policy/policy_conversions_client_ios.h" +#include "ui/base/webui/web_ui_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +PolicyUIHandler::PolicyUIHandler() {} + +PolicyUIHandler::~PolicyUIHandler() { + GetPolicyService()->RemoveObserver(policy::POLICY_DOMAIN_CHROME, this); + policy::SchemaRegistry* registry = ChromeBrowserState::FromWebUIIOS(web_ui()) + ->GetPolicyConnector() + ->GetSchemaRegistry(); + registry->RemoveObserver(this); +} + +void PolicyUIHandler::AddCommonLocalizedStringsToSource( + web::WebUIIOSDataSource* source) { + static constexpr webui::LocalizedString kStrings[] = { + {"conflict", IDS_POLICY_LABEL_CONFLICT}, + {"headerLevel", IDS_POLICY_HEADER_LEVEL}, + {"headerName", IDS_POLICY_HEADER_NAME}, + {"headerScope", IDS_POLICY_HEADER_SCOPE}, + {"headerSource", IDS_POLICY_HEADER_SOURCE}, + {"headerStatus", IDS_POLICY_HEADER_STATUS}, + {"headerValue", IDS_POLICY_HEADER_VALUE}, + {"warning", IDS_POLICY_HEADER_WARNING}, + {"levelMandatory", IDS_POLICY_LEVEL_MANDATORY}, + {"levelRecommended", IDS_POLICY_LEVEL_RECOMMENDED}, + {"error", IDS_POLICY_LABEL_ERROR}, + {"ignored", IDS_POLICY_LABEL_IGNORED}, + {"notSpecified", IDS_POLICY_NOT_SPECIFIED}, + {"ok", IDS_POLICY_OK}, + {"scopeDevice", IDS_POLICY_SCOPE_DEVICE}, + {"scopeUser", IDS_POLICY_SCOPE_USER}, + {"title", IDS_POLICY_TITLE}, + {"unknown", IDS_POLICY_UNKNOWN}, + {"unset", IDS_POLICY_UNSET}, + {"value", IDS_POLICY_LABEL_VALUE}, + }; + source->AddLocalizedStrings(kStrings); + source->AddLocalizedStrings(policy::kPolicySources); + source->UseStringsJs(); +} + +void PolicyUIHandler::RegisterMessages() { + GetPolicyService()->AddObserver(policy::POLICY_DOMAIN_CHROME, this); + + ChromeBrowserState* browser_state = + ChromeBrowserState::FromWebUIIOS(web_ui()); + browser_state->GetPolicyConnector()->GetSchemaRegistry()->AddObserver(this); + + web_ui()->RegisterMessageCallback( + "listenPoliciesUpdates", + base::BindRepeating(&PolicyUIHandler::HandleListenPoliciesUpdates, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "reloadPolicies", + base::BindRepeating(&PolicyUIHandler::HandleReloadPolicies, + base::Unretained(this))); +} + +void PolicyUIHandler::OnSchemaRegistryUpdated(bool has_new_schemas) { + // Update UI when new schema is added. + if (has_new_schemas) { + SendPolicies(); + } +} + +void PolicyUIHandler::OnPolicyUpdated(const policy::PolicyNamespace& ns, + const policy::PolicyMap& previous, + const policy::PolicyMap& current) { + SendPolicies(); +} + +base::Value PolicyUIHandler::GetPolicyNames() const { + ChromeBrowserState* browser_state = + ChromeBrowserState::FromWebUIIOS(web_ui()); + policy::SchemaRegistry* registry = + browser_state->GetPolicyConnector()->GetSchemaRegistry(); + scoped_refptr<policy::SchemaMap> schema_map = registry->schema_map(); + + // Add Chrome policy names. + base::Value chrome_policy_names(base::Value::Type::LIST); + policy::PolicyNamespace chrome_namespace(policy::POLICY_DOMAIN_CHROME, ""); + const policy::Schema* chrome_schema = schema_map->GetSchema(chrome_namespace); + for (auto it = chrome_schema->GetPropertiesIterator(); !it.IsAtEnd(); + it.Advance()) { + chrome_policy_names.Append(base::Value(it.key())); + } + + base::Value chrome_values(base::Value::Type::DICTIONARY); + chrome_values.SetStringKey("name", "Chrome Policies"); + chrome_values.SetKey("policyNames", std::move(chrome_policy_names)); + + base::Value names(base::Value::Type::DICTIONARY); + names.SetKey("chrome", std::move(chrome_values)); + return names; +} + +base::Value PolicyUIHandler::GetPolicyValues() const { + auto client = std::make_unique<PolicyConversionsClientIOS>( + ChromeBrowserState::FromWebUIIOS(web_ui())); + return policy::ArrayPolicyConversions(std::move(client)) + .EnableConvertValues(true) + .ToValue(); +} + +void PolicyUIHandler::HandleListenPoliciesUpdates(const base::ListValue* args) { + OnRefreshPoliciesDone(); +} + +void PolicyUIHandler::HandleReloadPolicies(const base::ListValue* args) { + GetPolicyService()->RefreshPolicies(base::Bind( + &PolicyUIHandler::OnRefreshPoliciesDone, weak_factory_.GetWeakPtr())); +} + +void PolicyUIHandler::SendPolicies() { + base::Value names = GetPolicyNames(); + base::Value values = GetPolicyValues(); + std::vector<const base::Value*> args; + args.push_back(&names); + args.push_back(&values); + web_ui()->FireWebUIListener("policies-updated", args); +} + +void PolicyUIHandler::OnRefreshPoliciesDone() { + SendPolicies(); +} + +policy::PolicyService* PolicyUIHandler::GetPolicyService() const { + ChromeBrowserState* browser_state = + ChromeBrowserState::FromWebUIIOS(web_ui()); + return browser_state->GetPolicyConnector()->GetPolicyService(); +}
diff --git a/ios/chrome/test/earl_grey2/chrome_ios_eg2_test.gni b/ios/chrome/test/earl_grey2/chrome_ios_eg2_test.gni index f8806ec..f1a1a9c 100644 --- a/ios/chrome/test/earl_grey2/chrome_ios_eg2_test.gni +++ b/ios/chrome/test/earl_grey2/chrome_ios_eg2_test.gni
@@ -137,12 +137,9 @@ ios_eg2_test(target_name) { forward_variables_from(invoker, [ + "xcode_test_application_name", "deps", "data_deps", - "executable_args", - "retries", - "shards", - "xcode_test_application_name", ]) xctest_bundle_principal_class = "ChromeEGTestBundleMain"
diff --git a/ios/showcase/badges/BUILD.gn b/ios/showcase/badges/BUILD.gn index 70abb83..fafe1626 100644 --- a/ios/showcase/badges/BUILD.gn +++ b/ios/showcase/badges/BUILD.gn
@@ -41,6 +41,7 @@ ":badges_constants", "//ios/chrome/browser/infobars:badge_public", "//ios/chrome/browser/ui/badges:public", + "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/showcase/test:eg2_test", "//ios/testing/earl_grey:eg_test_support+eg2", "//ios/third_party/earl_grey2:test_lib", @@ -56,6 +57,7 @@ ":badges_constants", "//ios/chrome/browser/infobars:badge", "//ios/chrome/browser/ui/badges:public", + "//ios/chrome/test/earl_grey:test_support", "//ios/showcase/test", "//ios/testing/earl_grey:earl_grey_support", ]
diff --git a/ios/showcase/badges/sc_badge_egtest.mm b/ios/showcase/badges/sc_badge_egtest.mm index 9fc82360..985cc89 100644 --- a/ios/showcase/badges/sc_badge_egtest.mm +++ b/ios/showcase/badges/sc_badge_egtest.mm
@@ -3,6 +3,7 @@ // found in the LICENSE file. #import "ios/chrome/browser/ui/badges/badge_constants.h" +#import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/showcase/badges/sc_badge_constants.h" #import "ios/showcase/test/showcase_eg_utils.h" #import "ios/showcase/test/showcase_test_case.h"
diff --git a/ios/showcase/bubble/BUILD.gn b/ios/showcase/bubble/BUILD.gn index 5fff2f0d..104924ec 100644 --- a/ios/showcase/bubble/BUILD.gn +++ b/ios/showcase/bubble/BUILD.gn
@@ -24,6 +24,7 @@ testonly = true sources = [ "sc_bubble_egtest.mm" ] deps = [ + "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/showcase/test:eg2_test", "//ios/testing/earl_grey:eg_test_support+eg2", "//ios/third_party/earl_grey2:test_lib", @@ -37,6 +38,7 @@ sources = [ "sc_bubble_egtest.mm" ] deps = [ "//ios/chrome/browser/ui/bubble", + "//ios/chrome/test/earl_grey:test_support", "//ios/showcase/test", "//ios/testing/earl_grey:earl_grey_support", "//ios/third_party/earl_grey:earl_grey+link",
diff --git a/ios/showcase/content_suggestions/BUILD.gn b/ios/showcase/content_suggestions/BUILD.gn index fef57a2..d7c705ae5 100644 --- a/ios/showcase/content_suggestions/BUILD.gn +++ b/ios/showcase/content_suggestions/BUILD.gn
@@ -63,6 +63,7 @@ "//ios/chrome/browser/ui/content_suggestions:content_suggestions_ui", "//ios/chrome/browser/ui/content_suggestions/cells:cells_ui", "//ios/chrome/browser/ui/util", + "//ios/chrome/test/earl_grey:test_support", "//ios/showcase/test", "//ios/testing/earl_grey:earl_grey_support", "//ios/third_party/earl_grey:earl_grey+link",
diff --git a/ios/showcase/core/BUILD.gn b/ios/showcase/core/BUILD.gn index ac51762..716385b6 100644 --- a/ios/showcase/core/BUILD.gn +++ b/ios/showcase/core/BUILD.gn
@@ -82,6 +82,7 @@ testonly = true sources = [ "showcase_egtest.mm" ] deps = [ + "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/showcase/test:eg2_test", "//ios/testing/earl_grey:eg_test_support+eg2", "//ios/third_party/earl_grey2:test_lib",
diff --git a/ios/showcase/infobars/BUILD.gn b/ios/showcase/infobars/BUILD.gn index 0831c88..47b80ec4 100644 --- a/ios/showcase/infobars/BUILD.gn +++ b/ios/showcase/infobars/BUILD.gn
@@ -71,6 +71,7 @@ ":constants", "//ios/chrome/browser/ui/infobars/banners:public", "//ios/chrome/browser/ui/infobars/modals:public", + "//ios/chrome/test/earl_grey:test_support", "//ios/showcase/infobars", "//ios/showcase/test", "//ios/testing/earl_grey:earl_grey_support",
diff --git a/ios/showcase/test/BUILD.gn b/ios/showcase/test/BUILD.gn index 12ea9a6..bfff47ad 100644 --- a/ios/showcase/test/BUILD.gn +++ b/ios/showcase/test/BUILD.gn
@@ -56,6 +56,7 @@ deps = [ "//base", + "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/third_party/earl_grey2:test_lib", "//ui/base", ]
diff --git a/ios/showcase/text_badge_view/BUILD.gn b/ios/showcase/text_badge_view/BUILD.gn index bbc36102..72a2cd3 100644 --- a/ios/showcase/text_badge_view/BUILD.gn +++ b/ios/showcase/text_badge_view/BUILD.gn
@@ -17,6 +17,7 @@ testonly = true sources = [ "sc_text_badge_view_egtest.mm" ] deps = [ + "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/showcase/test:eg2_test", "//ios/testing/earl_grey:eg_test_support+eg2", "//ios/third_party/earl_grey2:test_lib", @@ -30,6 +31,7 @@ sources = [ "sc_text_badge_view_egtest.mm" ] deps = [ "//ios/chrome/browser/ui/reading_list:reading_list_ui", + "//ios/chrome/test/earl_grey:test_support", "//ios/showcase/test", "//ios/testing/earl_grey:earl_grey_support", "//ios/third_party/earl_grey:earl_grey+link",
diff --git a/ios/third_party/earl_grey/ios_eg_test.gni b/ios/third_party/earl_grey/ios_eg_test.gni index 64bade8..82024fb 100644 --- a/ios/third_party/earl_grey/ios_eg_test.gni +++ b/ios/third_party/earl_grey/ios_eg_test.gni
@@ -2,25 +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/ios/ios_test_runner_wrapper.gni") import("//build/config/ios/rules.gni") import("//ios/build/chrome_build.gni") import("//ios/public/provider/chrome/browser/build_config.gni") # EarlGrey tests are just XCTests that also depends on EarlGrey. template("ios_eg_test") { - _target_name = target_name - _test_target = "${target_name}_test" - ios_xctest_test(_test_target) { - forward_variables_from(invoker, - "*", - [ - "executable_args", - "retries", - "shards", - "xctest", - "xcode_parallelization", - ]) + ios_xctest_test(target_name) { + forward_variables_from(invoker, "*") if (!defined(bundle_deps)) { bundle_deps = [] } @@ -39,55 +28,6 @@ "//ios/third_party/earl_grey:earl_grey+link", "//ios/third_party/ochamcrest:ochamcrest+link", ] - - # TODO(crbug.com/1056328) Because we change the target name, the subnodes - # are going to append with the _test in the naming, which won't be backwards - # compatible during migration from iOS recipe to Chromium. - output_name = "${_target_name}" - } - - ios_test_runner_wrapper(target_name) { - forward_variables_from(invoker, - [ - "data", - "data_deps", - "deps", - "executable_args", - "retries", - "shards", - "xctest", - "xcode_parallelization", - ]) - - _root_build_dir = rebase_path("${root_build_dir}", root_build_dir) - - # include the test target above as data_deps - if (!defined(data_deps)) { - data_deps = [] - } - data_deps += [ ":${_test_target}" ] - - if (!defined(executable_args)) { - executable_args = [] - } - - # EG test apps are *.app format. No host, but required xctest and may need - # xcode-parallelization - executable_args += [ - "--app", - "@WrappedPath(${_root_build_dir}/${target_name}.app)", - ] - - # Default xctest to true for EG tests. If set, only set arg if value = true - if (!defined(xctest) || (defined(xctest) && xctest)) { - executable_args += [ "--xctest" ] - } - - # Default xcode_parallelization to true for EG tests. - if (!defined(xcode_parallelization) || - (defined(xcode_parallelization) && xcode_parallelization)) { - executable_args += [ "--xcode-parallelization" ] - } } }
diff --git a/ios/third_party/earl_grey2/ios_eg2_test.gni b/ios/third_party/earl_grey2/ios_eg2_test.gni index 5f2c44f..02dd117 100644 --- a/ios/third_party/earl_grey2/ios_eg2_test.gni +++ b/ios/third_party/earl_grey2/ios_eg2_test.gni
@@ -2,7 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//build/config/ios/ios_test_runner_wrapper.gni") import("//build/config/ios/rules.gni") import("//ios/build/chrome_build.gni") import("//ios/public/provider/chrome/browser/build_config.gni") @@ -64,9 +63,7 @@ defined(invoker.deps), "deps must be defined for $target_name to include at least one earl grey test file.") - _target_name = target_name - _test_target = "${target_name}_test" - ios_xcuitest_test(_test_target) { + ios_xcuitest_test(target_name) { forward_variables_from(invoker, [ "xcode_test_application_name", @@ -80,51 +77,6 @@ deps = [] } deps += [ "//ios/third_party/earl_grey2:test_lib" ] - - # TODO(crbug.com/1056328) Because we change the target name, the subnodes - # are going to append with the _test in the naming, which won't be backwards - # compatible during migration from iOS recipe to Chromium. - output_name = "${_target_name}" - } - - ios_test_runner_wrapper(target_name) { - forward_variables_from(invoker, - [ - "data", - "data_deps", - "deps", - "executable_args", - "retries", - "shards", - "xcode_test_application_name", - ]) - _root_build_dir = rebase_path("${root_build_dir}", root_build_dir) - - if (!defined(data_deps)) { - data_deps = [] - } - - # Include the top ios_eg2_test target, and the host app - data_deps += [ ":${_test_target}" ] - - if (!defined(executable_args)) { - executable_args = [] - } - - # EG2 tests app are bundled as *-Runner.app, while the host app is bundled - # as *.app. - executable_args += [ - "--app", - "@WrappedPath(${_root_build_dir}/${target_name}-Runner.app)", - ] - executable_args += [ - "--host-app", - "@WrappedPath(${_root_build_dir}/${xcode_test_application_name}.app)", - ] - - # All EG2 tests require xcode-parallelization. EG2 doesn't use xctest, so we - # leave undefined - executable_args += [ "--xcode-parallelization" ] } }
diff --git a/ios/third_party/material_components_ios/BUILD.gn b/ios/third_party/material_components_ios/BUILD.gn index 7637bea1..f285a72 100644 --- a/ios/third_party/material_components_ios/BUILD.gn +++ b/ios/third_party/material_components_ios/BUILD.gn
@@ -107,7 +107,6 @@ "src/components/Buttons/src/MDCRaisedButton.h", "src/components/Buttons/src/MaterialButtons.h", "src/components/Buttons/src/ShapeThemer/MDCButtonShapeThemer.h", - "src/components/Buttons/src/ShapeThemer/MDCFloatingButtonShapeThemer.h", "src/components/Buttons/src/ShapeThemer/MaterialButtons+ShapeThemer.h", "src/components/Buttons/src/Theming/MDCButton+MaterialTheming.h", "src/components/Buttons/src/Theming/MDCFloatingButton+MaterialTheming.h", @@ -153,9 +152,6 @@ "src/components/Collections/src/private/MaterialCollectionsStrings_table.h", "src/components/Dialogs/src/ColorThemer/MDCAlertColorThemer.h", "src/components/Dialogs/src/ColorThemer/MaterialDialogs+ColorThemer.h", - "src/components/Dialogs/src/DialogThemer/MDCAlertControllerThemer.h", - "src/components/Dialogs/src/DialogThemer/MDCAlertScheme.h", - "src/components/Dialogs/src/DialogThemer/MaterialDialogs+DialogThemer.h", "src/components/Dialogs/src/MDCAlertController+ButtonForAction.h", "src/components/Dialogs/src/MDCAlertController.h", "src/components/Dialogs/src/MDCAlertControllerView.h", @@ -345,6 +341,8 @@ "src/components/Tabs/src/private/MDCTabBarIndicatorView.h", "src/components/Tabs/src/private/MDCTabBarPrivateIndicatorContext.h", "src/components/TextControls/src/BaseTextAreas/MDCBaseTextArea.h", + "src/components/TextControls/src/BaseTextAreas/MaterialTextControls+BaseTextAreas.h", + "src/components/TextControls/src/BaseTextAreas/private/MDCBaseTextAreaLayout.h", "src/components/TextControls/src/BaseTextAreas/private/MDCBaseTextAreaTextView.h", "src/components/TextControls/src/BaseTextFields/MDCBaseTextField.h", "src/components/TextControls/src/BaseTextFields/MaterialTextControls+BaseTextFields.h", @@ -352,10 +350,18 @@ "src/components/TextControls/src/Enums/MDCTextControlLabelBehavior.h", "src/components/TextControls/src/Enums/MDCTextControlState.h", "src/components/TextControls/src/Enums/MaterialTextControls+Enums.h", + "src/components/TextControls/src/FilledTextAreas/MDCFilledTextArea.h", + "src/components/TextControls/src/FilledTextAreas/MaterialTextControls+FilledTextAreas.h", + "src/components/TextControls/src/FilledTextAreasTheming/MDCFilledTextArea+MaterialTheming.h", + "src/components/TextControls/src/FilledTextAreasTheming/MaterialTextControls+FilledTextAreasTheming.h", "src/components/TextControls/src/FilledTextFields/MDCFilledTextField.h", "src/components/TextControls/src/FilledTextFields/MaterialTextControls+FilledTextFields.h", "src/components/TextControls/src/FilledTextFieldsTheming/MDCFilledTextField+MaterialTheming.h", "src/components/TextControls/src/FilledTextFieldsTheming/MaterialTextControls+FilledTextFieldsTheming.h", + "src/components/TextControls/src/OutlinedTextAreas/MDCOutlinedTextArea.h", + "src/components/TextControls/src/OutlinedTextAreas/MaterialTextControls+OutlinedTextAreas.h", + "src/components/TextControls/src/OutlinedTextAreasTheming/MDCOutlinedTextArea+MaterialTheming.h", + "src/components/TextControls/src/OutlinedTextAreasTheming/MaterialTextControls+OutlinedTextAreasTheming.h", "src/components/TextControls/src/OutlinedTextFields/MDCOutlinedTextField.h", "src/components/TextControls/src/OutlinedTextFields/MaterialTextControls+OutlinedTextFields.h", "src/components/TextControls/src/OutlinedTextFieldsTheming/MDCOutlinedTextField+MaterialTheming.h", @@ -455,8 +461,9 @@ "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlAssistiveLabelView.h", "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlAssistiveLabelViewLayout.h", "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlColorViewModel.h", + "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlGradientManager.h", "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlLabelAnimation.h", - "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlLabelState.h", + "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlLabelPosition.h", "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlVerticalPositioningReference.h", "src/components/private/TextControlsPrivate/src/Shared/MaterialTextControlsPrivate+Shared.h", "src/components/private/TextControlsPrivate/src/Shared/UIBezierPath+MDCTextControlStyle.h", @@ -537,7 +544,6 @@ "src/components/Collections/src/private", "src/components/Dialogs/src", "src/components/Dialogs/src/ColorThemer", - "src/components/Dialogs/src/DialogThemer", "src/components/Dialogs/src/Theming", "src/components/Dialogs/src/TypographyThemer", "src/components/Dialogs/src/private", @@ -595,8 +601,12 @@ "src/components/TextControls/src/BaseTextFields", "src/components/TextControls/src/BaseTextFields/private", "src/components/TextControls/src/Enums", + "src/components/TextControls/src/FilledTextAreas", + "src/components/TextControls/src/FilledTextAreasTheming", "src/components/TextControls/src/FilledTextFields", "src/components/TextControls/src/FilledTextFieldsTheming", + "src/components/TextControls/src/OutlinedTextAreas", + "src/components/TextControls/src/OutlinedTextAreasTheming", "src/components/TextControls/src/OutlinedTextFields", "src/components/TextControls/src/OutlinedTextFieldsTheming", "src/components/TextFields/src", @@ -793,8 +803,6 @@ "src/components/Buttons/src/MaterialButtons.h", "src/components/Buttons/src/ShapeThemer/MDCButtonShapeThemer.h", "src/components/Buttons/src/ShapeThemer/MDCButtonShapeThemer.m", - "src/components/Buttons/src/ShapeThemer/MDCFloatingButtonShapeThemer.h", - "src/components/Buttons/src/ShapeThemer/MDCFloatingButtonShapeThemer.m", "src/components/Buttons/src/ShapeThemer/MaterialButtons+ShapeThemer.h", "src/components/Buttons/src/Theming/MDCButton+MaterialTheming.h", "src/components/Buttons/src/Theming/MDCButton+MaterialTheming.m", @@ -865,11 +873,6 @@ "src/components/Dialogs/src/ColorThemer/MDCAlertColorThemer.h", "src/components/Dialogs/src/ColorThemer/MDCAlertColorThemer.m", "src/components/Dialogs/src/ColorThemer/MaterialDialogs+ColorThemer.h", - "src/components/Dialogs/src/DialogThemer/MDCAlertControllerThemer.h", - "src/components/Dialogs/src/DialogThemer/MDCAlertControllerThemer.m", - "src/components/Dialogs/src/DialogThemer/MDCAlertScheme.h", - "src/components/Dialogs/src/DialogThemer/MDCAlertScheme.m", - "src/components/Dialogs/src/DialogThemer/MaterialDialogs+DialogThemer.h", "src/components/Dialogs/src/MDCAlertController+ButtonForAction.h", "src/components/Dialogs/src/MDCAlertController+ButtonForAction.m", "src/components/Dialogs/src/MDCAlertController.h", @@ -1166,6 +1169,9 @@ "src/components/Tabs/src/private/MDCTabBarPrivateIndicatorContext.m", "src/components/TextControls/src/BaseTextAreas/MDCBaseTextArea.h", "src/components/TextControls/src/BaseTextAreas/MDCBaseTextArea.m", + "src/components/TextControls/src/BaseTextAreas/MaterialTextControls+BaseTextAreas.h", + "src/components/TextControls/src/BaseTextAreas/private/MDCBaseTextAreaLayout.h", + "src/components/TextControls/src/BaseTextAreas/private/MDCBaseTextAreaLayout.m", "src/components/TextControls/src/BaseTextAreas/private/MDCBaseTextAreaTextView.h", "src/components/TextControls/src/BaseTextAreas/private/MDCBaseTextAreaTextView.m", "src/components/TextControls/src/BaseTextFields/MDCBaseTextField.h", @@ -1175,13 +1181,26 @@ "src/components/TextControls/src/BaseTextFields/private/MDCBaseTextFieldLayout.m", "src/components/TextControls/src/Enums/MDCTextControlLabelBehavior.h", "src/components/TextControls/src/Enums/MDCTextControlState.h", + "src/components/TextControls/src/Enums/MDCTextControlState.m", "src/components/TextControls/src/Enums/MaterialTextControls+Enums.h", + "src/components/TextControls/src/FilledTextAreas/MDCFilledTextArea.h", + "src/components/TextControls/src/FilledTextAreas/MDCFilledTextArea.m", + "src/components/TextControls/src/FilledTextAreas/MaterialTextControls+FilledTextAreas.h", + "src/components/TextControls/src/FilledTextAreasTheming/MDCFilledTextArea+MaterialTheming.h", + "src/components/TextControls/src/FilledTextAreasTheming/MDCFilledTextArea+MaterialTheming.m", + "src/components/TextControls/src/FilledTextAreasTheming/MaterialTextControls+FilledTextAreasTheming.h", "src/components/TextControls/src/FilledTextFields/MDCFilledTextField.h", "src/components/TextControls/src/FilledTextFields/MDCFilledTextField.m", "src/components/TextControls/src/FilledTextFields/MaterialTextControls+FilledTextFields.h", "src/components/TextControls/src/FilledTextFieldsTheming/MDCFilledTextField+MaterialTheming.h", "src/components/TextControls/src/FilledTextFieldsTheming/MDCFilledTextField+MaterialTheming.m", "src/components/TextControls/src/FilledTextFieldsTheming/MaterialTextControls+FilledTextFieldsTheming.h", + "src/components/TextControls/src/OutlinedTextAreas/MDCOutlinedTextArea.h", + "src/components/TextControls/src/OutlinedTextAreas/MDCOutlinedTextArea.m", + "src/components/TextControls/src/OutlinedTextAreas/MaterialTextControls+OutlinedTextAreas.h", + "src/components/TextControls/src/OutlinedTextAreasTheming/MDCOutlinedTextArea+MaterialTheming.h", + "src/components/TextControls/src/OutlinedTextAreasTheming/MDCOutlinedTextArea+MaterialTheming.m", + "src/components/TextControls/src/OutlinedTextAreasTheming/MaterialTextControls+OutlinedTextAreasTheming.h", "src/components/TextControls/src/OutlinedTextFields/MDCOutlinedTextField.h", "src/components/TextControls/src/OutlinedTextFields/MDCOutlinedTextField.m", "src/components/TextControls/src/OutlinedTextFields/MaterialTextControls+OutlinedTextFields.h", @@ -1346,9 +1365,12 @@ "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlAssistiveLabelViewLayout.m", "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlColorViewModel.h", "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlColorViewModel.m", + "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlGradientManager.h", + "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlGradientManager.m", "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlLabelAnimation.h", "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlLabelAnimation.m", - "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlLabelState.h", + "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlLabelPosition.h", + "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlLabelPosition.m", "src/components/private/TextControlsPrivate/src/Shared/MDCTextControlVerticalPositioningReference.h", "src/components/private/TextControlsPrivate/src/Shared/MaterialTextControlsPrivate+Shared.h", "src/components/private/TextControlsPrivate/src/Shared/UIBezierPath+MDCTextControlStyle.h",
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index 18118cf..510845c0 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -58,6 +58,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/data_url.h" #include "third_party/blink/public/platform/web_encrypted_media_types.h" +#include "third_party/blink/public/platform/web_fullscreen_video_status.h" #include "third_party/blink/public/platform/web_media_player_client.h" #include "third_party/blink/public/platform/web_media_player_encrypted_media_client.h" #include "third_party/blink/public/platform/web_media_player_source.h" @@ -569,15 +570,9 @@ // info before returning. if (!decoder_requires_restart_for_overlay_) MaybeSendOverlayInfoToDecoder(); - - if (power_status_helper_) - power_status_helper_->SetIsFullscreen(true); } void WebMediaPlayerImpl::ExitedFullscreen() { - if (power_status_helper_) - power_status_helper_->SetIsFullscreen(false); - overlay_info_.is_fullscreen = false; // If we're in overlay mode, then exit it unless we're supposed to allow @@ -598,6 +593,14 @@ void WebMediaPlayerImpl::SetIsEffectivelyFullscreen( blink::WebFullscreenVideoStatus fullscreen_video_status) { delegate_->SetIsEffectivelyFullscreen(delegate_id_, fullscreen_video_status); + + if (power_status_helper_) { + // We don't care about pip, so anything that's "not fullscreen" is good + // enough for us. + power_status_helper_->SetIsFullscreen( + fullscreen_video_status != + blink::WebFullscreenVideoStatus::kNotEffectivelyFullscreen); + } } void WebMediaPlayerImpl::OnHasNativeControlsChanged(bool has_native_controls) {
diff --git a/media/gpu/android/codec_image.cc b/media/gpu/android/codec_image.cc index f3d8288..d57cea86 100644 --- a/media/gpu/android/codec_image.cc +++ b/media/gpu/android/codec_image.cc
@@ -248,13 +248,20 @@ } bool CodecImage::RenderToTextureOwnerBackBuffer(BlockingMode blocking_mode) { - DCHECK(codec_buffer_wait_coordinator_); DCHECK_NE(phase_, Phase::kInFrontBuffer); if (phase_ == Phase::kInBackBuffer) return true; if (phase_ == Phase::kInvalidated) return false; + // Normally, we should have a wait coordinator if we're called. However, if + // the renderer is torn down (either VideoFrameSubmitter or the whole process) + // before we get returns back from viz, then we can be notified that we're + // no longer in use (erroneously) when the VideoFrame is destroyed. So, if + // we don't have a wait coordinator, then just fail. + if (!codec_buffer_wait_coordinator_) + return false; + // Wait for a previous frame available so we don't confuse it with the one // we're about to release. if (codec_buffer_wait_coordinator_->IsExpectingFrameAvailable()) { @@ -272,7 +279,13 @@ } bool CodecImage::RenderToTextureOwnerFrontBuffer(BindingsMode bindings_mode) { - DCHECK(codec_buffer_wait_coordinator_); + // Normally, we should have a wait coordinator if we're called. However, if + // the renderer is torn down (either VideoFrameSubmitter or the whole process) + // before we get returns back from viz, then we can be notified that we're + // no longer in use (erroneously) when the VideoFrame is destroyed. So, if + // we don't have a wait coordinator, then just fail. + if (!codec_buffer_wait_coordinator_) + return false; if (phase_ == Phase::kInFrontBuffer) { EnsureBoundIfNeeded(bindings_mode);
diff --git a/media/gpu/android/codec_image.h b/media/gpu/android/codec_image.h index bc9a0d2..fe4ed50c 100644 --- a/media/gpu/android/codec_image.h +++ b/media/gpu/android/codec_image.h
@@ -171,6 +171,8 @@ ~CodecImage() override; private: + FRIEND_TEST_ALL_PREFIXES(CodecImageTest, RenderAfterUnusedDoesntCrash); + // The lifecycle phases of an image. // The only possible transitions are from left to right. Both // kInFrontBuffer and kInvalidated are terminal.
diff --git a/media/gpu/android/codec_image_unittest.cc b/media/gpu/android/codec_image_unittest.cc index a537d9a..840cf24f 100644 --- a/media/gpu/android/codec_image_unittest.cc +++ b/media/gpu/android/codec_image_unittest.cc
@@ -422,4 +422,12 @@ codec_buffer_wait_coordinator_->texture_owner()->get_crop_rect_count, 1); } +TEST_F(CodecImageTest, RenderAfterUnusedDoesntCrash) { + auto i = NewImage(kTextureOwner); + i->NotifyUnused(); + EXPECT_FALSE(i->RenderToTextureOwnerBackBuffer()); + EXPECT_FALSE(i->RenderToTextureOwnerFrontBuffer( + CodecImage::BindingsMode::kEnsureTexImageBound)); +} + } // namespace media
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc index 63ec890..e34dd7fad 100644 --- a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
@@ -39,6 +39,7 @@ #include "media/gpu/macros.h" #include "media/gpu/vaapi/h264_encoder.h" #include "media/gpu/vaapi/vaapi_common.h" +#include "media/gpu/vaapi/vaapi_utils.h" #include "media/gpu/vaapi/vp8_encoder.h" #include "media/gpu/vaapi/vp9_encoder.h" #include "media/gpu/vp8_reference_frame_vector.h" @@ -390,11 +391,6 @@ output_buffer_byte_size_ = encoder_->GetBitstreamBufferSize(); - va_surface_release_cb_ = BindToCurrentLoop(base::BindRepeating( - &VaapiVideoEncodeAccelerator::RecycleVASurfaceID, encoder_weak_this_)); - vpp_va_surface_release_cb_ = BindToCurrentLoop(base::BindRepeating( - &VaapiVideoEncodeAccelerator::RecycleVPPVASurfaceID, encoder_weak_this_)); - visible_rect_ = gfx::Rect(config.input_visible_size); expected_input_coded_size_ = VideoFrame::DetermineAlignedSize( config.input_format, config.input_visible_size); @@ -429,14 +425,20 @@ // The surface size for the reconstructed surface (and input surface in non // native input mode) is the coded size. + std::vector<VASurfaceID> surface_ids; if (!vaapi_wrapper_->CreateContextAndSurfaces( kVaSurfaceFormat, encoder_->GetCodedSize(), VaapiWrapper::SurfaceUsageHint::kVideoEncoder, (num_frames_in_flight_ + 1) * va_surfaces_per_video_frame_, - &available_va_surface_ids_)) { + &surface_ids)) { NOTIFY_ERROR(kPlatformFailureError, "Failed creating VASurfaces"); return; } + for (const VASurfaceID surface_id : surface_ids) { + available_va_surfaces_.emplace_back(std::make_unique<ScopedVASurfaceID>( + surface_id, + base::BindOnce(&VaapiWrapper::DestroySurface, vaapi_wrapper_))); + } child_task_runner_->PostTask( FROM_HERE, @@ -461,20 +463,24 @@ } void VaapiVideoEncodeAccelerator::RecycleVASurfaceID( - VASurfaceID va_surface_id) { - DVLOGF(4) << "va_surface_id: " << va_surface_id; + std::unique_ptr<ScopedVASurfaceID> scoped_va_surface_id, + VASurfaceID /* va_surface_id */) { + DCHECK(scoped_va_surface_id); + DVLOGF(4) << "va_surface_id: " << scoped_va_surface_id->id(); DCHECK_CALLED_ON_VALID_SEQUENCE(encoder_sequence_checker_); - available_va_surface_ids_.push_back(va_surface_id); + available_va_surfaces_.push_back(std::move(scoped_va_surface_id)); EncodePendingInputs(); } void VaapiVideoEncodeAccelerator::RecycleVPPVASurfaceID( - VASurfaceID va_surface_id) { - DVLOGF(4) << "va_surface_id: " << va_surface_id; + std::unique_ptr<ScopedVASurfaceID> scoped_va_surface_id, + VASurfaceID /* va_surface_id */) { + DCHECK(scoped_va_surface_id); + DVLOGF(4) << "va_surface_id: " << scoped_va_surface_id->id(); DCHECK_CALLED_ON_VALID_SEQUENCE(encoder_sequence_checker_); - available_vpp_va_surface_ids_.push_back(va_surface_id); + available_vpp_va_surfaces_.push_back(std::move(scoped_va_surface_id)); EncodePendingInputs(); } @@ -615,8 +621,8 @@ return nullptr; } - if (available_va_surface_ids_.size() < va_surfaces_per_video_frame_ || - (vpp_vaapi_wrapper_ && available_vpp_va_surface_ids_.empty())) { + if (available_va_surfaces_.size() < va_surfaces_per_video_frame_ || + (vpp_vaapi_wrapper_ && available_vpp_va_surfaces_.empty())) { DVLOGF(4) << "Not enough surfaces available"; return nullptr; } @@ -663,10 +669,14 @@ << ", but got: " << frame->visible_rect().ToString()); return nullptr; } - input_surface = new VASurface(available_va_surface_ids_.back(), - encoder_->GetCodedSize(), kVaSurfaceFormat, - base::BindOnce(va_surface_release_cb_)); - available_va_surface_ids_.pop_back(); + + const VASurfaceID input_surface_id = available_va_surfaces_.back()->id(); + input_surface = new VASurface( + input_surface_id, encoder_->GetCodedSize(), kVaSurfaceFormat, + base::BindOnce(&VaapiVideoEncodeAccelerator::RecycleVASurfaceID, + encoder_weak_this_, + std::move(available_va_surfaces_.back()))); + available_va_surfaces_.pop_back(); } if (visible_rect_ != frame->visible_rect()) { @@ -684,20 +694,32 @@ } // Allocate the same number of surfaces as reconstructed surfaces. + std::vector<VASurfaceID> surface_ids; if (!vpp_vaapi_wrapper_->CreateContextAndSurfaces( kVaSurfaceFormat, aligned_va_surface_size_, VaapiWrapper::SurfaceUsageHint::kVideoProcessWrite, - num_frames_in_flight_ + 1, &available_vpp_va_surface_ids_)) { + num_frames_in_flight_ + 1, &surface_ids)) { NOTIFY_ERROR(kPlatformFailureError, "Failed creating VASurfaces for scaling"); vpp_vaapi_wrapper_ = nullptr; return nullptr; - }; + } + for (const VASurfaceID surface_id : surface_ids) { + available_vpp_va_surfaces_.push_back( + std::make_unique<ScopedVASurfaceID>( + surface_id, base::BindOnce(&VaapiWrapper::DestroySurface, + vpp_vaapi_wrapper_))); + } } + + const VASurfaceID blit_surface_id = available_vpp_va_surfaces_.back()->id(); scoped_refptr<VASurface> blit_surface = new VASurface( - available_vpp_va_surface_ids_.back(), aligned_va_surface_size_, - kVaSurfaceFormat, base::BindOnce(vpp_va_surface_release_cb_)); - available_vpp_va_surface_ids_.pop_back(); + blit_surface_id, aligned_va_surface_size_, kVaSurfaceFormat, + base::BindOnce(&VaapiVideoEncodeAccelerator::RecycleVPPVASurfaceID, + encoder_weak_this_, + std::move(available_vpp_va_surfaces_.back()))); + available_vpp_va_surfaces_.pop_back(); + // Crop/Scale the visible area of |frame->visible_rect()| -> // |visible_rect_|. if (!vpp_vaapi_wrapper_->BlitSurface(*input_surface, *blit_surface, @@ -720,10 +742,14 @@ // Here, the surface size contained in |input_surface| is // |aligned_va_surface_size_| regardless of scaling in zero-copy mode, and // encoder_->GetCodedSize(). - scoped_refptr<VASurface> reconstructed_surface = - new VASurface(available_va_surface_ids_.back(), encoder_->GetCodedSize(), - kVaSurfaceFormat, base::BindOnce(va_surface_release_cb_)); - available_va_surface_ids_.pop_back(); + const VASurfaceID reconstructed_surface_id = + available_va_surfaces_.back()->id(); + scoped_refptr<VASurface> reconstructed_surface = new VASurface( + reconstructed_surface_id, encoder_->GetCodedSize(), kVaSurfaceFormat, + base::BindOnce(&VaapiVideoEncodeAccelerator::RecycleVASurfaceID, + encoder_weak_this_, + std::move(available_va_surfaces_.back()))); + available_va_surfaces_.pop_back(); auto job = std::make_unique<VaapiEncodeJob>( frame, force_keyframe, @@ -899,34 +925,35 @@ VLOGF(2); DCHECK_CALLED_ON_VALID_SEQUENCE(encoder_sequence_checker_); - encoder_weak_this_factory_.InvalidateWeakPtrs(); - if (flush_callback_) { child_task_runner_->PostTask( FROM_HERE, base::BindOnce(std::move(flush_callback_), false)); } // Clean up members that are to be accessed on the encoder thread only. - if (vaapi_wrapper_) - vaapi_wrapper_->DestroyContextAndSurfaces(available_va_surface_ids_); - if (vpp_vaapi_wrapper_) { - vpp_vaapi_wrapper_->DestroyContextAndSurfaces( - available_vpp_va_surface_ids_); - } + available_bitstream_buffers_ = {}; + input_queue_ = {}; - available_va_buffer_ids_.clear(); + // Release input and reconstructed surfaces held by + // |submitted_encode_jobs_|. + submitted_encode_jobs_ = {}; - while (!available_bitstream_buffers_.empty()) - available_bitstream_buffers_.pop(); - - while (!input_queue_.empty()) - input_queue_.pop(); - - while (!submitted_encode_jobs_.empty()) - submitted_encode_jobs_.pop(); - + // Release reconstructed surfaces held by |encoder_| as reference pictures. encoder_ = nullptr; + // Invalidate |encoder_weak_this_| so that the above clean up can let surfaces + // be back to |available_va_surfaces_ids_| and + // |available_vpp_va_surfaces_ids_|. + encoder_weak_this_factory_.InvalidateWeakPtrs(); + + if (vaapi_wrapper_) + vaapi_wrapper_->DestroyContext(); + if (vpp_vaapi_wrapper_) + vpp_vaapi_wrapper_->DestroyContext(); + + available_va_surfaces_.clear(); + available_vpp_va_surfaces_.clear(); + delete this; }
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.h b/media/gpu/vaapi/vaapi_video_encode_accelerator.h index cdb90fd4..5af15d8 100644 --- a/media/gpu/vaapi/vaapi_video_encode_accelerator.h +++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.h
@@ -25,6 +25,8 @@ namespace media { class VaapiEncodeJob; +template <typename T> +class ScopedID; // A VideoEncodeAccelerator implementation that uses VA-API // (https://01.org/vaapi) for HW-accelerated video encode. @@ -53,6 +55,9 @@ class VP8Accelerator; class VP9Accelerator; + // A self-cleaning VASurfaceID. + using ScopedVASurfaceID = ScopedID<VASurfaceID>; + // Encoder state. enum State { kUninitialized, @@ -113,12 +118,16 @@ void ExecuteEncode(VASurfaceID va_surface_id); // Callback that returns a no longer used VASurfaceID to - // |available_va_surface_ids_| for reuse. - void RecycleVASurfaceID(VASurfaceID va_surface_id); + // |available_va_surfaces_| for reuse. + void RecycleVASurfaceID( + std::unique_ptr<ScopedVASurfaceID> scoped_va_surface_id, + VASurfaceID va_surface_id); // Callback that returns a no longer used VASurfaceID to - // |available_vpp_va_surface_ids_| for reuse. - void RecycleVPPVASurfaceID(VASurfaceID va_surface_id); + // |available_vpp_va_surfaces_| for reuse. + void RecycleVPPVASurfaceID( + std::unique_ptr<ScopedVASurfaceID> scoped_va_surface_id, + VASurfaceID va_surface_id); // Returns a bitstream buffer to the client if both a previously executed job // awaits to be completed and we have bitstream buffers available to download @@ -195,9 +204,9 @@ std::unique_ptr<AcceleratedVideoEncoder> encoder_; // VA surfaces available for encoding. - std::vector<VASurfaceID> available_va_surface_ids_; + std::vector<std::unique_ptr<ScopedVASurfaceID>> available_va_surfaces_; // VA surfaces available for scaling. - std::vector<VASurfaceID> available_vpp_va_surface_ids_; + std::vector<std::unique_ptr<ScopedVASurfaceID>> available_vpp_va_surfaces_; // VASurfaceIDs internal format. static constexpr unsigned int kVaSurfaceFormat = VA_RT_FORMAT_YUV420; @@ -205,10 +214,6 @@ // VA buffers for coded frames. std::vector<VABufferID> available_va_buffer_ids_; - // Callback via which finished VA surfaces are returned to us. - base::RepeatingCallback<void(VASurfaceID)> va_surface_release_cb_; - base::RepeatingCallback<void(VASurfaceID)> vpp_va_surface_release_cb_; - // Queue of input frames to be encoded. base::queue<std::unique_ptr<InputFrameRef>> input_queue_;
diff --git a/media/gpu/vp9_decoder.cc b/media/gpu/vp9_decoder.cc index b66feb0..a36e204 100644 --- a/media/gpu/vp9_decoder.cc +++ b/media/gpu/vp9_decoder.cc
@@ -188,12 +188,12 @@ gfx::Size new_pic_size = curr_frame_size_; gfx::Rect new_render_rect(curr_frame_hdr_->render_width, curr_frame_hdr_->render_height); - // For safety, check the validity of render size or leave it as (0, 0). + // For safety, check the validity of render size or leave it as pic size. if (!gfx::Rect(new_pic_size).Contains(new_render_rect)) { DVLOG(1) << "Render size exceeds picture size. render size: " << new_render_rect.ToString() << ", picture size: " << new_pic_size.ToString(); - new_render_rect = gfx::Rect(); + new_render_rect = gfx::Rect(new_pic_size); } VideoCodecProfile new_profile = VP9ProfileToVideoCodecProfile(curr_frame_hdr_->profile);
diff --git a/media/gpu/windows/d3d11_texture_selector.cc b/media/gpu/windows/d3d11_texture_selector.cc index 756ea47..0c6ce073 100644 --- a/media/gpu/windows/d3d11_texture_selector.cc +++ b/media/gpu/windows/d3d11_texture_selector.cc
@@ -16,10 +16,11 @@ namespace media { TextureSelector::TextureSelector(VideoPixelFormat pixfmt, + DXGI_FORMAT output_dxgifmt, bool supports_swap_chain) : pixel_format_(pixfmt), - supports_swap_chain_(supports_swap_chain) { -} + output_dxgifmt_(output_dxgifmt), + supports_swap_chain_(supports_swap_chain) {} bool SupportsZeroCopy(const gpu::GpuPreferences& preferences, const gpu::GpuDriverBugWorkarounds& workarounds) { @@ -55,12 +56,11 @@ break; case DXGI_FORMAT_P010: MEDIA_LOG(INFO, media_log) << "D3D11VideoDecoder producing FP16"; - // Note: this combination isn't actually supported, since we don't support - // pbuffer textures right now. output_pixel_format = PIXEL_FORMAT_ARGB; output_dxgi_format = DXGI_FORMAT_R16G16B16A16_FLOAT; - // B8G8R8A8 is also an okay choice, if we don't have fp16 support. - needs_texture_copy = true; + // DXGI_FORMAT_B8G8R8A8_UNORM is also an okay choice, if we don't want to + // use fp16. + // TODO(liberato): Pick this better. break; default: // TODO(tmathmeyer) support other profiles in the future. @@ -69,6 +69,10 @@ return nullptr; } + // If we're trying to produce an output texture that's different from what + // the decoder is providing, then we need to copy it. + needs_texture_copy = (decoder_output_format != output_dxgi_format); + // Force texture copy on if requested for debugging. if (base::FeatureList::IsEnabled(kD3D11VideoDecoderAlwaysCopy)) needs_texture_copy = true; @@ -79,10 +83,9 @@ output_pixel_format, decoder_output_format, output_dxgi_format, supports_nv12_decode_swap_chain); // TODO(tmathmeyer) false always? } else { - // We don't support anything except NV12 for binding right now. With - // pbuffer textures, we could support rgb8 and / or fp16. - DCHECK_EQ(output_pixel_format, PIXEL_FORMAT_NV12); + MEDIA_LOG(INFO, media_log) << "D3D11VideoDecoder is binding textures"; return std::make_unique<TextureSelector>(output_pixel_format, + output_dxgi_format, supports_nv12_decode_swap_chain); } } @@ -93,7 +96,7 @@ ComD3D11DeviceContext device_context, gfx::Size size) { // TODO(liberato): If the output format is rgb, then create a pbuffer wrapper. - return std::make_unique<DefaultTexture2DWrapper>(size); + return std::make_unique<DefaultTexture2DWrapper>(size, OutputDXGIFormat()); } std::unique_ptr<Texture2DWrapper> CopyTextureSelector::CreateTextureWrapper( @@ -125,7 +128,7 @@ return nullptr; return std::make_unique<CopyingTexture2DWrapper>( - size, std::make_unique<DefaultTexture2DWrapper>(size), + size, std::make_unique<DefaultTexture2DWrapper>(size, OutputDXGIFormat()), std::make_unique<VideoProcessorProxy>(video_device, device_context), out_texture); }
diff --git a/media/gpu/windows/d3d11_texture_selector.h b/media/gpu/windows/d3d11_texture_selector.h index f91e9fc..effd825 100644 --- a/media/gpu/windows/d3d11_texture_selector.h +++ b/media/gpu/windows/d3d11_texture_selector.h
@@ -24,6 +24,7 @@ class MEDIA_GPU_EXPORT TextureSelector { public: TextureSelector(VideoPixelFormat pixfmt, + DXGI_FORMAT output_dxgifmt, bool supports_swap_chain); virtual ~TextureSelector() = default; @@ -39,12 +40,14 @@ ComD3D11DeviceContext, gfx::Size size); - VideoPixelFormat PixelFormat() { return pixel_format_; } + VideoPixelFormat PixelFormat() const { return pixel_format_; } + DXGI_FORMAT OutputDXGIFormat() const { return output_dxgifmt_; } private: friend class CopyTextureSelector; const VideoPixelFormat pixel_format_; + const DXGI_FORMAT output_dxgifmt_; const bool supports_swap_chain_; }; @@ -55,18 +58,13 @@ DXGI_FORMAT input_dxgifmt, DXGI_FORMAT output_dxgifmt, bool supports_swap_chain) - : TextureSelector(pixfmt, - supports_swap_chain), - output_dxgifmt_(output_dxgifmt) {} + : TextureSelector(pixfmt, output_dxgifmt, supports_swap_chain) {} std::unique_ptr<Texture2DWrapper> CreateTextureWrapper( ComD3D11Device device, ComD3D11VideoDevice video_device, ComD3D11DeviceContext, gfx::Size size) override; - - private: - DXGI_FORMAT output_dxgifmt_; }; } // namespace media
diff --git a/media/gpu/windows/d3d11_texture_selector_unittest.cc b/media/gpu/windows/d3d11_texture_selector_unittest.cc index 27b06174..4503d90 100644 --- a/media/gpu/windows/d3d11_texture_selector_unittest.cc +++ b/media/gpu/windows/d3d11_texture_selector_unittest.cc
@@ -49,8 +49,9 @@ TEST_F(D3D11TextureSelectorUnittest, NV12BindsToNV12) { auto tex_sel = CreateWithDefaultGPUInfo(DXGI_FORMAT_NV12); - // TODO(liberato): checl "binds", somehow. + // TODO(liberato): check "binds", somehow. EXPECT_EQ(tex_sel->PixelFormat(), PIXEL_FORMAT_NV12); + EXPECT_EQ(tex_sel->OutputDXGIFormat(), DXGI_FORMAT_NV12); } TEST_F(D3D11TextureSelectorUnittest, P010CopiesToARGB) { @@ -58,6 +59,9 @@ // TODO(liberato): check "copies", somehow. EXPECT_EQ(tex_sel->PixelFormat(), PIXEL_FORMAT_ARGB); + // Note that this might also produce 8 bit rgb, but for now always + // tries for fp16. + EXPECT_EQ(tex_sel->OutputDXGIFormat(), DXGI_FORMAT_R16G16B16A16_FLOAT); } } // namespace media
diff --git a/media/gpu/windows/d3d11_texture_wrapper.cc b/media/gpu/windows/d3d11_texture_wrapper.cc index 50a1229..6723664c 100644 --- a/media/gpu/windows/d3d11_texture_wrapper.cc +++ b/media/gpu/windows/d3d11_texture_wrapper.cc
@@ -4,7 +4,10 @@ #include "media/gpu/windows/d3d11_texture_wrapper.h" +#include <list> #include <memory> +#include <utility> +#include <vector> #include "gpu/command_buffer/service/mailbox_manager.h" #include "media/base/win/mf_helpers.h" @@ -12,12 +15,49 @@ namespace media { +// Handy structure so that we can activate / bind one or two textures. +struct ScopedTextureEverything { + ScopedTextureEverything(GLenum unit, GLuint service_id) + : active_(unit), binder_(GL_TEXTURE_EXTERNAL_OES, service_id) {} + ~ScopedTextureEverything() = default; + + // Order is important; we need |active_| to be constructed first + // and destructed last. + gl::ScopedActiveTexture active_; + gl::ScopedTextureBinder binder_; + + DISALLOW_COPY_AND_ASSIGN(ScopedTextureEverything); +}; + +// Another handy helper class to guarantee that ScopedTextureEverythings +// are deleted in reverse order. This is required so that the scoped +// active texture unit doesn't change. Surprisingly, none of the stl +// containers, or the chromium ones, seem to guarantee anything about +// the order of destruction. +struct OrderedDestructionList { + OrderedDestructionList() = default; + ~OrderedDestructionList() { + // Erase last-to-first. + while (!list_.empty()) + list_.pop_back(); + } + + template <typename... Args> + void emplace_back(Args&&... args) { + list_.emplace_back(std::forward<Args>(args)...); + } + + std::list<ScopedTextureEverything> list_; + DISALLOW_COPY_AND_ASSIGN(OrderedDestructionList); +}; + Texture2DWrapper::Texture2DWrapper() = default; Texture2DWrapper::~Texture2DWrapper() = default; -DefaultTexture2DWrapper::DefaultTexture2DWrapper(const gfx::Size& size) - : size_(size) {} +DefaultTexture2DWrapper::DefaultTexture2DWrapper(const gfx::Size& size, + DXGI_FORMAT dxgi_format) + : size_(size), dxgi_format_(dxgi_format) {} DefaultTexture2DWrapper::~DefaultTexture2DWrapper() = default; @@ -33,6 +73,8 @@ if (!result.IsOk()) return false; + // TODO(liberato): make sure that |mailbox_holders_| is zero-initialized in + // case we don't use all the planes. for (size_t i = 0; i < VideoFrame::kMaxPlanes; i++) (*mailbox_dest)[i] = mailbox_holders_[i]; @@ -44,8 +86,19 @@ if (!gpu_resources_) return false; - // We currently only bind NV12, which requires two GL textures. - const int textures_per_picture = 2; + // YUV textures are mapped onto two GL textures, while RGB use one. + int textures_per_picture = 0; + switch (dxgi_format_) { + case DXGI_FORMAT_NV12: + textures_per_picture = 2; + break; + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + textures_per_picture = 1; + break; + default: + return false; + } // Generate mailboxes and holders. std::vector<gpu::Mailbox> mailboxes; @@ -89,6 +142,8 @@ return false; // Create the textures and attach them to the mailboxes. + // TODO(liberato): Should we use GL_FLOAT for an fp16 texture? It doesn't + // really seem to matter so far as I can tell. for (int texture_idx = 0; texture_idx < textures_per_picture; texture_idx++) { uint32_t service_id = helper_->CreateTexture(target, GL_RGBA, size.width(), size.height(), @@ -100,11 +155,11 @@ // Create the stream for zero-copy use by gl. EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); const EGLint stream_attributes[] = { - EGL_CONSUMER_LATENCY_USEC_KHR, - 0, - EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, - 0, + // clang-format off + EGL_CONSUMER_LATENCY_USEC_KHR, 0, + EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0, EGL_NONE, + // clang-format on }; EGLStreamKHR stream = eglCreateStreamKHR(egl_display, stream_attributes); RETURN_ON_FAILURE(!!stream, "Could not create stream", false); @@ -114,26 +169,35 @@ // this function unless |helper_| retains it. Also, this won't work if we // have a FakeCommandBufferHelper since the service IDs aren't meaningful. gl_image_ = base::MakeRefCounted<gl::GLImageDXGI>(size, stream); - gl::ScopedActiveTexture texture0(GL_TEXTURE0); - gl::ScopedTextureBinder texture0_binder(GL_TEXTURE_EXTERNAL_OES, - service_ids_[0]); - gl::ScopedActiveTexture texture1(GL_TEXTURE1); - gl::ScopedTextureBinder texture1_binder(GL_TEXTURE_EXTERNAL_OES, - service_ids_[1]); - EGLAttrib consumer_attributes[] = { - EGL_COLOR_BUFFER_TYPE, - EGL_YUV_BUFFER_EXT, - EGL_YUV_NUMBER_OF_PLANES_EXT, - 2, - EGL_YUV_PLANE0_TEXTURE_UNIT_NV, - 0, - EGL_YUV_PLANE1_TEXTURE_UNIT_NV, - 1, - EGL_NONE, - }; + // Bind all the textures so that the stream can find them. + OrderedDestructionList texture_everythings; + for (int i = 0; i < textures_per_picture; i++) + texture_everythings.emplace_back(GL_TEXTURE0 + i, service_ids_[i]); + + std::vector<EGLAttrib> consumer_attributes; + if (textures_per_picture == 2) { + // Assume NV12. + consumer_attributes = { + // clang-format off + EGL_COLOR_BUFFER_TYPE, EGL_YUV_BUFFER_EXT, + EGL_YUV_NUMBER_OF_PLANES_EXT, 2, + EGL_YUV_PLANE0_TEXTURE_UNIT_NV, 0, + EGL_YUV_PLANE1_TEXTURE_UNIT_NV, 1, + EGL_NONE, + // clang-format on + }; + } else { + // Assume some rgb format. + consumer_attributes = { + // clang-format off + EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, + EGL_NONE, + // clang-format on + }; + } EGLBoolean result = eglStreamConsumerGLTextureExternalAttribsNV( - egl_display, stream, consumer_attributes); + egl_display, stream, consumer_attributes.data()); RETURN_ON_FAILURE(result, "Could not set stream consumer", false); EGLAttrib producer_attributes[] = {
diff --git a/media/gpu/windows/d3d11_texture_wrapper.h b/media/gpu/windows/d3d11_texture_wrapper.h index 7299f315..3d0e38bf 100644 --- a/media/gpu/windows/d3d11_texture_wrapper.h +++ b/media/gpu/windows/d3d11_texture_wrapper.h
@@ -55,7 +55,9 @@ // instance for each concurrently outstanding texture. class MEDIA_GPU_EXPORT DefaultTexture2DWrapper : public Texture2DWrapper { public: - DefaultTexture2DWrapper(const gfx::Size& size); + // While the specific texture instance can change on every call to + // ProcessTexture, the dxgi format must be the same for all of them. + DefaultTexture2DWrapper(const gfx::Size& size, DXGI_FORMAT dxgi_format); ~DefaultTexture2DWrapper() override; bool Init(GetCommandBufferHelperCB get_helper_cb) override; @@ -96,6 +98,7 @@ gfx::Size size_; std::unique_ptr<GpuResources> gpu_resources_; MailboxHolderArray mailbox_holders_; + DXGI_FORMAT dxgi_format_; }; } // namespace media
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc index fbccdb5..f9b2f28 100644 --- a/media/gpu/windows/d3d11_video_decoder.cc +++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -743,10 +743,15 @@ // For NV12, overlay is allowed by default. If the decoder is going to support // non-NV12 textures, then this may have to be conditionally set. Also note // that ALLOW_OVERLAY is required for encrypted video path. + // // Since all of our picture buffers allow overlay, we just use the finch // feature. However, we may choose to set ALLOW_OVERLAY to false even if // the finch flag is enabled. We may not choose to set ALLOW_OVERLAY if the // flag is off, however. + // + // Also note that, since we end up binding textures with GLImageDXGI, it's + // probably okay just to allow overlay always, and let the swap chain + // presenter decide if it wants to. const bool allow_overlay = base::FeatureList::IsEnabled(kD3D11VideoDecoderAllowOverlay); frame->metadata()->SetBoolean(VideoFrameMetadata::ALLOW_OVERLAY,
diff --git a/mojo/public/cpp/bindings/tests/BUILD.gn b/mojo/public/cpp/bindings/tests/BUILD.gn index 8ecc7de..0c7d2d0 100644 --- a/mojo/public/cpp/bindings/tests/BUILD.gn +++ b/mojo/public/cpp/bindings/tests/BUILD.gn
@@ -158,7 +158,12 @@ "struct_headers_unittest.test-mojom", ] - public_deps = [ "//mojo/public/mojom/base" ] + public_deps = [ + # NOTE: This is a kind of test in itself, to verify that mojom() rules can + # operate on generated mojom files and produce compilable outputs. + ":generated_test_mojom", + "//mojo/public/mojom/base", + ] support_lazy_serialization = true } @@ -192,3 +197,15 @@ deps = [ "//mojo/public/c/system" ] } + +action("generate_test_mojom") { + script = "generate_test_mojom.py" + outputs = [ "$target_gen_dir/generated.test-mojom" ] + args = [ rebase_path("$target_gen_dir/generated.test-mojom") ] +} + +mojom("generated_test_mojom") { + testonly = true + sources = [ "$target_gen_dir/generated.test-mojom" ] + parser_deps = [ ":generate_test_mojom" ] +}
diff --git a/mojo/public/cpp/bindings/tests/generate_test_mojom.py b/mojo/public/cpp/bindings/tests/generate_test_mojom.py new file mode 100755 index 0000000..22929f3 --- /dev/null +++ b/mojo/public/cpp/bindings/tests/generate_test_mojom.py
@@ -0,0 +1,15 @@ +#!/usr/bin/env python +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import sys + +def DoMain(args): + if len(args) != 1: + sys.exit(1) + with open(args[0], "w") as f: + f.writelines("module mojo.test.generated_test_mojom; interface Foo {};") + +if __name__ == '__main__': + DoMain(sys.argv[1:])
diff --git a/mojo/public/tools/bindings/BUILD.gn b/mojo/public/tools/bindings/BUILD.gn index 400cffc6..4743cfc 100644 --- a/mojo/public/tools/bindings/BUILD.gn +++ b/mojo/public/tools/bindings/BUILD.gn
@@ -92,9 +92,9 @@ "$target_gen_dir/ts_templates.zip", ] args = [ - "--use_bundled_pylibs", - "precompile", "-o", rebase_path(target_gen_dir, root_build_dir), + "--use_bundled_pylibs", + "precompile", ] }
diff --git a/mojo/public/tools/bindings/blink_bindings_configuration.gni b/mojo/public/tools/bindings/blink_bindings_configuration.gni index 5f67d5d..2684c0a 100644 --- a/mojo/public/tools/bindings/blink_bindings_configuration.gni +++ b/mojo/public/tools/bindings/blink_bindings_configuration.gni
@@ -36,5 +36,4 @@ ] } -blacklist = [] component_macro_suffix = "_BLINK"
diff --git a/mojo/public/tools/bindings/mojom.gni b/mojo/public/tools/bindings/mojom.gni index 507a1d4..4e22eb0 100644 --- a/mojo/public/tools/bindings/mojom.gni +++ b/mojo/public/tools/bindings/mojom.gni
@@ -199,6 +199,9 @@ # public_deps (optional) # Note: this can contain only other mojom targets. # +# parser_deps (optional) +# List of non-mojom targets required for the mojom sources to be parsed. +# # import_dirs (optional) # List of import directories that will get added when processing sources. # @@ -413,6 +416,42 @@ } write_file(target_sources_list, sources_list) + # Listed sources may be relative to the current target dir, or they may be + # absolute paths, including paths to generated mojom files. While those are + # fine as-is for input references, deriving output paths can be more subtle. + # + # Here we rewrite all source paths to be relative to the root build dir and + # strip any root_gen_dir prefixes. + # + # So for a target in //foo/bar with: + # + # sources = [ + # "a.mojom", + # "b/c.mojom", + # "//baz/d.mojom", + # "$target_gen_dir/e.mojom", + # ] + # + # output_file_base_paths will be: + # + # [ + # "foo/bar/a.mojom", + # "foo/bar/b/c.mojom", + # "baz/d.mojom", + # "foo/bar/e.mojom", + # ] + # + # This result is essentially a list of base filename paths which are suitable + # for the naming of any generated output files derived from their + # corresponding input mojoms. These paths are always considered to be relative + # to root_gen_dir. + source_abspaths = rebase_path(sources_list, "//") + output_file_base_paths = [] + foreach(path, source_abspaths) { + output_file_base_paths += + [ string_replace(path, rebase_path(root_gen_dir, "//") + "/", "") ] + } + # Sanity check that either all input files have a .mojom extension, or # all input files have a .test-mojom extension AND |testonly| is |true|. sources_list_filenames = @@ -451,7 +490,7 @@ invoker.enable_fuzzing) && (!defined(invoker.testonly) || !invoker.testonly) - if (defined(invoker.sources)) { + if (sources_list != []) { parser_target_name = "${target_name}__parser" enabled_features = [] if (defined(invoker.enabled_features)) { @@ -479,23 +518,28 @@ action(parser_target_name) { script = mojom_generator_script inputs = mojom_generator_sources + jinja2_sources - sources = invoker.sources + sources = sources_list + if (defined(invoker.parser_deps)) { + deps = invoker.parser_deps + } outputs = [] filelist = [] - foreach(source, invoker.sources) { - filename = get_path_info("$source", "name") - dirname = get_path_info("$source", "gen_dir") - outputs += [ "$dirname/$filename.p" ] - filelist += [ rebase_path("$source", root_build_dir) ] + foreach(source, sources_list) { + filelist += [ rebase_path(source, root_build_dir) ] + } + foreach(base_path, output_file_base_paths) { + filename = get_path_info(base_path, "name") + dirname = get_path_info(base_path, "dir") + outputs += [ "$root_gen_dir/$dirname/$filename.p" ] } response_file_contents = filelist args = [ - "parse", - "--filelist={{response_file_name}}", "-o", rebase_path(root_gen_dir, root_build_dir), + "parse", + "--filelist={{response_file_name}}", "-d", rebase_path("//", root_build_dir), ] @@ -511,7 +555,7 @@ parsed_target_name = "${target_name}__parsed" group(parsed_target_name) { public_deps = [] - if (defined(invoker.sources)) { + if (sources_list != []) { public_deps += [ ":$parser_target_name" ] } foreach(d, all_deps) { @@ -523,7 +567,7 @@ } } - if (defined(invoker.sources)) { + if (sources_list != []) { verify_deps_target_names = [] verify_deps_target_name = "${target_name}__verify_deps" verify_deps_target_names += [ ":$verify_deps_target_name" ] @@ -532,27 +576,32 @@ action(verify_deps_target_name) { script = mojom_generator_script inputs = mojom_generator_sources + jinja2_sources - sources = invoker.sources + sources = sources_list deps = [ ":$parsed_target_name" ] + if (defined(invoker.parser_deps)) { + deps += invoker.parser_deps + } outputs = [] filelist = [] - foreach(source, invoker.sources) { - filename = get_path_info("$source", "name") - dirname = get_path_info("$source", "gen_dir") - outputs += [ "$dirname/$filename.v" ] - filelist += [ rebase_path("$source", root_build_dir) ] + foreach(source, sources_list) { + filelist += [ rebase_path(source, root_build_dir) ] + } + foreach(base_path, output_file_base_paths) { + filename = get_path_info(base_path, "name") + dirname = get_path_info(base_path, "dir") + outputs += [ "$root_gen_dir/$dirname/$filename.v" ] } response_file_contents = filelist args = [ + "-o", + rebase_path(root_gen_dir, root_build_dir), "verify", "--filelist={{response_file_name}}", "-f", rebase_path("$target_gen_dir/$mojom_target_name.deps_sources_list", root_build_dir), - "--gen_dir", - rebase_path(root_gen_dir, root_build_dir), "--depth", rebase_path("//", root_build_dir), ] @@ -562,16 +611,16 @@ generator_cpp_message_ids_target_name = "${target_name}__generate_message_ids" # Generate code that is shared by different variants. - if (defined(invoker.sources)) { + if (sources_list != []) { common_generator_args = [ "--use_bundled_pylibs", + "-o", + rebase_path(root_gen_dir, root_build_dir), "generate", "-d", rebase_path("//", root_build_dir), "-I", rebase_path("//", root_build_dir), - "-o", - rebase_path(root_gen_dir, root_build_dir), "--bytecode_path", rebase_path("$root_gen_dir/mojo/public/tools/bindings", root_build_dir), ] @@ -628,18 +677,23 @@ action(generator_cpp_message_ids_target_name) { script = mojom_generator_script inputs = mojom_generator_sources + jinja2_sources - sources = invoker.sources + sources = sources_list deps = [ ":$parsed_target_name", "//mojo/public/tools/bindings:precompile_templates", ] + if (defined(invoker.parser_deps)) { + deps += invoker.parser_deps + } outputs = [] args = common_generator_args filelist = [] - foreach(source, invoker.sources) { - outputs += [ "$target_gen_dir/$source-shared-message-ids.h" ] + foreach(source, sources_list) { filelist += [ rebase_path("$source", root_build_dir) ] } + foreach(base_path, output_file_base_paths) { + outputs += [ "$root_gen_dir/$base_path-shared-message-ids.h" ] + } response_file_contents = filelist @@ -658,33 +712,32 @@ } } - generator_shared_cpp_outputs = [ - "{{source_gen_dir}}/{{source_file_part}}-params-data.h", - "{{source_gen_dir}}/{{source_file_part}}-shared-internal.h", - "{{source_gen_dir}}/{{source_file_part}}-shared.cc", - "{{source_gen_dir}}/{{source_file_part}}-shared.h", - ] generator_shared_target_name = "${target_name}_shared__generator" action(generator_shared_target_name) { visibility = [ ":*" ] script = mojom_generator_script inputs = mojom_generator_sources + jinja2_sources - sources = invoker.sources + sources = sources_list deps = [ ":$parsed_target_name", "//mojo/public/tools/bindings:precompile_templates", ] + verify_deps_target_names + if (defined(invoker.parser_deps)) { + deps += invoker.parser_deps + } outputs = [] args = common_generator_args filelist = [] - foreach(source, invoker.sources) { + foreach(source, sources_list) { filelist += [ rebase_path("$source", root_build_dir) ] + } + foreach(base_path, output_file_base_paths) { outputs += [ - "$target_gen_dir/$source-params-data.h", - "$target_gen_dir/$source-shared-internal.h", - "$target_gen_dir/$source-shared.cc", - "$target_gen_dir/$source-shared.h", + "$root_gen_dir/$base_path-params-data.h", + "$root_gen_dir/$base_path-shared-internal.h", + "$root_gen_dir/$base_path-shared.cc", + "$root_gen_dir/$base_path-shared.h", ] } @@ -724,9 +777,16 @@ } deps = [] public_deps = [] - if (defined(invoker.sources)) { - sources = - process_file_template(invoker.sources, generator_shared_cpp_outputs) + if (output_file_base_paths != []) { + sources = [] + foreach(base_path, output_file_base_paths) { + sources += [ + "$root_gen_dir/$base_path-params-data.h", + "$root_gen_dir/$base_path-shared-internal.h", + "$root_gen_dir/$base_path-shared.cc", + "$root_gen_dir/$base_path-shared.h", + ] + } public_deps += [ ":$generator_shared_target_name" ] } if (require_full_cpp_deps) { @@ -849,38 +909,21 @@ type_mappings_path = "$target_gen_dir/${target_name}${variant_suffix}__type_mappings" active_typemaps = [] - enabled_sources = [] - if (defined(invoker.sources)) { - generator_cpp_outputs = [] + if (sources_list != []) { + generator_cpp_output_suffixes = [] variant_dash_suffix = "" if (defined(variant)) { variant_dash_suffix = "-${variant}" } - generator_cpp_outputs += [ - "{{source_gen_dir}}/{{source_file_part}}${variant_dash_suffix}-forward.h", - "{{source_gen_dir}}/{{source_file_part}}${variant_dash_suffix}-import-headers.h", - "{{source_gen_dir}}/{{source_file_part}}${variant_dash_suffix}-test-utils.cc", - "{{source_gen_dir}}/{{source_file_part}}${variant_dash_suffix}-test-utils.h", - "{{source_gen_dir}}/{{source_file_part}}${variant_dash_suffix}.cc", - "{{source_gen_dir}}/{{source_file_part}}${variant_dash_suffix}.h", + generator_cpp_output_suffixes += [ + "${variant_dash_suffix}-forward.h", + "${variant_dash_suffix}-import-headers.h", + "${variant_dash_suffix}-test-utils.cc", + "${variant_dash_suffix}-test-utils.h", + "${variant_dash_suffix}.cc", + "${variant_dash_suffix}.h", ] - enabled_sources = [] - if (defined(bindings_configuration.blacklist)) { - foreach(source, invoker.sources) { - blacklisted = false - foreach(blacklisted_source, bindings_configuration.blacklist) { - if (get_path_info(source, "abspath") == blacklisted_source) { - blacklisted = true - } - } - if (!blacklisted) { - enabled_sources += [ source ] - } - } - } else { - enabled_sources = invoker.sources - } - foreach(source, enabled_sources) { + foreach(source, sources_list) { # TODO(sammc): Use a map instead of a linear scan when GN supports maps. foreach(typemap, bindings_configuration.typemaps) { _typemap_config = { @@ -923,24 +966,29 @@ visibility = [ ":*" ] script = mojom_generator_script inputs = mojom_generator_sources + jinja2_sources - sources = invoker.sources + sources = sources_list deps = [ ":$parsed_target_name", ":$type_mappings_target_name", "//mojo/public/tools/bindings:precompile_templates", ] + verify_deps_target_names + if (defined(invoker.parser_deps)) { + deps += invoker.parser_deps + } outputs = [] args = common_generator_args + export_args filelist = [] - foreach(source, invoker.sources) { + foreach(source, sources_list) { filelist += [ rebase_path("$source", root_build_dir) ] + } + foreach(base_path, output_file_base_paths) { outputs += [ - "$target_gen_dir/${source}${variant_dash_suffix}-forward.h", - "$target_gen_dir/${source}${variant_dash_suffix}-import-headers.h", - "$target_gen_dir/${source}${variant_dash_suffix}-test-utils.cc", - "$target_gen_dir/${source}${variant_dash_suffix}-test-utils.h", - "$target_gen_dir/${source}${variant_dash_suffix}.cc", - "$target_gen_dir/${source}${variant_dash_suffix}.h", + "$root_gen_dir/${base_path}${variant_dash_suffix}-forward.h", + "$root_gen_dir/${base_path}${variant_dash_suffix}-import-headers.h", + "$root_gen_dir/${base_path}${variant_dash_suffix}-test-utils.cc", + "$root_gen_dir/${base_path}${variant_dash_suffix}-test-utils.h", + "$root_gen_dir/${base_path}${variant_dash_suffix}.cc", + "$root_gen_dir/${base_path}${variant_dash_suffix}.h", ] } @@ -993,9 +1041,9 @@ assert( get_path_info(extra_cpp_template, "extension") == "tmpl", "--extra_cpp_template_paths only accepts template files ending in extension .tmpl") - foreach(source, invoker.sources) { + foreach(base_path, output_file_base_paths) { template_file_name = get_path_info("$extra_cpp_template", "name") - outputs += [ "$target_gen_dir/${source}${variant_dash_suffix}-${template_file_name}" ] + outputs += [ "$root_gen_dir/${base_path}${variant_dash_suffix}-${template_file_name}" ] } } } @@ -1031,7 +1079,7 @@ ] } - if (enabled_sources != []) { + if (sources_list != []) { # TODO(sammc): Pass the typemap description in a file to avoid command # line length limitations. typemap_description = [] @@ -1065,7 +1113,7 @@ group("${target_name}${variant_suffix}_headers") { public_deps = [] - if (enabled_sources != []) { + if (sources_list != []) { public_deps += [ ":$generator_cpp_message_ids_target_name", ":$generator_shared_target_name", @@ -1102,8 +1150,13 @@ testonly = invoker.testonly } defines = export_defines - if (enabled_sources != []) { - sources = process_file_template(enabled_sources, generator_cpp_outputs) + if (output_file_base_paths != []) { + sources = [] + foreach(base_path, output_file_base_paths) { + foreach(suffix, generator_cpp_output_suffixes) { + sources += [ "$root_gen_dir/${base_path}$suffix" ] + } + } } deps = [ ":$generator_cpp_message_ids_target_name", @@ -1120,7 +1173,7 @@ public_deps += [ "//mojo/public/cpp/bindings:bindings_base" ] } - if (enabled_sources != []) { + if (sources_list != []) { public_deps += [ ":$generator_target_name" ] } foreach(d, all_deps) { @@ -1192,13 +1245,11 @@ import("//build/config/android/rules.gni") java_generator_target_name = target_name + "_java__generator" - if (enabled_sources != []) { - generator_java_outputs = - [ "{{source_gen_dir}}/{{source_file_part}}.srcjar" ] + if (sources_list != []) { action(java_generator_target_name) { script = mojom_generator_script inputs = mojom_generator_sources + jinja2_sources - sources = enabled_sources + sources = sources_list deps = [ ":$parsed_target_name", ":$type_mappings_target_name", @@ -1207,9 +1258,11 @@ outputs = [] args = common_generator_args filelist = [] - foreach(source, invoker.sources) { + foreach(source, sources_list) { filelist += [ rebase_path("$source", root_build_dir) ] - outputs += [ "$target_gen_dir/$source.srcjar" ] + } + foreach(base_path, output_file_base_paths) { + outputs += [ "$root_gen_dir/$base_path.srcjar" ] } response_file_contents = filelist @@ -1235,9 +1288,10 @@ action(java_srcjar_target_name) { script = "//mojo/public/tools/gn/zip.py" inputs = [] - if (enabled_sources != []) { - inputs = - process_file_template(enabled_sources, generator_java_outputs) + if (output_file_base_paths != []) { + foreach(base_path, output_file_base_paths) { + inputs += [ "$root_gen_dir/${base_path}.srcjar" ] + } } output = "$target_gen_dir/$target_name.srcjar" outputs = [ output ] @@ -1248,7 +1302,7 @@ "--output=$rebase_output", ] deps = [] - if (enabled_sources != []) { + if (sources_list != []) { deps = [ ":$java_generator_target_name" ] } } @@ -1287,34 +1341,32 @@ if ((generate_fuzzing || !defined(invoker.cpp_only) || !invoker.cpp_only) && !use_typescript_for_target) { - if (defined(invoker.sources)) { + if (sources_list != []) { generator_js_target_name = "${target_name}_js__generator" - generator_js_lite_outputs = - [ "{{source_gen_dir}}/{{source_file_part}}-lite.js" ] - generator_js_outputs = [ "{{source_gen_dir}}/{{source_file_part}}.js" ] + - generator_js_lite_outputs action(generator_js_target_name) { script = mojom_generator_script inputs = mojom_generator_sources + jinja2_sources - sources = [] - if (defined(invoker.sources)) { - sources += invoker.sources - } + sources = sources_list deps = [ ":$parsed_target_name", "//mojo/public/tools/bindings:precompile_templates", ] + verify_deps_target_names + if (defined(invoker.parser_deps)) { + deps += invoker.parser_deps + } outputs = [] args = common_generator_args filelist = [] - foreach(source, invoker.sources) { + foreach(source, sources_list) { filelist += [ rebase_path("$source", root_build_dir) ] + } + foreach(base_path, output_file_base_paths) { outputs += [ - "$target_gen_dir/$source.js", - "$target_gen_dir/$source.externs.js", - "$target_gen_dir/$source-lite.js", - "$target_gen_dir/$source.html", - "$target_gen_dir/$source-lite-for-compile.js", + "$root_gen_dir/$base_path.js", + "$root_gen_dir/$base_path.externs.js", + "$root_gen_dir/$base_path-lite.js", + "$root_gen_dir/$base_path.html", + "$root_gen_dir/$base_path-lite-for-compile.js", ] } @@ -1347,7 +1399,7 @@ js_target_name = target_name + "_js" group(js_target_name) { public_deps = [] - if (defined(invoker.sources)) { + if (sources_list != []) { public_deps += [ ":$generator_js_target_name" ] } @@ -1359,8 +1411,14 @@ group(js_data_deps_target_name) { deps = [] - if (defined(invoker.sources)) { - data = process_file_template(invoker.sources, generator_js_outputs) + if (sources_list != []) { + data = [] + foreach(base_path, output_file_base_paths) { + data += [ + "$root_gen_dir/${base_path}.js", + "$root_gen_dir/${base_path}-lite.js", + ] + } deps += [ ":$generator_js_target_name" ] } @@ -1372,11 +1430,13 @@ } js_library_target_name = "${target_name}_js_library" - if (defined(invoker.sources)) { + if (sources_list != []) { js_library(js_library_target_name) { extra_public_deps = [ ":$generator_js_target_name" ] - sources = - process_file_template(invoker.sources, generator_js_lite_outputs) + sources = [] + foreach(base_path, output_file_base_paths) { + sources += [ "$root_gen_dir/${base_path}-lite.js" ] + } externs_list = [ "${externs_path}/mojo_core.js", "${externs_path}/pending.js", @@ -1394,14 +1454,13 @@ } js_library_for_compile_target_name = "${target_name}_js_library_for_compile" - if (defined(invoker.sources)) { - generator_js_lite_for_compile_outputs = - [ "{{source_gen_dir}}/{{source_file_part}}-lite-for-compile.js" ] + if (sources_list != []) { js_library(js_library_for_compile_target_name) { extra_public_deps = [ ":$generator_js_target_name" ] - sources = process_file_template(invoker.sources, - generator_js_lite_for_compile_outputs) - + sources = [] + foreach(base_path, output_file_base_paths) { + sources += [ "$root_gen_dir/${base_path}-lite-for-compile.js" ] + } externs_list = [ "${externs_path}/mojo_core.js", "${externs_path}/pending.js", @@ -1428,20 +1487,22 @@ ts_filelist = [] ts_outputs = [] js_outputs = [] - foreach(source, invoker.sources) { + foreach(source, sources_list) { source_filelist += [ rebase_path("$source", root_build_dir) ] + } + foreach(base_path, output_file_base_paths) { ts_outputs += [ - "$target_gen_dir/$source-lite.ts", - "$target_gen_dir/$source-lite.m.ts", + "$root_gen_dir/$base_path-lite.ts", + "$root_gen_dir/$base_path-lite.m.ts", ] ts_filelist += [ - rebase_path("$target_gen_dir/$source-lite.ts", root_build_dir), - rebase_path("$target_gen_dir/$source-lite.m.ts", root_build_dir), + rebase_path("$root_gen_dir/$base_path-lite.ts", root_build_dir), + rebase_path("$root_gen_dir/$base_path-lite.m.ts", root_build_dir), ] js_outputs += [ - "$target_gen_dir/$source-lite.js", - "$target_gen_dir/$source-lite.m.js", + "$root_gen_dir/$base_path-lite.js", + "$root_gen_dir/$base_path-lite.m.js", ] } @@ -1449,7 +1510,7 @@ action(generator_ts_target_name) { script = mojom_generator_script inputs = mojom_generator_sources + jinja2_sources - sources = invoker.sources + sources = sources_list deps = [ ":$parsed_target_name", "//mojo/public/tools/bindings:precompile_templates", @@ -1481,7 +1542,7 @@ js_target_name = target_name + "_js" group(js_target_name) { public_deps = [] - if (defined(invoker.sources)) { + if (sources_list != []) { public_deps += [ ":$generator_js_target_name" ] } @@ -1492,7 +1553,7 @@ } group(js_data_deps_target_name) { - data = process_file_template(invoker.sources, js_outputs) + data = js_outputs deps = [ ":$generator_js_target_name" ] data_deps = [] foreach(d, all_deps) {
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator.py b/mojo/public/tools/bindings/mojom_bindings_generator.py index acfc3c8..8cca6411 100755 --- a/mojo/public/tools/bindings/mojom_bindings_generator.py +++ b/mojo/public/tools/bindings/mojom_bindings_generator.py
@@ -90,26 +90,32 @@ class RelativePath(object): - """Represents a path relative to the source tree.""" - def __init__(self, path, source_root): + """Represents a path relative to the source tree or generated output dir.""" + + def __init__(self, path, source_root, output_dir): self.path = path - self.source_root = source_root + if path.startswith(source_root): + self.root = source_root + elif path.startswith(output_dir): + self.root = output_dir + else: + raise Exception("Invalid input path %s" % path) def relative_path(self): - return os.path.relpath(os.path.abspath(self.path), - os.path.abspath(self.source_root)) + return os.path.relpath( + os.path.abspath(self.path), os.path.abspath(self.root)) -def FindImportFile(rel_dir, file_name, search_rel_dirs): +def FindImportFile(args, rel_dir, file_name, search_rel_dirs): """Finds |file_name| in either |rel_dir| or |search_rel_dirs|. Returns a RelativePath with first file found, or an arbitrary non-existent file otherwise.""" for rel_search_dir in [rel_dir] + search_rel_dirs: path = os.path.join(rel_search_dir.path, file_name) if os.path.isfile(path): - return RelativePath(path, rel_search_dir.source_root) - return RelativePath(os.path.join(rel_dir.path, file_name), - rel_dir.source_root) + return RelativePath(path, rel_search_dir.root, args.output_dir) + return RelativePath( + os.path.join(rel_dir.path, file_name), rel_dir.root, args.output_dir) def ScrambleMethodOrdinals(interfaces, salt): @@ -194,7 +200,7 @@ imports = {} for parsed_imp in tree.import_list: rel_import_file = FindImportFile( - RelativePath(dirname, rel_filename.source_root), + args, RelativePath(dirname, rel_filename.root, args.output_dir), parsed_imp.import_filename, args.import_directories) imports[parsed_imp.import_filename] = self._GenerateModule( args, remaining_args, generator_modules, rel_import_file, @@ -250,9 +256,11 @@ for idx, import_dir in enumerate(args.import_directories): tokens = import_dir.split(":") if len(tokens) >= 2: - args.import_directories[idx] = RelativePath(tokens[0], tokens[1]) + args.import_directories[idx] = RelativePath(tokens[0], tokens[1], + args.output_dir) else: - args.import_directories[idx] = RelativePath(tokens[0], args.depth) + args.import_directories[idx] = RelativePath(tokens[0], args.depth, + args.output_dir) generator_modules = LoadGenerators(args.generators_string) fileutil.EnsureDirectoryExists(args.output_dir) @@ -265,8 +273,9 @@ args.filename.extend(f.read().split()) for filename in args.filename: - processor._GenerateModule(args, remaining_args, generator_modules, - RelativePath(filename, args.depth), []) + processor._GenerateModule( + args, remaining_args, generator_modules, + RelativePath(filename, args.depth, args.output_dir), []) return 0 @@ -332,7 +341,7 @@ args.filename.extend(f.read().split()) for filename in args.filename: - _ParseFile(args, RelativePath(filename, args.depth)) + _ParseFile(args, RelativePath(filename, args.depth, args.output_dir)) return 0 @@ -361,15 +370,15 @@ return sources_list def _VerifyImportDeps(args, __): - fileutil.EnsureDirectoryExists(args.gen_dir) + fileutil.EnsureDirectoryExists(args.output_dir) if args.filelist: with open(args.filelist) as f: args.filename.extend(f.read().split()) for filename in args.filename: - rel_path = RelativePath(filename, args.depth) - tree = _UnpickleAST(_GetPicklePath(rel_path, args.gen_dir)) + rel_path = RelativePath(filename, args.depth, args.output_dir) + tree = _UnpickleAST(_GetPicklePath(rel_path, args.output_dir)) mojom_imports = set( parsed_imp.import_filename for parsed_imp in tree.import_list @@ -378,12 +387,12 @@ sources = set() target_prefix = args.deps_file.split(".deps_sources_list")[0] - sources = GetSourcesList(target_prefix, sources, args.gen_dir) + sources = GetSourcesList(target_prefix, sources, args.output_dir) if (not sources.issuperset(mojom_imports)): target_name = target_prefix.rsplit("/", 1)[1] target_prefix_without_gen_dir = target_prefix.split( - args.gen_dir + "/", 1)[1] + args.output_dir + "/", 1)[1] full_target_name = "//" + target_prefix_without_gen_dir.rsplit( "/", 1)[0] + ":" + target_name @@ -395,7 +404,7 @@ source_filename, _ = os.path.splitext(rel_path.relative_path()) output_file = source_filename + '.v' - output_file_path = os.path.join(args.gen_dir, output_file) + output_file_path = os.path.join(args.output_dir, output_file) WriteFile("", output_file_path) return 0 @@ -405,6 +414,12 @@ description="Generate bindings from mojom files.") parser.add_argument("--use_bundled_pylibs", action="store_true", help="use Python modules bundled in the SDK") + parser.add_argument( + "-o", + "--output_dir", + dest="output_dir", + default=".", + help="output directory for generated files") subparsers = parser.add_subparsers() @@ -414,12 +429,6 @@ parse_parser.add_argument("filename", nargs="*", help="mojom input file") parse_parser.add_argument("--filelist", help="mojom input file list") parse_parser.add_argument( - "-o", - "--output_dir", - dest="output_dir", - default=".", - help="output directory for generated files") - parse_parser.add_argument( "-d", "--depth", dest="depth", default=".", help="depth from source root") parse_parser.add_argument( "--enable_feature", @@ -438,9 +447,6 @@ generate_parser.add_argument("--filelist", help="mojom input file list") generate_parser.add_argument("-d", "--depth", dest="depth", default=".", help="depth from source root") - generate_parser.add_argument("-o", "--output_dir", dest="output_dir", - default=".", - help="output directory for generated files") generate_parser.add_argument("-g", "--generators", dest="generators_string", metavar="GENERATORS", @@ -500,10 +506,13 @@ help="If set, generated bindings will serialize lazily when possible.", action="store_true") generate_parser.add_argument( - "--extra_cpp_template_paths", dest="extra_cpp_template_paths", action="append", metavar="path_to_template", - default=[], - help="Provide a path to a new template (.tmpl) that is used to generate " - "additional C++ source/header files ") + "--extra_cpp_template_paths", + dest="extra_cpp_template_paths", + action="append", + metavar="path_to_template", + default=[], + help="Provide a path to a new template (.tmpl) that is used to generate " + "additional C++ source/header files ") generate_parser.add_argument( "--disallow_native_types", help="Disallows the [Native] attribute to be specified on structs or " @@ -531,9 +540,6 @@ precompile_parser = subparsers.add_parser("precompile", description="Precompile templates for the mojom bindings generator.") - precompile_parser.add_argument( - "-o", "--output_dir", dest="output_dir", default=".", - help="output directory for precompiled templates") precompile_parser.set_defaults(func=_Precompile) verify_parser = subparsers.add_parser("verify", description="Checks " @@ -544,9 +550,6 @@ verify_parser.add_argument("-f", "--file", dest="deps_file", help="file containing paths to the sources files for " "dependencies") - verify_parser.add_argument("-g", "--gen_dir", - dest="gen_dir", - help="directory with the syntax tree") verify_parser.add_argument( "-d", "--depth", dest="depth", help="depth from source root")
diff --git a/native_client_sdk/PRESUBMIT.py b/native_client_sdk/PRESUBMIT.py index 0c9167c7..b2b4d85 100644 --- a/native_client_sdk/PRESUBMIT.py +++ b/native_client_sdk/PRESUBMIT.py
@@ -37,20 +37,3 @@ def CheckChangeOnCommit(input_api, output_api): return CommonChecks(input_api, output_api) - - -def GetPreferredTryMasters(project, change): - return { - 'master.tryserver.chromium.linux': { - 'linux_nacl_sdk': set(['defaulttests']), - 'linux_nacl_sdk_build': set(['defaulttests']), - }, - 'master.tryserver.chromium.win': { - 'win_nacl_sdk': set(['defaulttests']), - 'win_nacl_sdk_build': set(['defaulttests']), - }, - 'master.tryserver.chromium.mac': { - 'mac_nacl_sdk': set(['defaulttests']), - 'mac_nacl_sdk_build': set(['defaulttests']), - } - }
diff --git a/net/dns/context_host_resolver_unittest.cc b/net/dns/context_host_resolver_unittest.cc index e794b5ee..e50efce 100644 --- a/net/dns/context_host_resolver_unittest.cc +++ b/net/dns/context_host_resolver_unittest.cc
@@ -577,20 +577,23 @@ TEST_F(ContextHostResolverTest, ResolveFromCache) { auto resolve_context = std::make_unique<ResolveContext>( nullptr /* url_request_context */, true /* enable_caching */); + HostCache* host_cache = resolve_context->host_cache(); + auto resolver = std::make_unique<ContextHostResolver>( + manager_.get(), std::move(resolve_context)); + // Create the cache entry after creating the ContextHostResolver, as + // registering into the HostResolverManager initializes and invalidates the + // cache. base::SimpleTestTickClock clock; clock.Advance(base::TimeDelta::FromDays(62)); // Arbitrary non-zero time. AddressList expected(kEndpoint); - resolve_context->host_cache()->Set( + host_cache->Set( HostCache::Key("example.com", DnsQueryType::UNSPECIFIED, 0 /* host_resolver_flags */, HostResolverSource::ANY, NetworkIsolationKey()), HostCache::Entry(OK, expected, HostCache::Entry::SOURCE_DNS, base::TimeDelta::FromDays(1)), clock.NowTicks(), base::TimeDelta::FromDays(1)); - - auto resolver = std::make_unique<ContextHostResolver>( - manager_.get(), std::move(resolve_context)); resolver->SetTickClockForTesting(&clock); // Allow stale results and then confirm the result is not stale in order to @@ -715,14 +718,16 @@ auto resolver = std::make_unique<ContextHostResolver>( manager_.get(), std::move(resolve_context)); - // No invalidations yet. - ASSERT_EQ(resolve_context_ptr->current_session_for_testing(), nullptr); - ASSERT_EQ(resolve_context_ptr->host_cache()->network_changes(), 0); + // No invalidations yet (other than the initialization "invalidation" from + // registering the context). + ASSERT_EQ(resolve_context_ptr->current_session_for_testing(), + dns_client_->GetCurrentSession()); + ASSERT_EQ(resolve_context_ptr->host_cache()->network_changes(), 1); manager_->InvalidateCachesForTesting(); EXPECT_EQ(resolve_context_ptr->current_session_for_testing(), dns_client_->GetCurrentSession()); - EXPECT_EQ(resolve_context_ptr->host_cache()->network_changes(), 1); + EXPECT_EQ(resolve_context_ptr->host_cache()->network_changes(), 2); // Expect manager to be able to safely do invalidations after an individual // ContextHostResolver has been destroyed (and deregisters its ResolveContext)
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc index 8a8fd414..08cf9a4 100644 --- a/net/dns/host_resolver_manager.cc +++ b/net/dns/host_resolver_manager.cc
@@ -2863,6 +2863,8 @@ void HostResolverManager::RegisterResolveContext(ResolveContext* context) { registered_contexts_.AddObserver(context); + context->InvalidateCaches(dns_client_ ? dns_client_->GetCurrentSession() + : nullptr); } void HostResolverManager::DeregisterResolveContext(
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc index 533dca4..5329602 100644 --- a/net/dns/host_resolver_manager_unittest.cc +++ b/net/dns/host_resolver_manager_unittest.cc
@@ -9074,6 +9074,78 @@ c1.keys_for_addresses()); } +// Test that a newly-registered ResolveContext is immediately usable with a DNS +// configuration loaded before the context registration. +TEST_F(HostResolverManagerDnsTest, + NewlyRegisteredContext_ConfigBeforeRegistration) { + ResolveContext context(nullptr /* url_request_context */, + true /* enable_caching */); + set_allow_fallback_to_proctask(false); + ChangeDnsConfig(CreateValidDnsConfig()); + DnsConfigOverrides overrides; + overrides.secure_dns_mode = DnsConfig::SecureDnsMode::SECURE; + resolver_->SetDnsConfigOverrides(overrides); + + ASSERT_TRUE(dns_client_->GetCurrentSession()); + + resolver_->RegisterResolveContext(&context); + EXPECT_EQ(context.current_session_for_testing(), + dns_client_->GetCurrentSession()); + + // Test a SECURE-mode DoH request with SetForceDohServerAvailable(false). + // Should only succeed if a DoH server is marked available in the + // ResolveContext. MockDnsClient skips most other interaction with + // ResolveContext. + dns_client_->SetForceDohServerAvailable(false); + context.SetProbeSuccess(0u /* doh_server_index */, true /* success */, + dns_client_->GetCurrentSession()); + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("secure", 80), NetworkIsolationKey(), NetLogWithSource(), + base::nullopt, &context, context.host_cache())); + EXPECT_THAT(response.result_error(), IsOk()); + + resolver_->DeregisterResolveContext(&context); +} + +// Test interaction with a ResolveContext registered before a DNS config is +// ready. +TEST_F(HostResolverManagerDnsTest, + NewlyRegisteredContext_NoConfigAtRegistration) { + ResolveContext context(nullptr /* url_request_context */, + true /* enable_caching */); + set_allow_fallback_to_proctask(false); + InvalidateDnsConfig(); + DnsConfigOverrides overrides; + overrides.secure_dns_mode = DnsConfig::SecureDnsMode::SECURE; + resolver_->SetDnsConfigOverrides(overrides); + + ASSERT_FALSE(dns_client_->GetCurrentSession()); + + // Register context before loading a DNS config. + resolver_->RegisterResolveContext(&context); + EXPECT_FALSE(context.current_session_for_testing()); + + // Load DNS config and expect the session to be loaded into the ResolveContext + ChangeDnsConfig(CreateValidDnsConfig()); + ASSERT_TRUE(dns_client_->GetCurrentSession()); + EXPECT_EQ(context.current_session_for_testing(), + dns_client_->GetCurrentSession()); + + // Test a SECURE-mode DoH request with SetForceDohServerAvailable(false). + // Should only succeed if a DoH server is marked available in the + // ResolveContext. MockDnsClient skips most other interaction with + // ResolveContext. + dns_client_->SetForceDohServerAvailable(false); + context.SetProbeSuccess(0u /* doh_server_index */, true /* success */, + dns_client_->GetCurrentSession()); + ResolveHostResponseHelper response(resolver_->CreateRequest( + HostPortPair("secure", 80), NetworkIsolationKey(), NetLogWithSource(), + base::nullopt, &context, context.host_cache())); + EXPECT_THAT(response.result_error(), IsOk()); + + resolver_->DeregisterResolveContext(&context); +} + class HostResolverManagerEsniTest : public HostResolverManagerDnsTest { public: HostResolverManagerEsniTest()
diff --git a/net/quic/OWNERS b/net/quic/OWNERS index 6fd222f..9027f5a 100644 --- a/net/quic/OWNERS +++ b/net/quic/OWNERS
@@ -1,3 +1,4 @@ +dschinazi@chromium.org nharper@chromium.org rch@chromium.org zhongyi@chromium.org
diff --git a/printing/common/metafile_utils.cc b/printing/common/metafile_utils.cc index a603f8b..66945f8 100644 --- a/printing/common/metafile_utils.cc +++ b/printing/common/metafile_utils.cc
@@ -100,14 +100,13 @@ tag->fType = SkPDF::DocumentStructureType::kNonStruct; } - tag->fChildCount = ax_node->GetUnignoredChildCount(); - // Allocated here, cleaned up in DestroyStructureElementNodeTree(). - SkPDF::StructureElementNode* children = - new SkPDF::StructureElementNode[tag->fChildCount]; - tag->fChildren = children; - for (size_t i = 0; i < tag->fChildCount; i++) { + size_t children_count = ax_node->GetUnignoredChildCount(); + tag->fChildVector.resize(children_count); + for (size_t i = 0; i < children_count; i++) { + tag->fChildVector[i] = std::make_unique<SkPDF::StructureElementNode>(); bool success = RecursiveBuildStructureTree( - ax_node->GetUnignoredChildAtIndex(i), &children[i]); + ax_node->GetUnignoredChildAtIndex(i), tag->fChildVector[i].get()); + if (success) valid = true; } @@ -115,14 +114,6 @@ return valid; } -void DestroyStructureElementNodeTree(SkPDF::StructureElementNode* node) { - for (size_t i = 0; i < node->fChildCount; i++) { - DestroyStructureElementNodeTree( - const_cast<SkPDF::StructureElementNode*>(&node->fChildren[i])); - } - delete[] node->fChildren; -} - } // namespace namespace printing { @@ -146,9 +137,7 @@ metadata.fStructureElementTreeRoot = &tag_root; } - sk_sp<SkDocument> document = SkPDF::MakeDocument(stream, metadata); - DestroyStructureElementNodeTree(&tag_root); - return document; + return SkPDF::MakeDocument(stream, metadata); } sk_sp<SkData> SerializeOopPicture(SkPicture* pic, void* ctx) {
diff --git a/remoting/resources/remoting_strings.grd b/remoting/resources/remoting_strings.grd index 407dce6..fefa9cea 100644 --- a/remoting/resources/remoting_strings.grd +++ b/remoting/resources/remoting_strings.grd
@@ -303,66 +303,15 @@ </message> </if> <!-- is_android or is_ios --> - <message desc="Message shown when the Chrome Remote Desktop client tab is closed while a connection is active." name="IDS_CLOSE_PROMPT"> - Leaving this page will end your Chrome Remote Desktop session. - </message> - <message desc="Confirmation prompt shown when a user needs to authenticate against a third party, explaining the need to authorize the Chrome Remote Desktop app to access the authentication URL." name="IDS_DESCRIPTION_THIRD_PARTY_AUTH"> - The remote host requires you to authenticate to a third-party website. To continue, you must grant Chrome Remote Desktop additional permissions to access this address: - </message> - <message desc="Description for the home screen. This is shown when the app starts up, above buttons to share or connect." name="IDS_DESCRIPTION_HOME"> - Chrome Remote Desktop allows you to securely share your computer over the Web. Both users must be running the Chrome Remote Desktop app, which can be found at <ph name="URL">$1<ex><a href=http://chrome.google.com/remotedesktop>chrome.google.com/remotedesktop</a></ex></ph>. - </message> <message desc="Error displayed if authentication fails. This can be caused by stale credentials, in which logging out of the web-app and retrying can fix the problem." name="IDS_ERROR_AUTHENTICATION_FAILED" formatter_data="android_java"> Authentication failed. Please sign in to Chrome again. </message> - <message desc="Error displayed when the computer has a policy that only users in a particular domain may use it as a Chrome Remote Desktop host, but a user in a different domain is trying to use it as a Chrome Remote Desktop host. The Chrome Remote Desktop host allows a user to connect to their computer remotely (it 'hosts' a connection from a remote computer)." name="IDS_ERROR_INVALID_HOST_DOMAIN"> - Policy settings do not permit sharing this computer as a Chrome Remote Desktop host. Contact your system administrator for assistance. - </message> - <message desc="Error displayed when an operation is attempted that requires a signed-in user, but no-one is currently signed in." name="IDS_ERROR_NOT_AUTHENTICATED"> - You are not signed in to Chrome. Please sign in and try again. - </message> - <message desc="Message displayed when the current computer is accepting remote connections." name="IDS_HOME_DAEMON_ACTIVE_MESSAGE"> - You may securely access this computer using Chrome Remote Desktop. - </message> - <message desc="Message displayed when the current computer is not accepting remote connections, instructing the user how to enable them." name="IDS_HOME_DAEMON_START_MESSAGE"> - You must enable remote connections if you want to use Chrome Remote Desktop to access this computer. - </message> - <message desc="Message displayed to the user if there are no hosts registered to their account, informing them how to set up a host on another computer." name="IDS_HOST_LIST_EMPTY_HOSTING_SUPPORTED"> - To enable remote connections to a different computer, install Chrome Remote Desktop there and click “<ph name="BUTTON_NAME">$1<ex>Enable remote connections</ex></ph>”. - </message> - <message desc="Message displayed to the user if there are no hosts registered to their account, informing them how to set up a host on another computer." name="IDS_HOST_LIST_EMPTY_HOSTING_UNSUPPORTED"> - You have no computers registered. To enable remote connections to a computer, install Chrome Remote Desktop there and click “<ph name="BUTTON_NAME">$1<ex>Enable remote connections</ex></ph>”. - </message> - <message desc="Message displayed to the user if there are no hosts registered to their account. If the user has previously signed-in to the v1 app with an account other than their profile, they will lose access to all their hosts once they upgrade to the v2 app. This message informs them to sign in to the chrome with that account and re-install Chromoting." name="IDS_HOST_LIST_EMPTY_V2_MIGRATION"> - You have previously signed in as <ph name="USER_NAME">$1<ex>John Doe</ex></ph> (<ph name="USER_EMAIL">$2<ex>john.doe@gmail.com</ex></ph>). To access your computers in that account, <ph name="LINK_BEGIN">$3<ex><a href="https://support.google.com/chrome/answer/2364824?hl=en"></ex></ph>sign in to Google Chrome<ph name="LINK_END">$4<ex></a></ex></ph> with that account and re-install Chrome Remote Desktop. - </message> - <message desc="Message displayed next to the checkbox that the user can select to allow crash dump collection and reporting." name="IDS_HOST_SETUP_CRASH_REPORTING_MESSAGE"> - Help us improve Chrome Remote Desktop by allowing us to collect usage statistics and crash reports. - </message> - <message desc="Title of the dialog used to download and install the Chrome Remote Desktop host component. The Chrome Remote Desktop host allows a user to connect to their computer remotely (it 'hosts' a connection from a remote computer)." name="IDS_INSTALLER_DOWNLOAD"> - Download Chrome Remote Desktop Host Installer - </message> - <message desc="Message shown to inform the user that the product is governed by Google's terms of service and to include a link to view them. The Chrome Remote Desktop host allows a user to connect to their computer remotely (it 'hosts' a connection from a remote computer)." name="IDS_HOST_SETUP_TERMS_OF_SERVICE"> - By downloading the Chrome Remote Desktop Host Installer, you are agreeing to the Google <ph name="LINK_BEGIN">$1<ex><a href="http://www.google.com/intl/en/policies/terms"></ex></ph>Terms of Service<ph name="LINK_END">$4<ex></a></ex></ph>. - </message> - <message desc="Message shown when user is asked to manually install the Host components. The Chrome Remote Desktop host allows a user to connect to their computer remotely (it 'hosts' a connection from a remote computer)." name="IDS_HOST_SETUP_INSTALL"> - Chrome is downloading the Chrome Remote Desktop Host installer. Once the download is complete, please run the installer before continuing. - </message> <message desc="Message displayed when the client or host has disconnected." name="IDS_MESSAGE_SESSION_FINISHED"> Your Chrome Remote Desktop session has ended. </message> <message desc="The product name. Displayed in various Chrome pages, including the New Tab page, and displayed prominently on the app's main page." name="IDS_PRODUCT_NAME"> Chrome Remote Desktop </message> - <message desc="The product name. Displayed in various Chrome pages, including the New Tab page, and displayed prominently on the app's main page." name="IDS_PRODUCT_NAME_APP_STREAMING"> - Chrome App Streaming - </message> - <message desc="Message displayed at the bottom of the client connect dialog if Chrome Remote Desktop is running in the wrong start-up mode." name="IDS_WARNING_NOT_WINDOWED"> - NOTE: To ensure that all keyboard shortcuts are available, you can configure Chrome Remote Desktop to ‘Open as window’. - </message> - <message desc="Error message displayed if the user tries to connect to a computer running out-of-date Me2Me host software." name="IDS_HOST_NEEDS_UPDATE_TITLE"> - Chrome Remote Desktop on <ph name="HOSTNAME">$1<ex>My Linux desktop</ex></ph> is out-of-date and needs to be updated. - </message> <message name="IDS_COMPANY_NAME" desc="The company name specified in the version information of each Chrome Remote Desktop Host executable."> Google Inc. </message> @@ -375,18 +324,9 @@ <message name="IDS_SERVICE_DESCRIPTION" desc="The description of the Windows service installed by Chrome Remote Desktop."> This service enables incoming connections from Chrome Remote Desktop clients. </message> - <message name="IDS_CONTROLLER_NAME" desc="The name of the component to be elevated shown on the UAC prompt when enabling or disabling Chrome Remote Desktop Host. The Chrome Remote Desktop host allows a user to connect to their computer remotely (it 'hosts' a connection from a remote computer)."> - Chrome Remote Desktop Host Controller - </message> - <message name="IDS_VERIFY_PIN_DIALOG_MESSAGE" desc="The message displayed by the PIN verification dialog."> - Please confirm your account and PIN below to allow access by Chrome Remote Desktop. - </message> <message name="IDS_MAC_UNINSTALLER_BUNDLE_NAME" desc="The bundle name specified in the property list of Chrome Remote Desktop Host Uninstaller bundle on MacOS. The Chrome Remote Desktop host allows a user to connect to their computer remotely (it 'hosts' a connection from a remote computer)."> Chrome Remote Desktop Host Uninstaller </message> - <message desc="Error displayed when the local computer is configured badly." name="IDS_ERROR_POLICY"> - There is an error with the policy settings for Chrome Remote Desktop. Contact your system administrator for assistance. - </message> </if> <!-- _google_chrome --> <if expr="not _google_chrome"> @@ -402,66 +342,15 @@ </message> </if> <!-- is_android or is_ios --> - <message desc="Message shown when the Chromoting client tab is closed while a connection is active." name="IDS_CLOSE_PROMPT"> - Leaving this page will end your Chromoting session. - </message> - <message desc="Confirmation prompt shown when a user needs to authenticate against a third party, explaining the need to authorize the Chromoting app to access the authentication URL." name="IDS_DESCRIPTION_THIRD_PARTY_AUTH"> - The remote host requires you to authenticate to a third-party website. To continue, you must grant Chromoting additional permissions to access this address: - </message> - <message desc="Description for the home screen. This is shown when the app starts up, above buttons to share or connect." name="IDS_DESCRIPTION_HOME"> - Chromoting allows you to securely share your computer over the Web. Both users must be running the Chromoting app, which can be found at <ph name="URL">$1<ex><a href=http://chrome.google.com/remotedesktop>chrome.google.com/remotedesktop</a></ex></ph>. - </message> <message desc="Error displayed if authentication fails. This can be caused by stale credentials, in which logging out of the web-app and retrying can fix the problem." name="IDS_ERROR_AUTHENTICATION_FAILED" formatter_data="android_java"> Authentication failed. Please sign in to Chromium again. </message> - <message desc="Error displayed when the computer has a policy that only users in a particular domain may use it as a Chromoting host, but a user in a different domain is trying to use it as a Chromoting host. The Chromoting host allows a user to connect to their computer remotely (it 'hosts' a connection from a remote computer)." name="IDS_ERROR_INVALID_HOST_DOMAIN"> - Policy settings do not permit sharing this computer as a Chromoting host. Contact your system administrator for assistance. - </message> - <message desc="Error displayed when an operation is attempted that requires a signed-in user, but no-one is currently signed in." name="IDS_ERROR_NOT_AUTHENTICATED"> - You are not signed in to Chromium. Please sign in and try again. - </message> - <message desc="Message displayed when the current computer is accepting remote connections." name="IDS_HOME_DAEMON_ACTIVE_MESSAGE"> - You may securely access this computer using Chromoting. - </message> - <message desc="Message displayed when the current computer is not accepting remote connections, instructing the user how to enable them." name="IDS_HOME_DAEMON_START_MESSAGE"> - You must enable remote connections if you want to use Chromoting to access this computer. - </message> - <message desc="Message displayed to the user if there are no hosts registered to their account, informing them how to set up a host on another computer." name="IDS_HOST_LIST_EMPTY_HOSTING_SUPPORTED"> - To enable remote connections to a different computer, install Chromoting there and click “<ph name="BUTTON_NAME">$1<ex>Enable remote connections</ex></ph>”. - </message> - <message desc="Message displayed to the user if there are no hosts registered to their account, informing them how to set up a host on another computer." name="IDS_HOST_LIST_EMPTY_HOSTING_UNSUPPORTED"> - You have no computers registered. To enable remote connections to a computer, install Chromoting there and click “<ph name="BUTTON_NAME">$1<ex>Enable remote connections</ex></ph>”. - </message> - <message desc="Message displayed to the user if there are no hosts registered to their account. If the user has previously signed-in to the v1 app with an account other than their profile, they will lose access to all their hosts once they upgrade to the v2 app. This message informs them to sign in to the chrome with that account and re-install Chromoting." name="IDS_HOST_LIST_EMPTY_V2_MIGRATION"> - You have previously signed in as <ph name="USER_NAME">$1<ex>John Doe</ex></ph> (<ph name="USER_EMAIL">$2<ex>john.doe@gmail.com</ex></ph>). To access your computers in that account, <ph name="LINK_BEGIN">$3<ex><a href="https://support.google.com/chrome/answer/2364824?hl=en"></ex></ph>sign in to Chromium<ph name="LINK_END">$4<ex></a></ex></ph> with that account and re-install Chromoting. - </message> - <message desc="Message displayed next to the checkbox that the user can select to allow crash dump collection and reporting." name="IDS_HOST_SETUP_CRASH_REPORTING_MESSAGE"> - Help us improve Chromoting by allowing us to collect usage statistics and crash reports. - </message> - <message desc="Title of the dialog used to download and install the Chromoting host component. The Chromoting host allows a user to connect to their computer remotely (it 'hosts' a connection from a remote computer)." name="IDS_INSTALLER_DOWNLOAD"> - Download Chromoting Host Installer - </message> - <message desc="Message shown to inform the user that the product is governed by Google's terms of service and to include a link to view them." name="IDS_HOST_SETUP_TERMS_OF_SERVICE"> - By downloading the Chromoting Host Installer, you are agreeing to the Google <ph name="LINK_BEGIN">$1<ex><a href="http://www.google.com/intl/en/policies/terms"></ex></ph>Terms of Service<ph name="LINK_END">$4<ex></a></ex></ph>. - </message> - <message desc="Message shown when user is asked to manually install the Host components." name="IDS_HOST_SETUP_INSTALL"> - Chrome is downloading the Chromoting Host installer. Once the download is complete, please run the installer before continuing. - </message> <message desc="Message displayed when the client or host has disconnected." name="IDS_MESSAGE_SESSION_FINISHED"> Your Chromoting session has ended. </message> <message desc="The product name. Displayed in various Chrome pages, including the New Tab page, and displayed prominently on the app's main page." name="IDS_PRODUCT_NAME"> Chromoting </message> - <message desc="The product name. Displayed in various Chrome pages, including the New Tab page, and displayed prominently on the app's main page." name="IDS_PRODUCT_NAME_APP_STREAMING"> - Chromium App Streaming - </message> - <message desc="Message displayed at the bottom of the client connect dialog if Chromoting is running in the wrong start-up mode." name="IDS_WARNING_NOT_WINDOWED"> - NOTE: To ensure that all keyboard shortcuts are available, you can configure Chromoting to ‘Open as window’. - </message> - <message desc="Error message displayed if the user tries to connect to a computer running out-of-date Me2Me host software." name="IDS_HOST_NEEDS_UPDATE_TITLE"> - Chromoting on <ph name="HOSTNAME">$1<ex>My Linux desktop</ex></ph> is out-of-date and needs to be updated. - </message> <message name="IDS_COMPANY_NAME" desc="The company name specified in the version information of each Chromoting Host executable."> The Chromium Authors </message> @@ -474,141 +363,26 @@ <message name="IDS_SERVICE_DESCRIPTION" desc="The description of the Windows service installed by Chromoting."> This service enables incoming connections from Chromoting clients. </message> - <message name="IDS_CONTROLLER_NAME" desc="The name of the component to be elevated shown on the UAC prompt when enabling or disabling Chromoting Host."> - Chromoting Host Controller - </message> - <message name="IDS_VERIFY_PIN_DIALOG_MESSAGE" desc="The message displayed by the PIN verification dialog."> - Please confirm your account and PIN below to allow access by Chromoting. - </message> <message name="IDS_MAC_UNINSTALLER_BUNDLE_NAME" desc="The bundle name specified in the property list of Chromoting Host Uninstaller bundle on MacOS."> Chromoting Host Uninstaller </message> - <message desc="Error displayed when the local computer is configured badly." name="IDS_ERROR_POLICY"> - There is an error with the policy settings for Chrome Remote Desktop. Contact your system administrator for assistance. - </message> </if> <!-- not _google_chrome --> <message desc="Error that is shown on the client side when incompatible Chrome Remote Desktop versions are installed on host and client." name="IDS_ERROR_INCOMPATIBLE_PROTOCOL" formatter_data="android_java"> An incompatible protocol version was detected. Please make sure that you have the latest version of the software installed on both computers and try again. </message> - <message desc="Text shown when the app first starts, or if the access token is invalidated, explaining the need to authorize the Chromoting app before use." name="IDS_DESCRIPTION_AUTHORIZE"> - To continue you must first grant extended access permissions to your computer. You only have to do this once. - </message> <message desc="Error displayed if the client plugin are missing or if they could not be loaded." name="IDS_ERROR_BAD_PLUGIN_VERSION"> Some required components are missing. Please make sure you have installed the latest version of the software and try again. </message> - <message desc="Error displayed if the client plugin fails to load." name="IDS_ERROR_MISSING_PLUGIN"> - Some required components are missing. Please make sure you're running the latest version of Chrome and try again. - </message> - <message desc="Error displayed if the client plugin crashes." name="IDS_ERROR_NACL_PLUGIN_CRASHED"> - A required component has stopped working. Please report this problem to the developers. - </message> - <message desc="Error displayed if Native Client is not enabled." name="IDS_ERROR_NACL_DISABLED"> - Some required components are missing. Please go to chrome://plugins and make sure Native Client is enabled. - </message> - <message desc="Message shown if the user is not authorized to perform the requested action." name="IDS_ERROR_NOT_AUTHORIZED"> - You do not have permission to perform that action. - </message> <message desc="Message shown if the user is is trying to modify an object that does not exist." name="IDS_ERROR_NOT_FOUND"> The requested object does not exist. </message> - <!-- The following strings are AppRemoting-specific --> - <message desc="Message shown if the user is not authorized to run the app." name="IDS_ERROR_APP_NOT_AUTHORIZED"> - You do not have permission to run this application. - </message> - <message desc="Menu option to toggle the debugging stats." name="IDS_SHOW_STATS"> - Show statistics - </message> - <message desc="Menu option to toggle the debugging stats, including a summary of the current connection quality." name="IDS_SHOW_STATS_WITH_RTT"> - Show statistics (connection: <ph name="QUALITY">$1<ex>Good</ex></ph>) - </message> - <message desc="Indicates a 'good' quality connection." name="IDS_CONNECTION_QUALITY_GOOD"> - Good - </message> - <message desc="Indicates a 'fair' quality connection." name="IDS_CONNECTION_QUALITY_FAIR"> - Fair - </message> - <message desc="Indicates a 'poor' quality connection." name="IDS_CONNECTION_QUALITY_POOR"> - Poor - </message> <message desc="Menu option to submit feedback about the product." name="IDS_SEND_FEEDBACK"> Report an issue… </message> - <message desc="Title for the dialog prompting the user to consent to their email address being included as part of their feedback." name="IDS_FEEDBACK_CONSENT_TITLE"> - Report an issue - </message> - <message desc="Text asking the user for consent to their email address being included as part of their feedback." name="IDS_FEEDBACK_CONSENT_EMAIL"> - To allow us to contact you for further information, your email address will be included in any feedback you submit. - </message> - <message desc="Text asking the user to choose a category for their feedback." name="IDS_FEEDBACK_CATEGORY_INSTRUCTIONS"> - To help us solve your problem, please tell us what went wrong: - </message> - <message desc="The initial 'category', indicating that the user must select something to continue." name="IDS_FEEDBACK_CATEGORY_SELECT"> - Select… - </message> - <message desc="Category indicating that the user is having problems launching the application." name="IDS_FEEDBACK_CATEGORY_APP_LAUNCH"> - I can't open the application. - </message> - <message desc="Category indicating that the application is running too slowly." name="IDS_FEEDBACK_CATEGORY_APP_PERFORMANCE"> - The application is too slow. - </message> - <message desc="Category indicating that the user is having keyboard or mouse issues." name="IDS_FEEDBACK_CATEGORY_INPUT"> - I'm having problems with my keyboard or mouse. - </message> - <message desc="Category indicating that the user is having problems with Google Drive not uploading their files." name="IDS_FEEDBACK_CATEGORY_DRIVE_UPLOAD"> - I can't see my saved files on-line in Google Drive. - </message> - <message desc="Category indicating that the user is having problems with Google Drive not downloading their files." name="IDS_FEEDBACK_CATEGORY_DRIVE_DOWNLOAD"> - I can't open my Google Drive files. - </message> - <message desc="Category indicating that the user is having a problem not covered by any of the common categories." name="IDS_FEEDBACK_CATEGORY_OTHER"> - Something else. - </message> - <message desc="Title for the submenu item containing a list of windows opened by the remote app." name="IDS_WINDOWS_SUBMENU_TITLE"> - Windows - </message> - <message desc="Checkbox allowing the user to request that their virtual machine be rebooted if it becomes unconnectable." name="IDS_FEEDBACK_ABANDON_HOST"> - Reset the application. You will lose any unsaved work. - </message> - <message desc="Checkbox allowing the user to request that logs be included in their feedback." name="IDS_FEEDBACK_INCLUDE_LOGS"> - Include application logs to help us resolve your problem (logs may include private information). - </message> - <message desc="Link allowing the user to get additional information." name="IDS_LEARN_MORE"> - Learn more. - </message> - <message desc="Detailed privacy information for the feedback feature." name="IDS_FEEDBACK_PRIVACY_INFORMATION1"> - Application logs may include private information, including your identity (email address) and the names and properties of files and folders in Google Drive. - </message> - <message desc="Detailed privacy information for the feedback feature." name="IDS_FEEDBACK_PRIVACY_INFORMATION2"> - This information is used only for diagnosing the problem you are reporting, is available only to someone investigating your report, and is retained for no more than 30 days. - </message> - <message desc="Error message displayed if the reset attempt fails." name="IDS_FEEDBACK_ABANDON_FAILED"> - Could not reset the application. You can still send a bug report. - </message> - <message desc="Title for the submenu item containing a list of windows opened by the remote app." name="IDS_KEYBOARD_LAYOUTS_SUBMENU_TITLE"> - Keyboard layouts - </message> <message desc="Title for the connection error dialog." name="IDS_CONNECTION_FAILED"> Connection failed </message> - <message desc="Warning shown if the platform does not support transparency." name="IDS_NO_TRANSPARENCY_WARNING"> - Desktop integration is not supported on this platform. You can still use the application, but the user experience will be degraded. - </message> - <message desc="Message shown if the user has been idle for a long time, informing them that their session will be disconnected shortly." name="IDS_IDLE_TIMEOUT_WARNING"> - Your <ph name="APPLICATION_NAME">$1<ex>SampleApp Streaming</ex></ph> session has been inactive for a while and will be disconnected shortly. - </message> - <message desc="Button to allow the user to indicate that they are still using the service" name="IDS_IDLE_CONTINUE"> - Continue - </message> - <message desc="Button to allow the user to indicate that they are no longer using the service." name="IDS_IDLE_DISCONNECT"> - Disconnect now - </message> - <message desc="Button to restart the app after the connection is dropped." name="IDS_RESTART_BUTTON"> - Restart now - </message> - <message desc="Message show to the user when the connection is dropped." name="IDS_ERROR_CONNECTION_DROPPED"> - A network error occurred. We will restart the app when your device is on-line again. - </message> <if expr="is_android or is_ios"> <message desc="Button to show or hide the on-screen keyboard." name="IDS_SHOW_HIDE_KEYBOARD" formatter_data="android_java"> @@ -662,24 +436,12 @@ <message desc="Text shown in tooltip when user touches an offline host on the device." name="IDS_HOST_OFFLINE_TOOLTIP" formatter_data="android_java"> Host is offline. </message> - <message name="IDS_MOBILE_NETWORK_WARNING" desc="Message shown in an alert dialog that warns the user that they are trying to connect to a device over mobile network."> - Data charges may apply when connecting to a device over mobile network. Do you want to continue? - </message> <message name="IDS_THIRD_PARTY_AUTH_NOT_SUPPORTED" desc="Error message shown when the user attempts to connect to a remote device under third party authentication, which is currently unsupported by the client."> This device is not supported by this client because it requires third party authentication. </message> <message name="IDS_REPORT_THIS" desc="Label text for a button to report a connection failure to the developers."> Report this </message> - <message name="IDS_IOS_PHOTO_LIBRARY_USAGE_DESCRIPTION" desc="Message shown when the app requests permission to access the user's photo library."> - To choose a profile picture, allow Chrome Remote Desktop to access your photos - </message> - <message name="IDS_IOS_CAMERA_USAGE_DESCRIPTION" desc="Message shown when the app requests permission to use the camera of the device."> - To choose a profile picture, allow Chrome Remote Desktop to access your camera - </message> - <message name="IDS_SERVER_COMMUNICATION_ERROR" desc="Message shown when the client fails to communicate with the back end server."> - Failed to communicate with the server: <ph name="ERROR">$1<ex>Server Unavailable</ex></ph> - </message> <message name="IDS_TERMS_OF_SERVICE" desc="The label to access the terms of service, displayed in navigation menu." formatter_data="android_java"> Terms of Service </message> @@ -757,9 +519,6 @@ <message desc="Title for the button that brings up the frequently asked questions page." name="IDS_FAQS"> FAQs </message> - <message desc="Subtitle (description) of the option controlling whether or not the remote desktop is scaled down if it is too large to fit in the window." name="IDS_SHRINK_TO_FIT_SUBTITLE"> - Keep whole remote desktop visible - </message> <message desc="Subtitle (description) of the option controlling whether or not the remote desktop is resized to match the window size as closely as possible." name="IDS_RESIZE_TO_CLIENT_SUBTITLE"> Update remote resolution to match window </message> @@ -792,66 +551,33 @@ <message desc="Label for the access code entry box. This is where the client user enters the code that permits access to the host." name="IDS_ACCESS_CODE"> Access code </message> - <message desc="Text displayed when the access code is due to time out within 30 seconds." name="IDS_ACCESS_CODE_TIMER"> - This access code will expire in <ph name="TIMEOUT">$1<ex>0:30</ex></ph> - </message> - <message desc="In the connection history dialog, clicking this button shows all recent connections unfiltered." name="IDS_ALL_CONNECTIONS"> - All connections - </message> <message desc="Label next to the PIN entry edit box. The user must enter a PIN before enabling remote access to their computer." name="IDS_ASK_PIN_DIALOG_LABEL"> PIN </message> - <message desc="Label next to the PIN confirmation edit box. The user must enter a PIN before enabling remote access to their computer." name="IDS_ASK_PIN_DIALOG_CONFIRM_LABEL"> - Re-type PIN - </message> <message desc="Label for general-purpose Cancel buttons." name="IDS_CANCEL" formatter_data="android_java"> Cancel </message> - <message desc="In the connection history dialog, clicking this button will delete the connection history." name="IDS_CLEAR_HISTORY"> - Clear history - </message> <message desc="Label for general-purpose Close buttons." name="IDS_CLOSE" formatter_data="android_java"> Close </message> <message desc="Label for the connect button. Clicking this button will start the Chrome Remote Desktop session if the access code is correct." name="IDS_CONNECT_BUTTON" formatter_data="android_java"> Connect </message> - <message desc="Label for the connect button for hosts running an out-of-date version of the Me2Me host software. The user clicks this button to acknowledge the message but continue with the connection anyway." name="IDS_CONNECT_ANYWAY"> - Connect anyway - </message> <message desc="Confirmation prompt shown when a user attempts to delete a Me2Me host from their host list." name="IDS_CONFIRM_HOST_DELETE"> Are you sure you want to disable remote connections to <ph name="HOSTNAME">$1<ex>My Linux desktop</ex></ph>? If you change your mind, you'll need to visit that computer to re-enable connections. </message> <message desc="Confirmation prompt shown when a user attempts remove or deactivate a machine from the list of their remotely-accessible machines." name="IDS_CONFIRM_HOST_DELETE_ANDROID" formatter_data="android_java"> Are you sure you want to disable remote connections to <ph name="HOSTNAME">%1$s<ex>My Linux desktop</ex></ph>? </message> - <message desc="Column header in the connection history table showing the email address of the client end of the connection (the initiator) which may be this or another computer." name="IDS_CONNECTION_FROM_HEADER"> - From - </message> - <message desc="Title for the connection history dialog. This dialog shows recent connections made to and from this computer" name="IDS_CONNECTION_HISTORY_TITLE"> - Connection History - </message> - <message desc="Column header in the connection history table showing the email address of the host end of the connection (the connectee) which may be this or another computer." name="IDS_CONNECTION_TO_HEADER"> - To - </message> <message desc="Label for the continue button on the pre-authorization page. Clicking this button takes the user to the standard Google Accounts authorization page." name="IDS_CONTINUE_BUTTON"> Continue </message> <message desc="Message displayed when the session has lasted longer than five minutes, explaining that the host computer is being shared and asking whether or not the user wants to continue sharing it." name="IDS_CONTINUE_PROMPT"> You are currently sharing this machine with another user. Do you want to continue sharing? </message> - <message desc="Description for the client app. This is shown to the client user above the access code entry box before the connection is started. Note that the 'Share Now' quote should be copied verbatim from the corresponding translation." name="IDS_DESCRIPTION_CONNECT"> - Ask the user whose computer you wish to access to click “<ph name="SHARE">$1<ex>Share</ex></ph>” and give you the access code. - </message> - <message desc="Label for the 'yes' response to the dialog asking the user to confirm whether or not they want to disable remote access to a host." name="IDS_DISABLE_HOST"> - Disable - </message> <message desc="Label for the client-side disconnect button. Clicking this button disconnects oneself from the host." name="IDS_DISCONNECT_MYSELF_BUTTON" formatter_data="android_java"> Disconnect </message> - <message desc="Column header in the connection history table showing the length of time for which a connection was active, if available." name="IDS_DURATION_HEADER"> - Duration - </message> <message desc="Error that is shown on the client side when the host is blocking all connections due to failed authentication attempts." name="IDS_ERROR_HOST_OVERLOAD" formatter_data="android_java"> Connections to the remote computer are temporarily blocked because somebody was trying to connect to it with an invalid PIN. Please try again later. </message> @@ -877,9 +603,6 @@ <message desc="Error displayed when the host is online, but we are unable to connect to it due to network configuration." name="IDS_ERROR_NETWORK_FAILURE"> Could not connect to the network. Please check that your device is on-line. </message> - <message desc="Error displayed when the service returns a 503 error. Such errors are usually temporary, and resolve themselves in about 30 seconds." name="IDS_ERROR_SERVICE_UNAVAILABLE"> - The service is temporarily unavailable. Please try again later. - </message> <message desc="Error displayed when the user's oauth token is invalid." name="IDS_ERROR_OAUTH_TOKEN_INVALID"> There was an issue authenticating, please login again. </message> @@ -889,138 +612,18 @@ <message desc="Text displayed while a client is connecting to a host, but before the connection is established." name="IDS_FOOTER_CONNECTING" formatter_data="android_java"> Connecting… </message> - <message desc="Footer text displayed at the host after an access code has been generated, but before a client connects." name="IDS_FOOTER_WAITING"> - waiting for connection… - </message> <message desc="Menu option for toggle full-screen mode." name="IDS_FULL_SCREEN" formatter_data="android_java"> Full screen </message> - <message desc="Icon to leave full-screen mode." name="IDS_EXIT_FULL_SCREEN"> - Exit full screen - </message> - <message desc="Tool-tip for the window's close icon." name="IDS_CLOSE_WINDOW"> - Close window - </message> - <message desc="Tool-tip for the window's maximize icon." name="IDS_MAXIMIZE_WINDOW"> - Maximize window - </message> - <message desc="Tool-tip for the window's minimize icon." name="IDS_MINIMIZE_WINDOW"> - Minimize window - </message> - <message desc="Tool-tip for the window's restore icon." name="IDS_RESTORE_WINDOW"> - Restore window - </message> - <message desc="Tool-tip for the window's options menu icon." name="IDS_OPTIONS_MENU"> - Options - </message> - <message desc="Button displayed underneath explanatory text for app features. Clicking causes the text, infographic and the button itself to be replaced by the actual UI for that feature." name="IDS_GET_STARTED"> - Get started - </message> <message desc="Help link, displayed in the top-left (assuming ltr layout) corner of the main screen. Clicking this takes the user to our FAQ." name="IDS_HELP"> Help </message> <message desc="Credits link, displayed in the top-left (assuming ltr layout) corner of the main screen. Clicking this takes the user to our acknowledgements screen." name="IDS_CREDITS" formatter_data="android_java"> Credits </message> - <message desc="Clicking this button starts the desktop access process." name="IDS_HOME_ACCESS_BUTTON"> - Access - </message> - <message desc="Description of the 'access' or 'client' functionality, displayed next to a button that instigates an access operation." name="IDS_HOME_ACCESS_DESCRIPTION"> - See and control a shared computer. - </message> - <message desc="Hyperlink displayed immediately after the message indicating that the current computer is accepting remote connectins. Clicking this link allows the user to change the PIN (personal identification number) for accessing this host." name="IDS_HOME_DAEMON_CHANGE_PIN_LINK"> - Change PIN - </message> - <message desc="Button displayed when the current computer is accepting remote connections. Clicking this button causes it to stop accepting remote connections." name="IDS_HOME_DAEMON_STOP_BUTTON"> - Disable remote connections - </message> - <message desc="Button displayed when the current computer is not accepting remote connections. Clicking this button causes it to start accepting remote connections." name="IDS_HOME_DAEMON_START_BUTTON"> - Enable remote connections - </message> - <message desc="Message displayed in the application to indicate that this computer is remotely accessible, but only from a different account than the one that the user is currently signed in as." name="IDS_HOME_DAEMON_HOST_ENABLED_OTHER_ACCOUNT"> - This computer is currently shared under a different account. - </message> - <message desc="Explanatory text displayed when the user enables remote access or changes the PIN." name="IDS_HOST_SETUP_DIALOG_DESCRIPTION"> - To protect access to this computer, please choose a PIN of <ph name="BOLD_START">$1<ex><b></ex></ph>at least six digits<ph name="BOLD_END">$2<ex></b></ex></ph>. This PIN will be required when connecting from another location. - </message> - <message desc="Message shown when host service fails to start when enabling the host on local computer." name="IDS_HOST_SETUP_HOST_FAILED"> - Failed to start remote access service. - </message> - <message desc="Message shown when user has attempted to continue past the manual install dialog, but the Host components are not yet installed." name="IDS_HOST_SETUP_INSTALL_PENDING"> - Please run the installer before continuing. - </message> - <message desc="Message shown when host registration fails when enabling the host on local computer." name="IDS_ERROR_HOST_REGISTRATION_FAILED"> - Failed to register this computer. - </message> - <message desc="Message shown after access to local computer has been enabled successfully." name="IDS_HOST_SETUP_STARTED"> - Remote connections for this computer have been enabled. - </message> - <message desc="Instructions to the user to ask them to disable power management for the computer in order to be able to connect to it." name="IDS_HOST_SETUP_STARTED_DISABLE_SLEEP"> - Please check your computer's power management settings and ensure that it is not configured to sleep when idle. - </message> - <message desc="Message shown when local machine is being registered in the directory and when starting the host." name="IDS_HOST_SETUP_STARTING"> - Enabling remote connections for this computer… - </message> - <message desc="Message shown after we've failed to stop the host." name="IDS_HOST_SETUP_STOP_FAILED"> - Failed to disable remote access to this computer. Please try again later. - </message> - <message desc="Message shown after host has been stopped." name="IDS_HOST_SETUP_STOPPED"> - Remote connections for this computer have been disabled. - </message> - <message desc="Message shown when host is being stopped on the local machine." name="IDS_HOST_SETUP_STOPPING"> - Disabling remote connections for this computer… - </message> - <message desc="Message shown after changing PIN for the local computer." name="IDS_HOST_SETUP_UPDATED_PIN"> - Your PIN has been updated. - </message> - <message desc="Message shown while changing PIN for the local computer." name="IDS_HOST_SETUP_UPDATING_PIN"> - The PIN for this computer is being updated… - </message> - <message desc="Message shown we fail to update PIN for the local computer." name="IDS_HOST_SETUP_UPDATE_PIN_FAILED"> - Failed to update the PIN. Please try again later. - </message> - <message desc="Clicking this button starts the desktop sharing process." name="IDS_HOME_SHARE_BUTTON"> - Share - </message> - <message desc="Description of the 'share' or 'host' functionality, displayed next to a button that instigates a share operation." name="IDS_HOME_SHARE_DESCRIPTION"> - Share this computer for another user to see and control. - </message> - <message desc="Text displayed below the description of the 'share' or 'host' functionality on an unsupported platform." name="IDS_HOME_SHARE_DESCRIPTION_UNSUPPORTED"> - (this feature is not yet available for your computer) - </message> - <message desc="In the connection history dialog, clicking this button shows only recent connections to this computer." name="IDS_INCOMING_CONNECTIONS"> - To this computer - </message> - <message desc="Instructions shown above the access code when it is ready to be conveyed to the client." name="IDS_INSTRUCTIONS_SHARE_ABOVE"> - To begin sharing your desktop, give the access code below to the person who will be assisting you. - </message> - <message desc="Instructions shown below the access code when it is ready to be conveyed to the client." name="IDS_INSTRUCTIONS_SHARE_BELOW"> - Once they enter the code, you will be prompted to accept the connection and begin the sharing session. - </message> - <message desc="Instructions shown when the local user must accept or reject the incoming connection request." name="IDS_INSTRUCTIONS_SHARE_PROMPT"> - Please select '<ph name="SHARE">$1<ex>Share</ex></ph>' on the connection dialog box to complete the process. - </message> - <message desc="An error message displayed if the user enters an invalid PIN while setting up a host." name="IDS_INVALID_PIN"> - Please enter a PIN consisting of six or more digits. - </message> - <message desc="Description of the 'IT2Me' remote support functionality, displayed until the user clicks a 'get started' button, at which point it is replaced by the actual UI for that functionality." name="IDS_IT2ME_FIRST_RUN"> - User-to-user screen sharing, perfect for remote technical support. - </message> - <message desc="String displayed in front of the host when a connection is active informing the client user who they are connected to." name="IDS_LABEL_CONNECTED"> - Connected: - </message> - <message desc="Description of the 'Me2Me' remote access functionality, displayed until the user clicks a 'get started' button, at which point it is replaced by the actual UI for that functionality." name="IDS_ME2ME_FIRST_RUN"> - Access your own computer from anywhere. - </message> - <message desc="Text shown while generating an access code." name="IDS_MESSAGE_GENERATING"> - Generating access code… - </message> <message desc="Message shown on the host computer while a session is active informing them who is connected." name="IDS_MESSAGE_SHARED"> Your desktop is currently shared with <ph name="USER">$1<ex>user@domain.com</ex></ph>. </message> - <message desc="Sub-title for the one-time authorization step. Displayed after the product name and separated by a chevron." name="IDS_MODE_AUTHORIZE"> - Authorize - </message> <message desc="Sub-title for the remote assistance section of the UI, which contains buttons to share this computer or to connect to another computer, both on a one-off basis." name="IDS_MODE_IT2ME"> Remote Assistance </message> @@ -1119,15 +722,6 @@ Unrecognized host error: <ph name="HOST_OFFLINE_REASON">$1<ex>EXIT_CODE_FROM_HOST_NEWER_THAN_CLIENT</ex></ph>. </message> </if> - <message desc="Modified version of the host name shown for hosts that are running an out-of-date version of the Me2Me host software." name="IDS_UPDATE_REQUIRED"> - <ph name="HOSTNAME">$1<ex>My Linux desktop</ex></ph> (out-of-date) - </message> - <message desc="Explanatory text displayed if the user tries to connect to a computer running out-of-date Me2Me host software." name="IDS_HOST_NEEDS_UPDATE_DETAIL"> - Software updates usually happen automatically, but can fail in some rare cases. Updating the software should take no more than a few minutes and can be done while connected to your computer remotely. - </message> - <message desc="In the connection history dialog, clicking this button shows only recent connections from this computer." name="IDS_OUTGOING_CONNECTIONS"> - From this computer - </message> <message desc="Label for the PIN entry box." name="IDS_PIN"> PIN </message> @@ -1137,12 +731,6 @@ <message desc="Message displayed to the user asking them to enter a PIN for the host they are connecting to." name="IDS_PIN_MESSAGE_ANDROID" formatter_data="android_java"> Please enter your PIN for the remote computer. </message> - <message desc="Error message displayed to the user if they enter different PINs in the boxes marked 'PIN' and 'retype PIN'." name="IDS_PINS_NOT_EQUAL"> - Please enter the same PIN in both boxes. - </message> - <message desc="Web-app description. Displayed in Chrome's extensions page. KEEP THIS TO 132 CHARACTERS OR LESS, as this is a hard limit imposed by Chrome Web Store." name="IDS_PRODUCT_DESCRIPTION"> - Access other computers or allow another user to access your computer securely over the Internet. - </message> <message desc="Label for button to reconnect to the previous Me2Me host. This button appears on the 'session-finished' page." name="IDS_RECONNECT"> Reconnect </message> @@ -1152,24 +740,12 @@ <message desc="Label for button to retry connecting to a Me2Me host, after failing to connect to that host. This button appears on the 'session-finished' page." name="IDS_RETRY"> Retry </message> - <message desc="Tool-bar button used to access the Full-screen and shrink-to-fit features ('screen' in this context refers to the fact that the options are related to how the remote screen is displayed)." name="IDS_SCREEN_OPTIONS"> - Screen options - </message> <message desc="Label for the client-side menu button that sends a Ctrl-Alt-Del sequence to the host. Clicking this button behaves as if Ctrl, Alt and Del were pressed and then released at the host." name="IDS_SEND_CTRL_ALT_DEL" formatter_data="android_java"> Send Ctrl-Alt-Del </message> - <message desc="Tool-bar button used to access buttons for pressing and releasing keys or sequences of keys that might not otherwise be available. For example, Ctrl-Alt-Del, which if pressed at a client would take effect there, rather than being sent to the host as the user expected." name="IDS_SEND_KEYS"> - Send keys - </message> <message desc="Label for the client-side menu button that sends a PrtScn key press to the host. The 'PrtScn' abbreviation (as typically printed on the keycap on English keyboards) is preferred over 'Print Screen', to make it clearer that this refers to the physical PrtScn key, and not the OS-specific keyboard shortcut for the screen capture functionality." name="IDS_SEND_PRINT_SCREEN"> Send PrtScn </message> - <message desc="Label for the client-side menu button that toggles whether or not the right-hand Ctrl key is used to send the Windows/Command key." name="IDS_MAP_RIGHT_CTRL_TO_META"> - Use right Ctrl for Win key (⌘ on Mac) - </message> - <message desc="Menu option for enabling shrink-to-fit. When clicked, the remote desktop will be scaled down so that it fits in the browser window." name="IDS_SHRINK_TO_FIT"> - Shrink to fit - </message> <message desc="Sign in button, visible if the user's authentication token is corrupt, in which case the user has to sign in (authenticate) to the app again." name="IDS_SIGN_IN_BUTTON"> Sign in </message> @@ -1179,30 +755,9 @@ <message desc="Label for the 'stop sharing' button on the host-side. Clicking this button disconnects the client." name="IDS_STOP_SHARING_BUTTON"> Stop Sharing </message> - <message desc="Column header in the connection history table showing the time and date of a connection." name="IDS_TIME_HEADER"> - Time - </message> - <message desc="The tool-tip shown when the user hovers over an on-line host. Clicking the host will initiate a connection to it." name="IDS_TOOLTIP_CONNECT"> - Connect to <ph name="HOSTNAME">$1<ex>My Linux desktop</ex></ph> - </message> - <message desc="The tool-tip shown when the user hovers over the 'delete host' button. Clicking this button removes the host from the list and disables connections to it." name="IDS_TOOLTIP_DELETE"> - Disable remote connections to this computer - </message> <message desc="The tool-tip shown when the user hovers over the 'refresh host list' button. Clicking this button reloads the host list without reloading the app." name="IDS_TOOLTIP_REFRESH" formatter_data="android_java"> Refresh the list of hosts </message> - <message desc="The tool-tip shown when the user hovers over the 'rename host' button. Clicking this button allows the host name to be edited in-place." name="IDS_TOOLTIP_RENAME"> - Edit computer name - </message> - <message desc="Message displayed at the bottom of the host screen if local policy dictates that NAT traversal is disabled, meaning that connections outside the local network will not work." name="IDS_WARNING_NAT_DISABLED"> - NOTE: Policy settings permit connections only between computers within your network. - </message> - <message desc="Link to learn more detailed information on a topic." name="IDS_LEARN_HOW"> - Learn how. - </message> - <message desc="Help link displayed when the user enables the host on this computer. Clicking this link opens a page that explains why this operation is safe. This string appears in a UI with limited horizontal space. Please try to keep translations no more than about 30 characters." name="IDS_WHY_IS_THIS_SAFE"> - Why is this safe? - </message> <message desc="Check-box displayed when the user enters their PIN to connect to a host allowing them to 'pair' the client and host, avoiding the need to enter the PIN each time." name="IDS_REMEMBER_PIN" formatter_data="android_java"> Don't ask for a PIN again when connecting to this host from this device. </message> @@ -1224,15 +779,9 @@ <message name="IDS_REMOTING_REMOTE_SECURITY_KEY_DESCRIPTION" desc="The file description specified in the version information of remote_security_key.exe."> Security Key Remoting Process </message> - <message name="IDS_REMOTING_HOST_COMMAND_DESCRIPTION" desc="The file description specified in the version information of remoting_host_command.exe. The Chrome Remote Desktop host allows a user to connect to their computer remotely (it 'hosts' a connection from a remote computer)."> - Application to issue commands to Chrome remote desktop host. - </message> <message name="IDS_REMOTING_START_HOST_DESCRIPTION" desc="The file description specified in the version information of remoting_start_host.exe."> Host Provisioning Utility </message> - <message name="IDS_VERIFY_PIN_DIALOG_EMAIL_LABEL" desc="The message displayed by the PIN verification dialog."> - Account - </message> <message name="IDS_HOST_CATEGORY" desc="Name of the message category assigned to all messages written to the EventLog by Chromoting Host."> Host </message> @@ -1254,54 +803,18 @@ <message name="IDS_HOST_STOPPED" desc="The message reported to the EventLog by Chromoting Host every time it is stopped."> Host stopped. </message> - <message desc="Link to allow a host's paired clients to be viewed or edited." name="IDS_HOME_DAEMON_MANAGE_PAIRINGS"> - View/edit - </message> <message desc="This text is used on a button or context-menu or similar control. When chosen or pressed, it deletes a selected item from a list." meaning="Delete an item from a list." name="IDS_DELETE_LIST_ITEM" formatter_data="android_java"> Delete </message> - <message desc="Link to delete a specific paired client." name="IDS_DELETE_PAIRED_CLIENT"> - Delete - </message> - <message desc="Link to delete all paired clients." name="IDS_DELETE_ALL_PAIRED_CLIENTS"> - Delete all - </message> - <message desc="Message displayed in the paired client manager dialog when all paired clients have been deleted." name="IDS_NO_PAIRED_CLIENTS"> - All paired clients have been deleted. - </message> - <message desc="Message displayed when the current computer has been paired with one or more clients, allowing them to connect without needing a PIN." name="IDS_HOME_DAEMON_PAIRED_MESSAGE"> - This computer is configured to allow one or more clients to connect without entering a PIN. - </message> - <message desc="Message displayed above the list of paired clients, explaining its purpose." name="IDS_PAIRED_CLIENTS_INTRODUCTION"> - The following clients have been paired with this computer and can connect without supplying a PIN. You can revoke this permission at any time, either individually, or for all clients. - </message> - <message desc="Table header for the dates at which clients were paired." name="IDS_PAIRED_CLIENT_DATE"> - Pairing date - </message> - <message desc="Table header for the names of paired clients." name="IDS_PAIRED_CLIENT_NAME"> - Client - </message> <message desc="Text shown while a background operation is in progress." name="IDS_WORKING"> Working… </message> - <message desc="Menu option to toggle the visibility of connection statistics." name="IDS_TOGGLE_STATS"> - Show statistics - </message> - <message desc="Menu option to open a new window." name="IDS_NEW_WINDOW"> - New window… - </message> <message desc="Label for the Feedback button displayed in the Android Help screen. Pressing this button causes the Feedback screen to be shown." name="IDS_ACTIONBAR_FEEDBACK" formatter_data="android_java"> Feedback </message> <message desc="Label for the menu button displayed on the Android toolbar. Pressing this button will open a drawer with a list of menu options." name="IDS_ACTIONBAR_MENU" formatter_data="android_java"> Menu </message> - <message desc="Label for button to accept remote assistance. This button appears in the Hangouts confirm dialog." name="IDS_HANGOUTS_CONFIRM_DIALOG_ACCEPT" > - Accept - </message> - <message desc="Label for button to decline remote assistance. This button appears in the Hangouts confirm dialog." name="IDS_HANGOUTS_CONFIRM_DIALOG_DECLINE" > - Decline - </message> <message desc="Message displayed before sharing computer in 'It2Me' mode." name="IDS_SHARE_CONFIRM_DIALOG_MESSAGE" > Would you like to share this computer for another user to see and control? </message> @@ -1314,33 +827,6 @@ <message desc="Label for the button to decline sharing the computer in 'It2Me' mode." name="IDS_SHARE_CONFIRM_DIALOG_DECLINE" > Cancel </message> - <message desc="Text shown in tooltip to inform the user that a setting is managed by domain policy." name="IDS_SETTING_MANAGED_BY_POLICY"> - This setting is managed by your domain policy. - </message> - <message desc="Platform-specific text indicating that a component is for the Windows OS." name="IDS_FOR_PLATFORM_WINDOWS"> - For Windows 7 and above - </message> - <message desc="Platform-specific text indicating that a component is for the Mac OS." name="IDS_FOR_PLATFORM_MAC"> - For Mac (OS X Yosemite 10.10 and above) - </message> - <message desc="Text for the button the user clicks to indicate that they agree to the terms of service and want to proceed with downloading the installer." name="IDS_ACCEPT_AND_INSTALL"> - Accept and Install - </message> - <message name="IDS_WEBSITE_INVITE_BETA" desc="Invitation to early adopters to try the new version"> - Get a sneak peek at the new <ph name="LINK_BEGIN">$1<ex><a href=http://example.com></ex></ph>Chrome Remote Desktop web app<ph name="LINK_END">$2<ex></a></ex></ph>. We'd love to hear your feedback. - </message> - <message name="IDS_WEBSITE_INVITE_STABLE" desc="Invitation to all users to try the new version"> - Chrome Remote Desktop is now on the web! Check out our <ph name="LINK_BEGIN">$1<ex><a href=http://example.com></ex></ph>free web app<ph name="LINK_END">$2<ex></a></ex></ph>. - </message> - <message name="IDS_WEBSITE_INVITE_FILE_TRANSFER" desc="Announcement of the file transfer feature"> - Chrome Remote Desktop is now on the web with new features including file transfer! Check out our <ph name="LINK_BEGIN">$1<ex><a href=http://example.com></ex></ph>web app<ph name="LINK_END">$2<ex></a></ex></ph>. - </message> - <message name="IDS_WEBSITE_INVITE_MULTI_MONITOR" desc="Announcement of improved support for multi-monitor"> - Chrome Remote Desktop is now on the web. Try our <ph name="LINK_BEGIN">$1<ex><a href=http://example.com></ex></ph>web app<ph name="LINK_END">$2<ex></a></ex></ph>—it's fast and free, with even more features, including improved support for multiple monitors. - </message> - <message name="IDS_WEBSITE_INVITE_DEPRECATION" desc="Requirement all users to try the new version"> - This app is no longer supported. To ensure you're getting the latest features and security updates, please use the <ph name="LINK_BEGIN">$1<ex><a href=http://example.com></ex></ph>Chrome Remote Desktop web app<ph name="LINK_END">$2<ex></a></ex></ph>. - </message> <message name="IDS_DOWNLOAD_FILE_DIALOG_TITLE" desc="Window title for file chooser to select file to download to the client"> Download File </message> @@ -1363,9 +849,6 @@ <message name="IDS_MAC_PERMISSION_WIZARD_FINAL_TEXT" desc="The text shown on the final screen of the permission wizard that lets the user know they have successfully granted the permissions necessary for Chrome Remote Desktop to work properly. Mac-only."> You're all set! </message> - <message name="IDS_MAC_PERMISSION_ALREADY_DONE" desc="The label for the checkbox that the user can check to indicate that they have already granted this permission. This can be used to override the automatic permission check, for example when our heuristic to check permission is failing. Mac-only."> - I have already granted this permission. - </message> <message name="IDS_ACCESSIBILITY_PERMISSION_DIALOG_TITLE" desc="The title of the prompt that asks the user to grant 'Accessibility' permission to the Chrome Remote Desktop service. This permission is part of the 'Privacy and Security' preferences pane. Mac-only."> Grant 'Accessibility' permission to <ph name="PRODUCT_NAME">$1<ex>Chrome Remote Desktop</ex></ph> </message>
diff --git a/services/network/legacy_tls_config_distributor.cc b/services/network/legacy_tls_config_distributor.cc index 54c3b2da..5158b3a 100644 --- a/services/network/legacy_tls_config_distributor.cc +++ b/services/network/legacy_tls_config_distributor.cc
@@ -17,6 +17,7 @@ #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "crypto/sha2.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" namespace network { @@ -50,8 +51,16 @@ bool LegacyTLSExperimentConfig::ShouldSuppressLegacyTLSWarning( const std::string& hostname) const { + // Match on eTLD+1 rather than full hostname (to account for subdomains and + // redirects). If no registrable domain is found, default to using the + // hostname as-is. + auto domain = net::registry_controlled_domains::GetDomainAndRegistry( + hostname, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); + if (domain.empty()) + domain = hostname; + // Convert bytes from crypto::SHA256 so we can compare to the proto contents. - std::string host_hash_bytes = crypto::SHA256HashString(hostname); + std::string host_hash_bytes = crypto::SHA256HashString(domain); std::string host_hash = base::ToLowerASCII( base::HexEncode(host_hash_bytes.data(), host_hash_bytes.size())); const auto& control_site_hashes = proto_.control_site_hashes();
diff --git a/testing/iossim/BUILD.gn b/testing/iossim/BUILD.gn index 0358723..71a20741 100644 --- a/testing/iossim/BUILD.gn +++ b/testing/iossim/BUILD.gn
@@ -2,7 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//build/config/ios/ios_sdk.gni") import("//build/config/mac/mac_sdk.gni") if (current_toolchain == host_toolchain) { @@ -17,8 +16,4 @@ sources = [ get_label_info(":iossim($host_toolchain)", "root_out_dir") + "/iossim" ] } -} else { - group("iossim") { - public_deps = [ ":iossim($default_toolchain)" ] - } }
diff --git a/testing/test.gni b/testing/test.gni index eda4330..2b4e0f7f 100644 --- a/testing/test.gni +++ b/testing/test.gni
@@ -23,12 +23,6 @@ import("//build/config/chromeos/rules.gni") } -if (is_ios) { - import("//build/config/ios/ios_sdk.gni") - import("//build/config/ios/ios_test_runner_wrapper.gni") - import("//build/config/ios/rules.gni") -} - # Define a test as an executable (or apk on Android) with the "testonly" flag # set. # Variable: @@ -233,6 +227,9 @@ output_name = _exec_target } } else if (is_ios) { + import("//build/config/ios/ios_sdk.gni") + import("//build/config/ios/rules.gni") + declare_args() { # Keep the unittest-as-xctest functionality defaulted to off until the # bots are updated to handle it properly. @@ -242,31 +239,6 @@ } _test_target = target_name - _wrapper_output_name = "run_${target_name}" - ios_test_runner_wrapper(_wrapper_output_name) { - forward_variables_from(invoker, - [ - "data", - "data_deps", - "deps", - "executable_args", - "retries", - "shards", - ]) - - _root_build_dir = rebase_path("${root_build_dir}", root_build_dir) - - if (!defined(executable_args)) { - executable_args = [] - } - executable_args += [ - "--app", - "@WrappedPath(${_root_build_dir}/${_test_target}.app)", - ] - - wrapper_output_name = "${_wrapper_output_name}" - } - _resources_bundle_data = target_name + "_resources_bundle_data" bundle_data(_resources_bundle_data) { @@ -309,13 +281,6 @@ bundle_deps = [] } bundle_deps += [ ":$_resources_bundle_data" ] - - if (!defined(data_deps)) { - data_deps = [] - } - - # Include the generate_wrapper as part of data_deps - data_deps += [ ":${_wrapper_output_name}" ] } } else if (is_chromeos && cros_board != "") { # Building for a cros board (ie: not linux-chromeos).
diff --git a/testing/variations/README.md b/testing/variations/README.md index 9f659e6..9568f20a6 100644 --- a/testing/variations/README.md +++ b/testing/variations/README.md
@@ -80,24 +80,27 @@ ### Experiments (Groups) Each *experiment* is a dictionary that must contain the `name` key, identifying -the experiment group name. This name **must** match the FieldTrial experiment -group name used in the Chromium client code. +the experiment group name. -> Note: Many newer studies do not use experiment names in the client code at -> all, and rely on the [Feature List API][FeatureListAPI] instead. Nonetheless, -> if a study has a server-side configuration, the experiment `name` specified -> here must still match the name specified in the server-side configuration; -> this is used to implement sanity-checks on the server. +> Note: Studies should typically use the [Feature List API][FeatureListAPI]. For +> such studies, the experiment `name` specified in the testing config is still +> required (for legacy reasons), but it is ignored. However, the lists of +> `enable_features`, `disable_features`, and `params` **must** match the server +> config. This is enforced via server-side Tricorder checks. +> +> For old-school studies that do check the actual experiment group name in the +> client code, the `name` **must** exactly match the client code and the server +> config. -The remaining keys, `params`, `enable_features`, and `disable_features` are +The remaining keys -- `enable_features`, `disable_features`, and `params` -- are optional. -`params` is a dictionary mapping parameter name to parameter. - `enable_features` and `disable_features` indicate which features should be enabled and disabled, respectively, through the [Feature List API][FeatureListAPI]. +`params` is a dictionary mapping parameter name to parameter value. + > Reminder: The variations framework does not actually fetch any field trial > definitions from the server for Chromium builds, so any feature enabling or > disabling must be configured here.
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 3fd7156..2bf017b 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -6073,6 +6073,7 @@ { "name": "VizForWebView", "enable_features": [ + "EnableSharedImageForWebview", "UseSkiaForGLReadback", "UseSkiaRenderer", "VizForWebView"
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 86f2b58..3a2ce614 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -121,7 +121,6 @@ "platform/mac/web_sandbox_support.h", "platform/mac/web_scrollbar_theme.h", "platform/media/webmediaplayer_delegate.h", - "platform/modules/mediastream/media_stream_audio_deliverer.h", "platform/modules/mediastream/media_stream_types.h", "platform/modules/mediastream/secure_display_link_tracker.h", "platform/modules/mediastream/web_media_element_source_utils.h",
diff --git a/third_party/blink/public/common/frame/sandbox_flags.h b/third_party/blink/public/common/frame/sandbox_flags.h index d360f57e..ddd105e 100644 --- a/third_party/blink/public/common/frame/sandbox_flags.h +++ b/third_party/blink/public/common/frame/sandbox_flags.h
@@ -31,10 +31,6 @@ return static_cast<WebSandboxFlags>(~static_cast<int>(flags)); } -inline std::ostream& operator<<(std::ostream& out, WebSandboxFlags flags) { - return out << std::bitset<sizeof(int) * 8>(static_cast<int>(flags)); -} - } // namespace mojom } // namespace blink
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 1b1364a5..d13656f4 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2513,6 +2513,8 @@ kXRSessionRequestHitTestSourceForTransientInput = 3167, kXRDOMOverlay = 3168, kCssStyleSheetReplaceWithImport = 3169, + kCryptoAlgorithmEd25519 = 3170, + kCryptoAlgorithmX25519 = 3171, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/web_crypto_algorithm.h b/third_party/blink/public/platform/web_crypto_algorithm.h index bb46a6e2..bfb7e8e 100644 --- a/third_party/blink/public/platform/web_crypto_algorithm.h +++ b/third_party/blink/public/platform/web_crypto_algorithm.h
@@ -72,8 +72,10 @@ kWebCryptoAlgorithmIdEcdh, kWebCryptoAlgorithmIdHkdf, kWebCryptoAlgorithmIdPbkdf2, + kWebCryptoAlgorithmIdEd25519, + kWebCryptoAlgorithmIdX25519, #if INSIDE_BLINK - kWebCryptoAlgorithmIdLast = kWebCryptoAlgorithmIdPbkdf2, + kWebCryptoAlgorithmIdLast = kWebCryptoAlgorithmIdX25519, #endif }; @@ -105,6 +107,8 @@ kWebCryptoAlgorithmParamsTypeAesDerivedKeyParams, kWebCryptoAlgorithmParamsTypeHkdfParams, kWebCryptoAlgorithmParamsTypePbkdf2Params, + kWebCryptoAlgorithmParamsTypeEd25519Params, + kWebCryptoAlgorithmParamsTypeX25519KeyDeriveParams, }; struct WebCryptoAlgorithmInfo { @@ -138,6 +142,8 @@ class WebCryptoAesDerivedKeyParams; class WebCryptoHkdfParams; class WebCryptoPbkdf2Params; +class WebCryptoEd25519Params; +class WebCryptoX25519KeyDeriveParams; class WebCryptoAlgorithmParams; class WebCryptoAlgorithmPrivate; @@ -209,6 +215,9 @@ AesDerivedKeyParams() const; BLINK_PLATFORM_EXPORT const WebCryptoHkdfParams* HkdfParams() const; BLINK_PLATFORM_EXPORT const WebCryptoPbkdf2Params* Pbkdf2Params() const; + BLINK_PLATFORM_EXPORT const WebCryptoEd25519Params* Ed25519Params() const; + BLINK_PLATFORM_EXPORT const WebCryptoX25519KeyDeriveParams* + X25519KeyDeriveParams() const; // Returns true if the provided algorithm ID is for a hash (in other words, // SHA-*)
diff --git a/third_party/blink/public/platform/web_crypto_algorithm_params.h b/third_party/blink/public/platform/web_crypto_algorithm_params.h index 59794d7..c8acc9b 100644 --- a/third_party/blink/public/platform/web_crypto_algorithm_params.h +++ b/third_party/blink/public/platform/web_crypto_algorithm_params.h
@@ -415,6 +415,31 @@ const unsigned iterations_; }; +class WebCryptoEd25519Params : public WebCryptoAlgorithmParamsWithHash { + public: + explicit WebCryptoEd25519Params(const WebCryptoAlgorithm& hash) + : WebCryptoAlgorithmParamsWithHash(hash) {} + + WebCryptoAlgorithmParamsType GetType() const override { + return kWebCryptoAlgorithmParamsTypeEd25519Params; + } +}; + +class WebCryptoX25519KeyDeriveParams : public WebCryptoAlgorithmParams { + public: + explicit WebCryptoX25519KeyDeriveParams(const WebCryptoKey& public_key) + : public_key_(public_key) {} + + WebCryptoAlgorithmParamsType GetType() const override { + return kWebCryptoAlgorithmParamsTypeX25519KeyDeriveParams; + } + + const WebCryptoKey& PublicKey() const { return public_key_; } + + private: + const WebCryptoKey public_key_; +}; + } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_CRYPTO_ALGORITHM_PARAMS_H_
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni index 0b2030b..26f2470 100644 --- a/third_party/blink/renderer/bindings/idl_in_modules.gni +++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -916,7 +916,7 @@ "//third_party/blink/renderer/modules/webusb/worker_navigator_usb.idl", "//third_party/blink/renderer/modules/xr/element_xr.idl", "//third_party/blink/renderer/modules/xr/navigator_xr.idl", - "//third_party/blink/renderer/modules/xr/xr.idl", + "//third_party/blink/renderer/modules/xr/xr_system.idl", "//third_party/blink/renderer/modules/xr/xr_anchor.idl", "//third_party/blink/renderer/modules/xr/xr_anchor_set.idl", "//third_party/blink/renderer/modules/xr/xr_bounded_reference_space.idl",
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc index d348301..e5521f2 100644 --- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc +++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc
@@ -111,6 +111,10 @@ return kHkdfTag; case kWebCryptoAlgorithmIdPbkdf2: return kPbkdf2Tag; + // TODO(crbug.com/1032821): Handle them explicitly for Lint. + case kWebCryptoAlgorithmIdEd25519: + case kWebCryptoAlgorithmIdX25519: + return 0; } NOTREACHED() << "Unknown algorithm ID " << id; return 0;
diff --git a/third_party/blink/renderer/core/dom/character_data.cc b/third_party/blink/renderer/core/dom/character_data.cc index 146bd34..e513dfa9 100644 --- a/third_party/blink/renderer/core/dom/character_data.cc +++ b/third_party/blink/renderer/core/dom/character_data.cc
@@ -233,7 +233,11 @@ if (parentNode()) { ContainerNode::ChildrenChange change = { - ContainerNode::kTextChanged, this, previousSibling(), nextSibling(), + ContainerNode::kTextChanged, + this, + previousSibling(), + nextSibling(), + nullptr, ContainerNode::kChildrenChangeSourceAPI}; parentNode()->ChildrenChanged(change); }
diff --git a/third_party/blink/renderer/core/dom/container_node.cc b/third_party/blink/renderer/core/dom/container_node.cc index bb51a146..68ff9e06 100644 --- a/third_party/blink/renderer/core/dom/container_node.cc +++ b/third_party/blink/renderer/core/dom/container_node.cc
@@ -810,6 +810,11 @@ GetDocument().NodeChildrenWillBeRemoved(*this); } + HeapVector<Member<Node>>* removed_nodes = nullptr; + if (ChildrenChangedAllChildrenRemovedNeedsList()) { + removed_nodes = + MakeGarbageCollected<HeapVector<Member<Node>>>(CountChildren()); + } { HTMLFrameOwnerElement::PluginDisposeSuspendScope suspend_plugin_dispose; TreeOrderedMap::RemoveScope tree_remove_scope; @@ -822,11 +827,14 @@ while (Node* child = first_child_) { RemoveBetween(nullptr, child->nextSibling(), *child); NotifyNodeRemoved(*child); + if (removed_nodes) + removed_nodes->push_back(child); } } - ChildrenChange change = {kAllChildrenRemoved, nullptr, nullptr, nullptr, - kChildrenChangeSourceAPI}; + ChildrenChange change = { + kAllChildrenRemoved, nullptr, nullptr, nullptr, removed_nodes, + kChildrenChangeSourceAPI}; ChildrenChanged(change); } @@ -1031,6 +1039,10 @@ inserted_node->SetStyleChangeOnInsertion(); } +bool ContainerNode::ChildrenChangedAllChildrenRemovedNeedsList() const { + return false; +} + void ContainerNode::CloneChildNodesFrom(const ContainerNode& node) { for (const Node& child : NodeTraversal::ChildrenOf(node)) AppendChild(child.Clone(GetDocument(), CloneChildrenFlag::kClone));
diff --git a/third_party/blink/renderer/core/dom/container_node.h b/third_party/blink/renderer/core/dom/container_node.h index 3ced374..cda2fd1 100644 --- a/third_party/blink/renderer/core/dom/container_node.h +++ b/third_party/blink/renderer/core/dom/container_node.h
@@ -315,8 +315,12 @@ Node* unchanged_next, ChildrenChangeSource by_parser) { ChildrenChange change = { - node.IsElementNode() ? kElementInserted : kNonElementInserted, &node, - unchanged_previous, unchanged_next, by_parser}; + node.IsElementNode() ? kElementInserted : kNonElementInserted, + &node, + unchanged_previous, + unchanged_next, + nullptr, + by_parser}; return change; } @@ -325,8 +329,12 @@ Node* next_sibling, ChildrenChangeSource by_parser) { ChildrenChange change = { - node.IsElementNode() ? kElementRemoved : kNonElementRemoved, &node, - previous_sibling, next_sibling, by_parser}; + node.IsElementNode() ? kElementRemoved : kNonElementRemoved, + &node, + previous_sibling, + next_sibling, + nullptr, + by_parser}; return change; } @@ -353,14 +361,23 @@ // - siblingChanged.nextSibling after single node insertion // - nextSibling of the last inserted node after multiple node insertion. Node* sibling_after_change = nullptr; + + // List of removed nodes for kAllChildrenRemoved. + HeapVector<Member<Node>>* removed_nodes; ChildrenChangeSource by_parser; }; // Notifies the node that it's list of children have changed (either by adding // or removing child nodes), or a child node that is of the type // CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value. + // + // ChildrenChanged() implementations may modify the DOM tree, and may dispatch + // synchronous events. virtual void ChildrenChanged(const ChildrenChange&); + // Provides ChildrenChange::removed_nodes for kAllChildrenRemoved. + virtual bool ChildrenChangedAllChildrenRemovedNeedsList() const; + virtual bool ChildrenCanHaveStyle() const { return true; } void Trace(Visitor*) override;
diff --git a/third_party/blink/renderer/core/dom/node.h b/third_party/blink/renderer/core/dom/node.h index e9b73073..1cb6f6a 100644 --- a/third_party/blink/renderer/core/dom/node.h +++ b/third_party/blink/renderer/core/dom/node.h
@@ -767,16 +767,20 @@ // // Blink notifies this callback regardless if the subtree of the node is a // document tree or a floating subtree. Implementation can determine the type - // of subtree by seeing insertionPoint->isConnected(). For a performance + // of subtree by seeing insertion_point->isConnected(). For a performance // reason, notifications are delivered only to ContainerNode subclasses if the - // insertionPoint is out of document. + // insertion_point is out of document. // - // There are another callback named didNotifySubtreeInsertionsToDocument(), + // There are another callback named DidNotifySubtreeInsertionsToDocument(), // which is called after all the descendant is notified, if this node was // inserted into the document tree. Only a few subclasses actually need // this. To utilize this, the node should return - // InsertionShouldCallDidNotifySubtreeInsertions from insertedInto(). + // kInsertionShouldCallDidNotifySubtreeInsertions from InsertedInto(). // + // InsertedInto() implementations must not modify the DOM tree, and must not + // dispatch synchronous events. On the other hand, + // DidNotifySubtreeInsertionsToDocument() may modify the DOM tree, and may + // dispatch synchronous events. enum InsertionNotificationRequest { kInsertionDone, kInsertionShouldCallDidNotifySubtreeInsertions @@ -788,10 +792,12 @@ // Notifies the node that it is no longer part of the tree. // - // This is a dual of insertedInto(), and is similar to the + // This is a dual of InsertedInto(), and is similar to the // DOMNodeRemovedFromDocument DOM event, but does not require the overhead of // event dispatching, and is called _after_ the node is removed from the tree. // + // RemovedFrom() implementations must not modify the DOM tree, and must not + // dispatch synchronous events. virtual void RemovedFrom(ContainerNode& insertion_point); // FIXME(dominicc): This method is not debug-only--it is used by
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index b45c81d..fde84cca 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -142,6 +142,7 @@ #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h" #include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h" +#include "third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" #include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" @@ -2659,10 +2660,7 @@ const GraphicsLayer* root) { ForAllDrawableGraphicsLayers( root, - [&](const GraphicsLayer* layer) { - RecordGraphicsLayerAsForeignLayer( - context, DisplayItem::kForeignLayerWrapper, *layer); - }, + [&](const GraphicsLayer* layer) { RecordGraphicsLayer(context, *layer); }, [&](const GraphicsLayer* layer, cc::Layer* contents_layer) { RecordForeignLayer( context, *layer, DisplayItem::kForeignLayerContentsWrapper, @@ -2678,7 +2676,7 @@ [](const GraphicsLayer* layer) { PaintArtifactCompositor::UpdateLayerDebugInfo( layer->CcLayer(), - PaintChunk::Id(*layer, DisplayItem::kForeignLayerWrapper), + PaintChunk::Id(*layer, DisplayItem::kGraphicsLayerWrapper), layer->GetCompositingReasons(), layer->GetRasterInvalidationTracking()); },
diff --git a/third_party/blink/renderer/core/html/forms/html_opt_group_element.cc b/third_party/blink/renderer/core/html/forms/html_opt_group_element.cc index 3c09fa5..a3feb75 100644 --- a/third_party/blink/renderer/core/html/forms/html_opt_group_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_opt_group_element.cc
@@ -84,6 +84,29 @@ return !IsDisabledFormControl(); } +void HTMLOptGroupElement::ChildrenChanged(const ChildrenChange& change) { + HTMLElement::ChildrenChanged(change); + if (HTMLSelectElement* select = OwnerSelectElement()) { + if (change.type == kElementInserted) { + if (auto* option = DynamicTo<HTMLOptionElement>(change.sibling_changed)) + select->OptionInserted(*option, option->Selected()); + } else if (change.type == kElementRemoved) { + if (auto* option = DynamicTo<HTMLOptionElement>(change.sibling_changed)) + select->OptionRemoved(*option); + } else if (change.type == kAllChildrenRemoved) { + DCHECK(change.removed_nodes); + for (Node* node : *change.removed_nodes) { + if (auto* option = DynamicTo<HTMLOptionElement>(node)) + select->OptionRemoved(*option); + } + } + } +} + +bool HTMLOptGroupElement::ChildrenChangedAllChildrenRemovedNeedsList() const { + return true; +} + Node::InsertionNotificationRequest HTMLOptGroupElement::InsertedInto( ContainerNode& insertion_point) { HTMLElement::InsertedInto(insertion_point);
diff --git a/third_party/blink/renderer/core/html/forms/html_opt_group_element.h b/third_party/blink/renderer/core/html/forms/html_opt_group_element.h index 693aa166..a03db9b 100644 --- a/third_party/blink/renderer/core/html/forms/html_opt_group_element.h +++ b/third_party/blink/renderer/core/html/forms/html_opt_group_element.h
@@ -52,6 +52,8 @@ ~HTMLOptGroupElement() override; bool SupportsFocus() const override; + void ChildrenChanged(const ChildrenChange& change) override; + bool ChildrenChangedAllChildrenRemovedNeedsList() const override; void ParseAttribute(const AttributeModificationParams&) override; void AccessKeyAction(bool send_mouse_events) override; void DidAddUserAgentShadowRoot(ShadowRoot&) override;
diff --git a/third_party/blink/renderer/core/html/forms/html_option_element.cc b/third_party/blink/renderer/core/html/forms/html_option_element.cc index 9ee3ba0..bce8b9e 100644 --- a/third_party/blink/renderer/core/html/forms/html_option_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_option_element.cc
@@ -339,30 +339,6 @@ return String(); } -Node::InsertionNotificationRequest HTMLOptionElement::InsertedInto( - ContainerNode& insertion_point) { - HTMLElement::InsertedInto(insertion_point); - if (HTMLSelectElement* select = OwnerSelectElement()) { - if (&insertion_point == select || - (IsA<HTMLOptGroupElement>(insertion_point) && - insertion_point.parentNode() == select)) - select->OptionInserted(*this, is_selected_); - } - return kInsertionDone; -} - -void HTMLOptionElement::RemovedFrom(ContainerNode& insertion_point) { - if (auto* select = DynamicTo<HTMLSelectElement>(insertion_point)) { - if (!parentNode() || IsA<HTMLOptGroupElement>(*parentNode())) - select->OptionRemoved(*this); - } else if (IsA<HTMLOptGroupElement>(insertion_point)) { - select = DynamicTo<HTMLSelectElement>(insertion_point.parentNode()); - if (select) - select->OptionRemoved(*this); - } - HTMLElement::RemovedFrom(insertion_point); -} - String HTMLOptionElement::CollectOptionInnerText() const { StringBuilder text; for (Node* node = firstChild(); node;) {
diff --git a/third_party/blink/renderer/core/html/forms/html_option_element.h b/third_party/blink/renderer/core/html/forms/html_option_element.h index ce663f6..b627a08 100644 --- a/third_party/blink/renderer/core/html/forms/html_option_element.h +++ b/third_party/blink/renderer/core/html/forms/html_option_element.h
@@ -101,8 +101,6 @@ bool MatchesDefaultPseudoClass() const override; bool MatchesEnabledPseudoClass() const override; void ParseAttribute(const AttributeModificationParams&) override; - InsertionNotificationRequest InsertedInto(ContainerNode&) override; - void RemovedFrom(ContainerNode&) override; void AccessKeyAction(bool) override; void ChildrenChanged(const ChildrenChange&) override;
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc index e38c97e2..c2c3b31 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -64,7 +64,6 @@ #include "third_party/blink/renderer/core/layout/hit_test_request.h" #include "third_party/blink/renderer/core/layout/hit_test_result.h" #include "third_party/blink/renderer/core/layout/layout_block_flow.h" -#include "third_party/blink/renderer/core/layout/layout_menu_list.h" #include "third_party/blink/renderer/core/layout/layout_object_factory.h" #include "third_party/blink/renderer/core/layout/layout_theme.h" #include "third_party/blink/renderer/core/page/chrome_client.h" @@ -110,7 +109,7 @@ // static bool HTMLSelectElement::CanAssignToSelectSlot(const Node& node) { - // Even if options/optgroups are not rendered as children of LayoutMenuList, + // Even if options/optgroups are not rendered as children of menulist SELECT, // we still need to add them to the flat tree through slotting since we need // their ComputedStyle for popup rendering. return node.HasTagName(html_names::kOptionTag) || @@ -364,7 +363,7 @@ const ComputedStyle& style, LegacyLayout legacy_layout) { if (UsesMenuList()) - return new LayoutMenuList(this); + return LayoutObjectFactory::CreateFlexibleBox(*this, style, legacy_layout); return LayoutObjectFactory::CreateBlockFlow(*this, style, legacy_layout); } @@ -878,6 +877,37 @@ ResetToDefaultSelection(); } +void HTMLSelectElement::ChildrenChanged(const ChildrenChange& change) { + HTMLFormControlElementWithState::ChildrenChanged(change); + if (change.type == kElementInserted) { + if (auto* option = DynamicTo<HTMLOptionElement>(change.sibling_changed)) { + OptionInserted(*option, option->Selected()); + } else if (auto* optgroup = + DynamicTo<HTMLOptGroupElement>(change.sibling_changed)) { + for (auto& option : Traversal<HTMLOptionElement>::ChildrenOf(*optgroup)) + OptionInserted(option, option.Selected()); + } + } else if (change.type == kElementRemoved) { + if (auto* option = DynamicTo<HTMLOptionElement>(change.sibling_changed)) { + OptionRemoved(*option); + } else if (auto* optgroup = + DynamicTo<HTMLOptGroupElement>(change.sibling_changed)) { + for (auto& option : Traversal<HTMLOptionElement>::ChildrenOf(*optgroup)) + OptionRemoved(option); + } + } else if (change.type == kAllChildrenRemoved) { + DCHECK(change.removed_nodes); + for (Node* node : *change.removed_nodes) { + if (auto* option = DynamicTo<HTMLOptionElement>(node)) + OptionRemoved(*option); + } + } +} + +bool HTMLSelectElement::ChildrenChangedAllChildrenRemovedNeedsList() const { + return true; +} + void HTMLSelectElement::OptionInserted(HTMLOptionElement& option, bool option_is_selected) { DCHECK_EQ(option.OwnerSelectElement(), this); @@ -1418,7 +1448,7 @@ void HTMLSelectElement::DidAddUserAgentShadowRoot(ShadowRoot& root) { // Even if UsesMenuList(), the <slot> is necessary to have ComputedStyles - // for <option>s. LayoutMenuList::IsChildAllowed() rejects all of + // for <option>s. LayoutFlexibleBox::IsChildAllowed() rejects all of // LayoutObject children except for MenuListInnerElement's. root.AppendChild( HTMLSlotElement::CreateUserAgentCustomAssignSlot(GetDocument()));
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.h b/third_party/blink/renderer/core/html/forms/html_select_element.h index 7fefca9..6160b1e 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.h +++ b/third_party/blink/renderer/core/html/forms/html_select_element.h
@@ -212,6 +212,8 @@ FormControlState SaveFormControlState() const override; void RestoreFormControlState(const FormControlState&) override; + void ChildrenChanged(const ChildrenChange& change) override; + bool ChildrenChangedAllChildrenRemovedNeedsList() const override; void ParseAttribute(const AttributeModificationParams&) override; bool IsPresentationAttribute(const QualifiedName&) const override;
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element_test.cc b/third_party/blink/renderer/core/html/forms/html_select_element_test.cc index df8adbc..f250ea8 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element_test.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element_test.cc
@@ -459,4 +459,14 @@ ASSERT_TRUE(select->GetLayoutObject()); } +TEST_F(HTMLSelectElementTest, SlotAssignmentRecalcDuringOptionRemoval) { + // crbug.com/1056094 + // This test passes if no CHECK failure about IsSlotAssignmentRecalcForbidden. + SetHtmlInnerHTML("<div dir=auto><select><option>option0"); + auto* select = GetDocument().body()->firstChild()->firstChild(); + auto* option = select->firstChild(); + select->appendChild(option); + option->remove(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/inspector/DEPS b/third_party/blink/renderer/core/inspector/DEPS index 8ea5d7a..56e80d5 100644 --- a/third_party/blink/renderer/core/inspector/DEPS +++ b/third_party/blink/renderer/core/inspector/DEPS
@@ -9,4 +9,5 @@ "+cc/trees/transform_node.h", "+third_party/inspector_protocol/crdtp", "+third_party/icu/source/common/unicode/locid.h", + "+net/http/http_status_code.h", ]
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 e36567d..8810436 100644 --- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -37,6 +37,7 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "build/build_config.h" +#include "net/http/http_status_code.h" #include "services/network/public/mojom/referrer_policy.mojom-blink.h" #include "services/network/public/mojom/websocket.mojom-blink.h" #include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink.h" @@ -497,10 +498,10 @@ static std::unique_ptr<protocol::Network::Request> BuildObjectForResourceRequest(const ResourceRequest& request, + scoped_refptr<EncodedFormData> post_data, size_t max_body_size) { String postData; - bool hasPostData = - FormDataToString(request.HttpBody(), max_body_size, &postData); + bool hasPostData = FormDataToString(post_data, max_body_size, &postData); KURL url = request.Url(); // protocol::Network::Request doesn't have a separate referrer string member // like blink::ResourceRequest, so here we add ResourceRequest's referrer @@ -771,12 +772,15 @@ String request_id = IdentifiersFactory::RequestId(loader, identifier); NetworkResourcesData::ResourceData const* data = resources_data_->Data(request_id); - // Support for POST request redirect + // Support for POST request redirect. scoped_refptr<EncodedFormData> post_data; - if (data) + if (data && + (redirect_response.HttpStatusCode() == net::HTTP_TEMPORARY_REDIRECT || + redirect_response.HttpStatusCode() == net::HTTP_PERMANENT_REDIRECT)) { post_data = data->PostData(); - else if (request.HttpBody()) + } else if (request.HttpBody()) { post_data = request.HttpBody()->DeepCopy(); + } resources_data_->ResourceCreated(request_id, loader_id, request.Url(), post_data); @@ -799,7 +803,8 @@ initiator_info, std::numeric_limits<int>::max()); std::unique_ptr<protocol::Network::Request> request_info( - BuildObjectForResourceRequest(request, max_post_data_size_.Get())); + BuildObjectForResourceRequest(request, post_data, + max_post_data_size_.Get())); // |loader| is null while inspecting worker. // TODO(horo): Refactor MixedContentChecker and set mixed content type even if
diff --git a/third_party/blink/renderer/core/layout/BUILD.gn b/third_party/blink/renderer/core/layout/BUILD.gn index 5a19f5d..1ff875b 100644 --- a/third_party/blink/renderer/core/layout/BUILD.gn +++ b/third_party/blink/renderer/core/layout/BUILD.gn
@@ -145,8 +145,6 @@ "layout_list_marker.h", "layout_media.cc", "layout_media.h", - "layout_menu_list.cc", - "layout_menu_list.h", "layout_multi_column_flow_thread.cc", "layout_multi_column_flow_thread.h", "layout_multi_column_set.cc",
diff --git a/third_party/blink/renderer/core/layout/layout_menu_list.cc b/third_party/blink/renderer/core/layout/layout_menu_list.cc deleted file mode 100644 index 81056ec..0000000 --- a/third_party/blink/renderer/core/layout/layout_menu_list.cc +++ /dev/null
@@ -1,39 +0,0 @@ -/* - * This file is part of the select element layoutObject in WebCore. - * - * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. - * All rights reserved. - * (C) 2009 Torch Mobile Inc. All rights reserved. - * (http://www.torchmobile.com/) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "third_party/blink/renderer/core/layout/layout_menu_list.h" - -#include "third_party/blink/renderer/core/html/forms/html_select_element.h" - -namespace blink { - -LayoutMenuList::LayoutMenuList(Element* element) : LayoutFlexibleBox(element) { - DCHECK(IsA<HTMLSelectElement>(element)); -} - -LayoutMenuList::~LayoutMenuList() = default; - -} // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_menu_list.h b/third_party/blink/renderer/core/layout/layout_menu_list.h deleted file mode 100644 index 066b749..0000000 --- a/third_party/blink/renderer/core/layout/layout_menu_list.h +++ /dev/null
@@ -1,48 +0,0 @@ -/* - * This file is part of the select element layoutObject in WebCore. - * - * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. - * All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_MENU_LIST_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_MENU_LIST_H_ - -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/layout/layout_flexible_box.h" - -namespace blink { - -class CORE_EXPORT LayoutMenuList final : public LayoutFlexibleBox { - public: - explicit LayoutMenuList(Element*); - ~LayoutMenuList() override; - - const char* GetName() const override { return "LayoutMenuList"; } - - private: - bool IsOfType(LayoutObjectType type) const override { - return type == kLayoutObjectMenuList || LayoutFlexibleBox::IsOfType(type); - } -}; - -} // namespace blink - -#endif
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 32114296..c4e74d7 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -869,6 +869,12 @@ // FIXME: In future it may be possible to broaden these conditions in order to // improve performance. + // Positioned objects always have self-painting layers and are safe to use as + // relayout boundaries. + bool is_svg_root = object->IsSVGRoot(); + if (!object->IsPositioned() && !is_svg_root) + return false; + // LayoutInline can't be relayout roots since LayoutBlockFlow is responsible // for layouting them. if (object->IsLayoutInline()) @@ -912,7 +918,7 @@ if (object->IsTextControl()) return true; - if (object->IsSVGRoot()) + if (is_svg_root) return true; if (!object->HasOverflowClip())
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index c3918d7..38ba1b2c 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -2540,7 +2540,6 @@ kLayoutObjectMathML, kLayoutObjectMathMLRoot, kLayoutObjectMedia, - kLayoutObjectMenuList, kLayoutObjectNGBlockFlow, kLayoutObjectNGFieldset, kLayoutObjectNGFlexibleBox,
diff --git a/third_party/blink/renderer/core/loader/cookie_jar.cc b/third_party/blink/renderer/core/loader/cookie_jar.cc index 9ed53b95..ca6b5e6 100644 --- a/third_party/blink/renderer/core/loader/cookie_jar.cc +++ b/third_party/blink/renderer/core/loader/cookie_jar.cc
@@ -10,11 +10,13 @@ namespace blink { -CookieJar::CookieJar(blink::Document* document) : document_(document) {} +CookieJar::CookieJar(blink::Document* document) + : backend_(document->ToExecutionContext()), document_(document) {} CookieJar::~CookieJar() = default; void CookieJar::Trace(Visitor* visitor) { + visitor->Trace(backend_); visitor->Trace(document_); } @@ -56,7 +58,8 @@ if (!backend_.is_bound() || !backend_.is_connected()) { backend_.reset(); document_->GetBrowserInterfaceBroker().GetInterface( - backend_.BindNewPipeAndPassReceiver()); + backend_.BindNewPipeAndPassReceiver( + document_->GetTaskRunner(TaskType::kInternalDefault))); } }
diff --git a/third_party/blink/renderer/core/loader/cookie_jar.h b/third_party/blink/renderer/core/loader/cookie_jar.h index 55af081..44bb2eb9 100644 --- a/third_party/blink/renderer/core/loader/cookie_jar.h +++ b/third_party/blink/renderer/core/loader/cookie_jar.h
@@ -7,8 +7,8 @@ #include "services/network/public/mojom/restricted_cookie_manager.mojom-blink.h" -#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -27,7 +27,7 @@ private: void RequestRestrictedCookieManagerIfNeeded(); - mojo::Remote<network::mojom::blink::RestrictedCookieManager> backend_; + HeapMojoRemote<network::mojom::blink::RestrictedCookieManager> backend_; Member<blink::Document> document_; };
diff --git a/third_party/blink/renderer/core/paint/README.md b/third_party/blink/renderer/core/paint/README.md index 8a6f7a85..446308d 100644 --- a/third_party/blink/renderer/core/paint/README.md +++ b/third_party/blink/renderer/core/paint/README.md
@@ -165,12 +165,11 @@ which uses the compositing decisions from the current compositor (PaintLayerCompositor, which produces GraphicsLayers) with the new CompositeAfterPaint compositor (PaintArtifactCompositor). This is done by a step -at the end of paint which collects all painted GraphicsLayers (and their -associated cc::Layers) as a list of -[ForeignLayerDisplayItem](../../platform/graphics/paint/foreign_layer_display_item.h)s. -Foreign layers are typically used for cc::Layers managed outside blink (e.g., +at the end of paint which collects all painted GraphicsLayers as a list of +[GraphicsLayerDisplayItem](../../platform/graphics/paint/graphics_layer_display_item.h)s. +Additionaly, [ForeignLayerDisplayItem](../../platform/graphics/paint/foreign_layer_display_item.h)s are used for cc::Layers managed outside blink (e.g., video layers, plugin layers) and are treated as opaque composited content by -the PaintArtifactCompositor. This approach of using foreign layers starts using +the PaintArtifactCompositor. This approach starts using much of the new PaintArtifactCompositor logic (e.g., converting blink property trees to cc property trees) without changing how compositing decisions are made. @@ -292,9 +291,9 @@ |<--------------------------------------------------+ | PaintChunksToCcLayer::Convert() | v | -+----------------+ | -| Foreign layers | | -+----------------+ | ++--------------------------------------------------+ | +| GraphicsLayerDisplayItem/ForeignLayerDisplayItem | | ++--------------------------------------------------+ | | | | LocalFrameView::PushPaintArtifactToCompositor() | | PaintArtifactCompositor::Update() |
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc index ddd84d2..c714e3f 100644 --- a/third_party/blink/renderer/core/style/computed_style.cc +++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -2216,10 +2216,13 @@ if (!::features::IsFormControlsRefreshEnabled()) return 0; - // For FormControlsRefresh checkbox and radio have a 2px inner padding. if (EffectiveAppearance() == kCheckboxPart || - EffectiveAppearance() == kRadioPart) + EffectiveAppearance() == kRadioPart) { return 2; + } else if (IsLink()) { + return 1; + } + return 0; }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index adb0a21..c720070 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -151,7 +151,7 @@ } void AXObjectCacheImpl::InitializePopup(Document* document) { - if (!document || documents_.Contains(document) || document->View()) + if (!document || documents_.Contains(document) || !document->View()) return; documents_.insert(document); @@ -159,7 +159,7 @@ } void AXObjectCacheImpl::DisposePopup(Document* document) { - if (documents_.Contains(document) || document->View()) + if (!documents_.Contains(document) || !document->View()) return; document->View()->UnregisterFromLifecycleNotifications(this);
diff --git a/third_party/blink/renderer/modules/crypto/crypto_histograms.cc b/third_party/blink/renderer/modules/crypto/crypto_histograms.cc index 611c2b3b..c3fe37e 100644 --- a/third_party/blink/renderer/modules/crypto/crypto_histograms.cc +++ b/third_party/blink/renderer/modules/crypto/crypto_histograms.cc
@@ -48,6 +48,10 @@ return WebFeature::kCryptoAlgorithmHkdf; case kWebCryptoAlgorithmIdPbkdf2: return WebFeature::kCryptoAlgorithmPbkdf2; + case kWebCryptoAlgorithmIdX25519: + return WebFeature::kCryptoAlgorithmX25519; + case kWebCryptoAlgorithmIdEd25519: + return WebFeature::kCryptoAlgorithmEd25519; } NOTREACHED(); @@ -100,6 +104,8 @@ case kWebCryptoAlgorithmParamsTypeEcKeyGenParams: case kWebCryptoAlgorithmParamsTypeEcKeyImportParams: case kWebCryptoAlgorithmParamsTypeAesDerivedKeyParams: + case kWebCryptoAlgorithmParamsTypeEd25519Params: + case kWebCryptoAlgorithmParamsTypeX25519KeyDeriveParams: break; } }
diff --git a/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc b/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc index c691635..f862421 100644 --- a/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc +++ b/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc
@@ -75,10 +75,12 @@ {"SHA-1", 5, kWebCryptoAlgorithmIdSha1}, {"ECDSA", 5, kWebCryptoAlgorithmIdEcdsa}, {"PBKDF2", 6, kWebCryptoAlgorithmIdPbkdf2}, + {"X25519", 6, kWebCryptoAlgorithmIdX25519}, {"AES-KW", 6, kWebCryptoAlgorithmIdAesKw}, {"SHA-512", 7, kWebCryptoAlgorithmIdSha512}, {"SHA-384", 7, kWebCryptoAlgorithmIdSha384}, {"SHA-256", 7, kWebCryptoAlgorithmIdSha256}, + {"ED25519", 7, kWebCryptoAlgorithmIdEd25519}, {"AES-CBC", 7, kWebCryptoAlgorithmIdAesCbc}, {"AES-GCM", 7, kWebCryptoAlgorithmIdAesGcm}, {"AES-CTR", 7, kWebCryptoAlgorithmIdAesCtr}, @@ -203,6 +205,14 @@ return false; id = it->algorithm_id; + // TODO(crbug.com/1032821): X25519 and Ed25519 are currently introduced behind + // a flag. + if (!RuntimeEnabledFeatures::WebCryptoCurve25519Enabled() && + (id == kWebCryptoAlgorithmIdEd25519 || + id == kWebCryptoAlgorithmIdX25519)) { + return false; + } + return true; } @@ -839,15 +849,10 @@ return true; } -// Defined by the WebCrypto spec as: -// -// dictionary EcdhKeyDeriveParams : Algorithm { -// required CryptoKey public; -// }; -bool ParseEcdhKeyDeriveParams(const Dictionary& raw, - std::unique_ptr<WebCryptoAlgorithmParams>& params, - const ErrorContext& context, - AlgorithmError* error) { +bool GetPeerPublicKey(const Dictionary& raw, + const ErrorContext& context, + AlgorithmError* error, + WebCryptoKey* peer_public_key) { v8::Local<v8::Value> v8_value; if (!raw.Get("public", v8_value)) { SetTypeError(context.ToString("public", "Missing required property"), @@ -862,7 +867,25 @@ return false; } - params = std::make_unique<WebCryptoEcdhKeyDeriveParams>(crypto_key->Key()); + *peer_public_key = crypto_key->Key(); + return true; +} + +// Defined by the WebCrypto spec as: +// +// dictionary EcdhKeyDeriveParams : Algorithm { +// required CryptoKey public; +// }; +bool ParseEcdhKeyDeriveParams(const Dictionary& raw, + std::unique_ptr<WebCryptoAlgorithmParams>& params, + const ErrorContext& context, + AlgorithmError* error) { + WebCryptoKey peer_public_key; + if (!GetPeerPublicKey(raw, context, error, &peer_public_key)) + return false; + + DCHECK(!peer_public_key.IsNull()); + params = std::make_unique<WebCryptoEcdhKeyDeriveParams>(peer_public_key); return true; } @@ -936,6 +959,47 @@ return true; } +// TODO(crbug.com/1032821): The implementation of Curve25519 algorithms is +// experimental. See also the status on +// https://chromestatus.com/feature/4913922408710144. +// +// Ed25519Params in the prototype assumes the same structure as EcdsaParams: +// +// dictionary Ed25519Params : Algorithm { +// required HashAlgorithmIdentifier hash; +// }; +bool ParseEd25519Params(const Dictionary& raw, + std::unique_ptr<WebCryptoAlgorithmParams>& params, + const ErrorContext& context, + AlgorithmError* error) { + WebCryptoAlgorithm hash; + if (!ParseHash(raw, hash, context, error)) + return false; + + params = std::make_unique<WebCryptoEd25519Params>(hash); + return true; +} + +// TODO(crbug.com/1032821): X25519KeyDeriveParams in the prototype assumes the +// same structure as EcdhKeyDeriveParams: +// +// dictionary X25519KeyDeriveParams : Algorithm { +// required CryptoKey public; +// }; +bool ParseX25519KeyDeriveParams( + const Dictionary& raw, + std::unique_ptr<WebCryptoAlgorithmParams>& params, + const ErrorContext& context, + AlgorithmError* error) { + WebCryptoKey peer_public_key; + if (!GetPeerPublicKey(raw, context, error, &peer_public_key)) + return false; + + DCHECK(!peer_public_key.IsNull()); + params = std::make_unique<WebCryptoX25519KeyDeriveParams>(peer_public_key); + return true; +} + bool ParseAlgorithmParams(const Dictionary& raw, WebCryptoAlgorithmParamsType type, std::unique_ptr<WebCryptoAlgorithmParams>& params, @@ -995,6 +1059,12 @@ case kWebCryptoAlgorithmParamsTypePbkdf2Params: context.Add("Pbkdf2Params"); return ParsePbkdf2Params(raw, params, context, error); + case kWebCryptoAlgorithmParamsTypeEd25519Params: + context.Add("Ed25519Params"); + return ParseEd25519Params(raw, params, context, error); + case kWebCryptoAlgorithmParamsTypeX25519KeyDeriveParams: + context.Add("X25519KeyDeriveParams"); + return ParseX25519KeyDeriveParams(raw, params, context, error); } NOTREACHED(); return false;
diff --git a/third_party/blink/renderer/modules/crypto/subtle_crypto.cc b/third_party/blink/renderer/modules/crypto/subtle_crypto.cc index aebbee1..a81d7a4a 100644 --- a/third_party/blink/renderer/modules/crypto/subtle_crypto.cc +++ b/third_party/blink/renderer/modules/crypto/subtle_crypto.cc
@@ -36,6 +36,7 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/web_crypto.h" #include "third_party/blink/public/platform/web_crypto_algorithm.h" +#include "third_party/blink/public/platform/web_crypto_algorithm_params.h" #include "third_party/blink/renderer/bindings/core/v8/dictionary.h" #include "third_party/blink/renderer/bindings/modules/v8/array_buffer_or_array_buffer_view_or_json_web_key.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" @@ -49,6 +50,7 @@ #include "third_party/blink/renderer/modules/crypto/crypto_utilities.h" #include "third_party/blink/renderer/modules/crypto/normalize_algorithm.h" #include "third_party/blink/renderer/platform/json/json_values.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/xr/BUILD.gn b/third_party/blink/renderer/modules/xr/BUILD.gn index a8bbf40..2bae19df 100644 --- a/third_party/blink/renderer/modules/xr/BUILD.gn +++ b/third_party/blink/renderer/modules/xr/BUILD.gn
@@ -11,8 +11,6 @@ "navigator_xr.h", "type_converters.cc", "type_converters.h", - "xr.cc", - "xr.h", "xr_anchor.cc", "xr_anchor.h", "xr_anchor_set.cc", @@ -83,6 +81,8 @@ "xr_space.h", "xr_spherical_harmonics.cc", "xr_spherical_harmonics.h", + "xr_system.cc", + "xr_system.h", "xr_target_ray_space.cc", "xr_target_ray_space.h", "xr_transient_input_hit_test_result.cc",
diff --git a/third_party/blink/renderer/modules/xr/idls.gni b/third_party/blink/renderer/modules/xr/idls.gni index 05c7a58..242d0ab 100644 --- a/third_party/blink/renderer/modules/xr/idls.gni +++ b/third_party/blink/renderer/modules/xr/idls.gni
@@ -3,7 +3,6 @@ # found in the LICENSE file. modules_idl_files = [ - "xr.idl", "xr_anchor.idl", "xr_anchor_set.idl", "xr_bounded_reference_space.idl", @@ -33,6 +32,7 @@ "xr_session_event.idl", "xr_space.idl", "xr_spherical_harmonics.idl", + "xr_system.idl", "xr_transient_input_hit_test_result.idl", "xr_transient_input_hit_test_source.idl", "xr_view.idl",
diff --git a/third_party/blink/renderer/modules/xr/navigator_xr.cc b/third_party/blink/renderer/modules/xr/navigator_xr.cc index 2038f80..274cf40 100644 --- a/third_party/blink/renderer/modules/xr/navigator_xr.cc +++ b/third_party/blink/renderer/modules/xr/navigator_xr.cc
@@ -10,7 +10,7 @@ #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/navigator.h" #include "third_party/blink/renderer/core/inspector/console_message.h" -#include "third_party/blink/renderer/modules/xr/xr.h" +#include "third_party/blink/renderer/modules/xr/xr_system.h" #include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -33,7 +33,7 @@ return *supplement; } -XR* NavigatorXR::xr(Navigator& navigator) { +XRSystem* NavigatorXR::xr(Navigator& navigator) { // Always return null when the navigator is detached. if (!navigator.GetFrame()) { return nullptr; @@ -42,7 +42,7 @@ return NavigatorXR::From(navigator).xr(); } -XR* NavigatorXR::xr() { +XRSystem* NavigatorXR::xr() { auto* document = GetDocument(); // Always return null when the navigator is detached. @@ -58,8 +58,8 @@ } if (!xr_) { - xr_ = MakeGarbageCollected<XR>(*document->GetFrame(), - document->UkmSourceID()); + xr_ = MakeGarbageCollected<XRSystem>(*document->GetFrame(), + document->UkmSourceID()); } return xr_;
diff --git a/third_party/blink/renderer/modules/xr/navigator_xr.h b/third_party/blink/renderer/modules/xr/navigator_xr.h index 668bcf7..78342d3 100644 --- a/third_party/blink/renderer/modules/xr/navigator_xr.h +++ b/third_party/blink/renderer/modules/xr/navigator_xr.h
@@ -13,7 +13,7 @@ namespace blink { class Document; -class XR; +class XRSystem; class MODULES_EXPORT NavigatorXR final : public GarbageCollected<NavigatorXR>, public Supplement<Navigator> { @@ -27,15 +27,15 @@ explicit NavigatorXR(Navigator&); - static XR* xr(Navigator&); - XR* xr(); + static XRSystem* xr(Navigator&); + XRSystem* xr(); void Trace(Visitor*) override; private: Document* GetDocument(); - Member<XR> xr_; + Member<XRSystem> xr_; // Gates metrics collection once per local DOM window frame. bool did_log_navigator_xr_ = false;
diff --git a/third_party/blink/renderer/modules/xr/navigator_xr.idl b/third_party/blink/renderer/modules/xr/navigator_xr.idl index 2e3f513..9e90ef3 100644 --- a/third_party/blink/renderer/modules/xr/navigator_xr.idl +++ b/third_party/blink/renderer/modules/xr/navigator_xr.idl
@@ -7,5 +7,5 @@ ImplementedAs=NavigatorXR ] partial interface Navigator { // Latest API - [SecureContext, RuntimeEnabled=WebXR, MeasureAs=NavigatorXR, SameObject] readonly attribute XR xr; + [SecureContext, RuntimeEnabled=WebXR, MeasureAs=NavigatorXR, SameObject] readonly attribute XRSystem xr; };
diff --git a/third_party/blink/renderer/modules/xr/xr_anchor.cc b/third_party/blink/renderer/modules/xr/xr_anchor.cc index 2d25428f..f7276ba 100644 --- a/third_party/blink/renderer/modules/xr/xr_anchor.cc +++ b/third_party/blink/renderer/modules/xr/xr_anchor.cc
@@ -4,9 +4,9 @@ #include "third_party/blink/renderer/modules/xr/xr_anchor.h" #include "third_party/blink/renderer/modules/xr/type_converters.h" -#include "third_party/blink/renderer/modules/xr/xr.h" #include "third_party/blink/renderer/modules/xr/xr_object_space.h" #include "third_party/blink/renderer/modules/xr/xr_session.h" +#include "third_party/blink/renderer/modules/xr/xr_system.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc b/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc index 5bc8fd62..2b15f65 100644 --- a/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc +++ b/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc
@@ -8,10 +8,10 @@ #include "third_party/blink/renderer/core/dom/events/native_event_listener.h" #include "third_party/blink/renderer/core/events/pointer_event.h" #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h" -#include "third_party/blink/renderer/modules/xr/xr.h" #include "third_party/blink/renderer/modules/xr/xr_frame_provider.h" #include "third_party/blink/renderer/modules/xr/xr_input_source.h" #include "third_party/blink/renderer/modules/xr/xr_session.h" +#include "third_party/blink/renderer/modules/xr/xr_system.h" #include "third_party/blink/renderer/modules/xr/xr_view.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/xr/xr_frame_provider.cc b/third_party/blink/renderer/modules/xr/xr_frame_provider.cc index 05c0a34..eefe923 100644 --- a/third_party/blink/renderer/modules/xr/xr_frame_provider.cc +++ b/third_party/blink/renderer/modules/xr/xr_frame_provider.cc
@@ -13,10 +13,10 @@ #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" #include "third_party/blink/renderer/core/loader/document_loader.h" -#include "third_party/blink/renderer/modules/xr/xr.h" #include "third_party/blink/renderer/modules/xr/xr_light_estimation_state.h" #include "third_party/blink/renderer/modules/xr/xr_plane_detection_state.h" #include "third_party/blink/renderer/modules/xr/xr_session.h" +#include "third_party/blink/renderer/modules/xr/xr_system.h" #include "third_party/blink/renderer/modules/xr/xr_viewport.h" #include "third_party/blink/renderer/modules/xr/xr_webgl_layer.h" #include "third_party/blink/renderer/modules/xr/xr_world_tracking_state.h" @@ -51,7 +51,7 @@ } // namespace -XRFrameProvider::XRFrameProvider(XR* xr) +XRFrameProvider::XRFrameProvider(XRSystem* xr) : xr_(xr), last_has_focus_(xr->IsFrameFocused()) { frame_transport_ = MakeGarbageCollected<XRFrameTransport>(); }
diff --git a/third_party/blink/renderer/modules/xr/xr_frame_provider.h b/third_party/blink/renderer/modules/xr/xr_frame_provider.h index 8a659e5..6ed8d94 100644 --- a/third_party/blink/renderer/modules/xr/xr_frame_provider.h +++ b/third_party/blink/renderer/modules/xr/xr_frame_provider.h
@@ -14,16 +14,16 @@ namespace blink { -class XR; -class XRSession; class XRFrameTransport; +class XRSession; +class XRSystem; class XRWebGLLayer; // This class manages requesting and dispatching frame updates, which includes // pose information for a given XRDevice. class XRFrameProvider final : public GarbageCollected<XRFrameProvider> { public: - explicit XRFrameProvider(XR*); + explicit XRFrameProvider(XRSystem*); XRSession* immersive_session() const { return immersive_session_; } @@ -72,7 +72,7 @@ void ProcessScheduledFrame(device::mojom::blink::XRFrameDataPtr frame_data, double high_res_now_ms); - const Member<XR> xr_; + const Member<XRSystem> xr_; // Immersive session state Member<XRSession> immersive_session_;
diff --git a/third_party/blink/renderer/modules/xr/xr_input_source.cc b/third_party/blink/renderer/modules/xr/xr_input_source.cc index ce7994d..676bfdfa 100644 --- a/third_party/blink/renderer/modules/xr/xr_input_source.cc +++ b/third_party/blink/renderer/modules/xr/xr_input_source.cc
@@ -12,12 +12,12 @@ #include "third_party/blink/renderer/core/html/html_frame_element_base.h" #include "third_party/blink/renderer/core/input/event_handling_util.h" #include "third_party/blink/renderer/core/layout/hit_test_location.h" -#include "third_party/blink/renderer/modules/xr/xr.h" #include "third_party/blink/renderer/modules/xr/xr_grip_space.h" #include "third_party/blink/renderer/modules/xr/xr_input_source_event.h" #include "third_party/blink/renderer/modules/xr/xr_session.h" #include "third_party/blink/renderer/modules/xr/xr_session_event.h" #include "third_party/blink/renderer/modules/xr/xr_space.h" +#include "third_party/blink/renderer/modules/xr/xr_system.h" #include "third_party/blink/renderer/modules/xr/xr_target_ray_space.h" #include "third_party/blink/renderer/modules/xr/xr_utils.h"
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc index 34efa7f..ae7c3d8 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.cc +++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -28,7 +28,6 @@ #include "third_party/blink/renderer/modules/event_target_modules.h" #include "third_party/blink/renderer/modules/screen_orientation/screen_orientation.h" #include "third_party/blink/renderer/modules/xr/type_converters.h" -#include "third_party/blink/renderer/modules/xr/xr.h" #include "third_party/blink/renderer/modules/xr/xr_anchor_set.h" #include "third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h" #include "third_party/blink/renderer/modules/xr/xr_canvas_input_provider.h" @@ -43,6 +42,7 @@ #include "third_party/blink/renderer/modules/xr/xr_reference_space.h" #include "third_party/blink/renderer/modules/xr/xr_render_state.h" #include "third_party/blink/renderer/modules/xr/xr_session_event.h" +#include "third_party/blink/renderer/modules/xr/xr_system.h" #include "third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h" #include "third_party/blink/renderer/modules/xr/xr_view.h" #include "third_party/blink/renderer/modules/xr/xr_webgl_layer.h" @@ -301,7 +301,7 @@ } XRSession::XRSession( - XR* xr, + XRSystem* xr, mojo::PendingReceiver<device::mojom::blink::XRSessionClient> client_receiver, device::mojom::blink::XRSessionMode mode,
diff --git a/third_party/blink/renderer/modules/xr/xr_session.h b/third_party/blink/renderer/modules/xr/xr_session.h index 236c679..585782fce 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.h +++ b/third_party/blink/renderer/modules/xr/xr_session.h
@@ -36,7 +36,6 @@ class ResizeObserver; class ScriptPromiseResolver; class V8XRFrameRequestCallback; -class XR; class XRAnchor; class XRAnchorSet; class XRCanvasInputProvider; @@ -47,6 +46,7 @@ class XRRenderState; class XRRenderStateInit; class XRSpace; +class XRSystem; class XRTransientInputHitTestOptionsInit; class XRTransientInputHitTestSource; class XRViewData; @@ -96,7 +96,7 @@ HashSet<device::mojom::blink::XRSessionFeature> reported_features_; }; - XRSession(XR* xr, + XRSession(XRSystem* xr, mojo::PendingReceiver<device::mojom::blink::XRSessionClient> client_receiver, device::mojom::blink::XRSessionMode mode, @@ -106,7 +106,7 @@ XRSessionFeatureSet enabled_features); ~XRSession() override = default; - XR* xr() const { return xr_; } + XRSystem* xr() const { return xr_; } const String& environmentBlendMode() const { return blend_mode_string_; } XRDOMOverlayState* domOverlayState() const { return dom_overlay_state_; } const String visibilityState() const; @@ -367,7 +367,7 @@ void HandleShutdown(); - const Member<XR> xr_; + const Member<XRSystem> xr_; const device::mojom::blink::XRSessionMode mode_; const bool environment_integration_; String blend_mode_string_;
diff --git a/third_party/blink/renderer/modules/xr/xr.cc b/third_party/blink/renderer/modules/xr/xr_system.cc similarity index 88% rename from third_party/blink/renderer/modules/xr/xr.cc rename to third_party/blink/renderer/modules/xr/xr_system.cc index 0f8cea15..1e86019e6 100644 --- a/third_party/blink/renderer/modules/xr/xr.cc +++ b/third_party/blink/renderer/modules/xr/xr_system.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/modules/xr/xr.h" +#include "third_party/blink/renderer/modules/xr/xr_system.h" #include <utility> @@ -55,8 +55,8 @@ const char kNoDevicesMessage[] = "No XR hardware found."; const char kImmersiveArModeNotValid[] = - "Failed to execute '%s' on 'XR': The provided value 'immersive-ar' is not " - "a valid enum value of type XRSessionMode."; + "Failed to execute '%s' on 'XRSystem': The provided value 'immersive-ar' " + "is not a valid enum value of type XRSessionMode."; constexpr device::mojom::XRSessionFeature kDefaultImmersiveVrFeatures[] = { device::mojom::XRSessionFeature::REF_SPACE_VIEWER, @@ -203,7 +203,7 @@ // Ensure that the inline session request is allowed, if not // return which security error occurred. // https://immersive-web.github.io/webxr/#inline-session-request-is-allowed -const char* XR::CheckInlineSessionRequestAllowed( +const char* XRSystem::CheckInlineSessionRequestAllowed( LocalFrame* frame, const PendingRequestSessionQuery& query) { // Without user activation, we must reject the session if *any* features @@ -232,7 +232,7 @@ return nullptr; } -XR::PendingSupportsSessionQuery::PendingSupportsSessionQuery( +XRSystem::PendingSupportsSessionQuery::PendingSupportsSessionQuery( ScriptPromiseResolver* resolver, device::mojom::blink::XRSessionMode session_mode, bool throw_on_unsupported) @@ -240,12 +240,13 @@ mode_(session_mode), throw_on_unsupported_(throw_on_unsupported) {} -void XR::PendingSupportsSessionQuery::Trace(Visitor* visitor) { +void XRSystem::PendingSupportsSessionQuery::Trace(Visitor* visitor) { visitor->Trace(resolver_); } -void XR::PendingSupportsSessionQuery::Resolve(bool supported, - ExceptionState* exception_state) { +void XRSystem::PendingSupportsSessionQuery::Resolve( + bool supported, + ExceptionState* exception_state) { if (throw_on_unsupported_) { if (supported) { resolver_->Resolve(); @@ -259,7 +260,7 @@ } } -void XR::PendingSupportsSessionQuery::RejectWithDOMException( +void XRSystem::PendingSupportsSessionQuery::RejectWithDOMException( DOMExceptionCode exception_code, const String& message, ExceptionState* exception_state) { @@ -277,7 +278,7 @@ } } -void XR::PendingSupportsSessionQuery::RejectWithSecurityError( +void XRSystem::PendingSupportsSessionQuery::RejectWithSecurityError( const String& sanitized_message, ExceptionState* exception_state) { if (exception_state) { @@ -292,7 +293,7 @@ } } -void XR::PendingSupportsSessionQuery::RejectWithTypeError( +void XRSystem::PendingSupportsSessionQuery::RejectWithTypeError( const String& message, ExceptionState* exception_state) { if (exception_state) { @@ -307,12 +308,12 @@ } } -device::mojom::blink::XRSessionMode XR::PendingSupportsSessionQuery::mode() - const { +device::mojom::blink::XRSessionMode +XRSystem::PendingSupportsSessionQuery::mode() const { return mode_; } -XR::PendingRequestSessionQuery::PendingRequestSessionQuery( +XRSystem::PendingRequestSessionQuery::PendingRequestSessionQuery( int64_t ukm_source_id, ScriptPromiseResolver* resolver, device::mojom::blink::XRSessionMode session_mode, @@ -326,7 +327,7 @@ ParseSensorRequirement(); } -void XR::PendingRequestSessionQuery::Resolve( +void XRSystem::PendingRequestSessionQuery::Resolve( XRSession* session, mojo::PendingRemote<device::mojom::blink::XRSessionMetricsRecorder> metrics_recorder) { @@ -335,7 +336,7 @@ std::move(metrics_recorder)); } -void XR::PendingRequestSessionQuery::RejectWithDOMException( +void XRSystem::PendingRequestSessionQuery::RejectWithDOMException( DOMExceptionCode exception_code, const String& message, ExceptionState* exception_state) { @@ -352,7 +353,7 @@ ReportRequestSessionResult(SessionRequestStatus::kOtherError); } -void XR::PendingRequestSessionQuery::RejectWithSecurityError( +void XRSystem::PendingRequestSessionQuery::RejectWithSecurityError( const String& sanitized_message, ExceptionState* exception_state) { if (exception_state) { @@ -366,7 +367,7 @@ ReportRequestSessionResult(SessionRequestStatus::kOtherError); } -void XR::PendingRequestSessionQuery::RejectWithTypeError( +void XRSystem::PendingRequestSessionQuery::RejectWithTypeError( const String& message, ExceptionState* exception_state) { if (exception_state) { @@ -381,7 +382,7 @@ } device::mojom::XRSessionFeatureRequestStatus -XR::PendingRequestSessionQuery::GetFeatureRequestStatus( +XRSystem::PendingRequestSessionQuery::GetFeatureRequestStatus( device::mojom::XRSessionFeature feature, const XRSession* session) const { using device::mojom::XRSessionFeatureRequestStatus; @@ -403,7 +404,7 @@ return XRSessionFeatureRequestStatus::kNotRequested; } -void XR::PendingRequestSessionQuery::ReportRequestSessionResult( +void XRSystem::PendingRequestSessionQuery::ReportRequestSessionResult( SessionRequestStatus status, XRSession* session, mojo::PendingRemote<device::mojom::blink::XRSessionMetricsRecorder> @@ -456,34 +457,34 @@ } } -device::mojom::blink::XRSessionMode XR::PendingRequestSessionQuery::mode() +device::mojom::blink::XRSessionMode XRSystem::PendingRequestSessionQuery::mode() const { return mode_; } -const XRSessionFeatureSet& XR::PendingRequestSessionQuery::RequiredFeatures() - const { +const XRSessionFeatureSet& +XRSystem::PendingRequestSessionQuery::RequiredFeatures() const { return required_features_.valid_features; } -const XRSessionFeatureSet& XR::PendingRequestSessionQuery::OptionalFeatures() - const { +const XRSessionFeatureSet& +XRSystem::PendingRequestSessionQuery::OptionalFeatures() const { return optional_features_.valid_features; } -bool XR::PendingRequestSessionQuery::InvalidRequiredFeatures() const { +bool XRSystem::PendingRequestSessionQuery::InvalidRequiredFeatures() const { return required_features_.invalid_features; } -bool XR::PendingRequestSessionQuery::InvalidOptionalFeatures() const { +bool XRSystem::PendingRequestSessionQuery::InvalidOptionalFeatures() const { return optional_features_.invalid_features; } -ScriptState* XR::PendingRequestSessionQuery::GetScriptState() const { +ScriptState* XRSystem::PendingRequestSessionQuery::GetScriptState() const { return resolver_->GetScriptState(); } -void XR::PendingRequestSessionQuery::ParseSensorRequirement() { +void XRSystem::PendingRequestSessionQuery::ParseSensorRequirement() { // All modes other than inline require sensors. if (mode_ != device::mojom::blink::XRSessionMode::kInline) { sensor_requirement_ = SensorRequirement::kRequired; @@ -510,22 +511,23 @@ sensor_requirement_ = kNone; } -void XR::PendingRequestSessionQuery::Trace(Visitor* visitor) { +void XRSystem::PendingRequestSessionQuery::Trace(Visitor* visitor) { visitor->Trace(resolver_); visitor->Trace(dom_overlay_element_); } -XR::OverlayFullscreenEventManager::OverlayFullscreenEventManager( - XR* xr, - XR::PendingRequestSessionQuery* query, +XRSystem::OverlayFullscreenEventManager::OverlayFullscreenEventManager( + XRSystem* xr, + XRSystem::PendingRequestSessionQuery* query, device::mojom::blink::RequestSessionResultPtr result) : xr_(xr), query_(query), result_(std::move(result)) { DVLOG(2) << __func__; } -XR::OverlayFullscreenEventManager::~OverlayFullscreenEventManager() = default; +XRSystem::OverlayFullscreenEventManager::~OverlayFullscreenEventManager() = + default; -void XR::OverlayFullscreenEventManager::Invoke( +void XRSystem::OverlayFullscreenEventManager::Invoke( ExecutionContext* execution_context, Event* event) { DVLOG(2) << __func__ << ": event type=" << event->type(); @@ -554,7 +556,7 @@ } } -void XR::OverlayFullscreenEventManager::RequestFullscreen() { +void XRSystem::OverlayFullscreenEventManager::RequestFullscreen() { Element* element = query_->DOMOverlayElement(); DCHECK(element); @@ -593,20 +595,22 @@ Fullscreen::RequestType::kUnprefixed); } -void XR::OverlayFullscreenEventManager::Trace(Visitor* visitor) { +void XRSystem::OverlayFullscreenEventManager::Trace(Visitor* visitor) { visitor->Trace(xr_); visitor->Trace(query_); EventListener::Trace(visitor); } -XR::OverlayFullscreenExitObserver::OverlayFullscreenExitObserver(XR* xr) +XRSystem::OverlayFullscreenExitObserver::OverlayFullscreenExitObserver( + XRSystem* xr) : xr_(xr) { DVLOG(2) << __func__; } -XR::OverlayFullscreenExitObserver::~OverlayFullscreenExitObserver() = default; +XRSystem::OverlayFullscreenExitObserver::~OverlayFullscreenExitObserver() = + default; -void XR::OverlayFullscreenExitObserver::Invoke( +void XRSystem::OverlayFullscreenExitObserver::Invoke( ExecutionContext* execution_context, Event* event) { DVLOG(2) << __func__ << ": event type=" << event->type(); @@ -620,7 +624,7 @@ } } -void XR::OverlayFullscreenExitObserver::ExitFullscreen( +void XRSystem::OverlayFullscreenExitObserver::ExitFullscreen( Element* element, base::OnceClosure on_exited) { DVLOG(2) << __func__; @@ -640,13 +644,13 @@ Fullscreen::FullyExitFullscreen(element_->GetDocument(), kUaOriginated); } -void XR::OverlayFullscreenExitObserver::Trace(Visitor* visitor) { +void XRSystem::OverlayFullscreenExitObserver::Trace(Visitor* visitor) { visitor->Trace(xr_); visitor->Trace(element_); EventListener::Trace(visitor); } -device::mojom::blink::XRSessionOptionsPtr XR::XRSessionOptionsFromQuery( +device::mojom::blink::XRSessionOptionsPtr XRSystem::XRSessionOptionsFromQuery( const PendingRequestSessionQuery& query) { device::mojom::blink::XRSessionOptionsPtr session_options = device::mojom::blink::XRSessionOptions::New(); @@ -658,7 +662,7 @@ return session_options; } -XR::XR(LocalFrame& frame, int64_t ukm_source_id) +XRSystem::XRSystem(LocalFrame& frame, int64_t ukm_source_id) : ExecutionContextLifecycleObserver(frame.GetDocument()), FocusChangedObserver(frame.GetPage()), ukm_source_id_(ukm_source_id), @@ -672,11 +676,12 @@ frame.GetBrowserInterfaceBroker().GetInterface( service_.BindNewPipeAndPassReceiver( frame.GetTaskRunner(TaskType::kMiscPlatformAPI))); - service_.set_disconnect_handler(WTF::Bind( - &XR::Dispose, WrapWeakPersistent(this), DisposeType::kDisconnected)); + service_.set_disconnect_handler(WTF::Bind(&XRSystem::Dispose, + WrapWeakPersistent(this), + DisposeType::kDisconnected)); } -void XR::FocusedFrameChanged() { +void XRSystem::FocusedFrameChanged() { // Tell all sessions that focus changed. for (const auto& session : sessions_) { session->OnFocusChanged(); @@ -686,19 +691,19 @@ frame_provider_->OnFocusChanged(); } -bool XR::IsFrameFocused() { +bool XRSystem::IsFrameFocused() { return FocusChangedObserver::IsFrameFocused(GetFrame()); } -ExecutionContext* XR::GetExecutionContext() const { +ExecutionContext* XRSystem::GetExecutionContext() const { return ExecutionContextLifecycleObserver::GetExecutionContext(); } -const AtomicString& XR::InterfaceName() const { +const AtomicString& XRSystem::InterfaceName() const { return event_target_names::kXR; } -XRFrameProvider* XR::frameProvider() { +XRFrameProvider* XRSystem::frameProvider() { if (!frame_provider_) { frame_provider_ = MakeGarbageCollected<XRFrameProvider>(this); } @@ -708,16 +713,16 @@ const mojo::AssociatedRemote< device::mojom::blink::XREnvironmentIntegrationProvider>& -XR::xrEnvironmentProviderRemote() { +XRSystem::xrEnvironmentProviderRemote() { return environment_provider_; } -void XR::AddEnvironmentProviderErrorHandler( +void XRSystem::AddEnvironmentProviderErrorHandler( EnvironmentProviderErrorCallback callback) { environment_provider_error_callbacks_.push_back(std::move(callback)); } -void XR::ExitPresent(base::OnceClosure on_exited) { +void XRSystem::ExitPresent(base::OnceClosure on_exited) { DVLOG(1) << __func__; // If the document was potentially being shown in a DOM overlay via @@ -770,7 +775,7 @@ } } -void XR::SetFramesThrottled(const XRSession* session, bool throttled) { +void XRSystem::SetFramesThrottled(const XRSession* session, bool throttled) { // The service only cares if the immersive session is throttling frames. if (session->immersive()) { // If we have an immersive session, we should have a service. @@ -779,22 +784,23 @@ } } -ScriptPromise XR::supportsSession(ScriptState* script_state, - const String& mode, - ExceptionState& exception_state) { +ScriptPromise XRSystem::supportsSession(ScriptState* script_state, + const String& mode, + ExceptionState& exception_state) { return InternalIsSessionSupported(script_state, mode, exception_state, true); } -ScriptPromise XR::isSessionSupported(ScriptState* script_state, - const String& mode, - ExceptionState& exception_state) { +ScriptPromise XRSystem::isSessionSupported(ScriptState* script_state, + const String& mode, + ExceptionState& exception_state) { return InternalIsSessionSupported(script_state, mode, exception_state, false); } -ScriptPromise XR::InternalIsSessionSupported(ScriptState* script_state, - const String& mode, - ExceptionState& exception_state, - bool throw_on_unsupported) { +ScriptPromise XRSystem::InternalIsSessionSupported( + ScriptState* script_state, + const String& mode, + ExceptionState& exception_state, + bool throw_on_unsupported) { LocalFrame* frame = GetFrame(); Document* doc = frame ? frame->GetDocument() : nullptr; if (!doc) { @@ -849,16 +855,16 @@ outstanding_support_queries_.insert(query); service_->SupportsSession( std::move(session_options), - WTF::Bind(&XR::OnSupportsSessionReturned, WrapPersistent(this), + WTF::Bind(&XRSystem::OnSupportsSessionReturned, WrapPersistent(this), WrapPersistent(query))); return promise; } -void XR::RequestImmersiveSession(LocalFrame* frame, - Document* doc, - PendingRequestSessionQuery* query, - ExceptionState* exception_state) { +void XRSystem::RequestImmersiveSession(LocalFrame* frame, + Document* doc, + PendingRequestSessionQuery* query, + ExceptionState* exception_state) { DVLOG(2) << __func__; // Log an immersive session request if we haven't already if (!did_log_request_immersive_session_) { @@ -914,16 +920,16 @@ // browser side to send an event indicating success or failure. auto callback = query->DOMOverlayElement() - ? WTF::Bind(&XR::OnRequestSessionSetupForDomOverlay, + ? WTF::Bind(&XRSystem::OnRequestSessionSetupForDomOverlay, WrapWeakPersistent(this), WrapPersistent(query)) - : WTF::Bind(&XR::OnRequestSessionReturned, WrapWeakPersistent(this), - WrapPersistent(query)); + : WTF::Bind(&XRSystem::OnRequestSessionReturned, + WrapWeakPersistent(this), WrapPersistent(query)); service_->RequestSession(std::move(session_options), std::move(callback)); } -void XR::RequestInlineSession(LocalFrame* frame, - PendingRequestSessionQuery* query, - ExceptionState* exception_state) { +void XRSystem::RequestInlineSession(LocalFrame* frame, + PendingRequestSessionQuery* query, + ExceptionState* exception_state) { DVLOG(2) << __func__; // Make sure the inline session request was allowed auto* inline_session_request_error = @@ -965,11 +971,11 @@ auto session_options = XRSessionOptionsFromQuery(*query); service_->RequestSession( std::move(session_options), - WTF::Bind(&XR::OnRequestSessionReturned, WrapWeakPersistent(this), + WTF::Bind(&XRSystem::OnRequestSessionReturned, WrapWeakPersistent(this), WrapPersistent(query))); } -XR::RequestedXRSessionFeatureSet XR::ParseRequestedFeatures( +XRSystem::RequestedXRSessionFeatureSet XRSystem::ParseRequestedFeatures( Document* doc, const HeapVector<ScriptValue>& features, const device::mojom::blink::XRSessionMode& session_mode, @@ -1021,10 +1027,10 @@ return result; } -ScriptPromise XR::requestSession(ScriptState* script_state, - const String& mode, - XRSessionInit* session_init, - ExceptionState& exception_state) { +ScriptPromise XRSystem::requestSession(ScriptState* script_state, + const String& mode, + XRSessionInit* session_init, + ExceptionState& exception_state) { DVLOG(2) << __func__; // TODO(https://crbug.com/968622): Make sure we don't forget to call // metrics-related methods when the promise gets resolved/rejected. @@ -1126,7 +1132,7 @@ // This will be called when the XR hardware or capabilities have potentially // changed. For example, if a new physical device was connected to the system, // it might be able to support immersive sessions, where it couldn't before. -void XR::OnDeviceChanged() { +void XRSystem::OnDeviceChanged() { LocalFrame* frame = GetFrame(); Document* doc = frame ? frame->GetDocument() : nullptr; if (doc && @@ -1135,8 +1141,8 @@ } } -void XR::OnSupportsSessionReturned(PendingSupportsSessionQuery* query, - bool supports_session) { +void XRSystem::OnSupportsSessionReturned(PendingSupportsSessionQuery* query, + bool supports_session) { // The session query has returned and we're about to resolve or reject the // promise, so remove it from our outstanding list. DCHECK(outstanding_support_queries_.Contains(query)); @@ -1144,7 +1150,7 @@ query->Resolve(supports_session); } -void XR::OnRequestSessionSetupForDomOverlay( +void XRSystem::OnRequestSessionSetupForDomOverlay( PendingRequestSessionQuery* query, device::mojom::blink::RequestSessionResultPtr result) { DCHECK(query->DOMOverlayElement()); @@ -1161,7 +1167,7 @@ } } -void XR::OnRequestSessionReturned( +void XRSystem::OnRequestSessionReturned( PendingRequestSessionQuery* query, device::mojom::blink::RequestSessionResultPtr result) { // The session query has returned and we're about to resolve or reject the @@ -1237,8 +1243,9 @@ environment_provider_.BindNewEndpointAndPassReceiver( GetExecutionContext()->GetTaskRunner( TaskType::kMiscPlatformAPI))); - environment_provider_.set_disconnect_handler(WTF::Bind( - &XR::OnEnvironmentProviderDisconnect, WrapWeakPersistent(this))); + environment_provider_.set_disconnect_handler( + WTF::Bind(&XRSystem::OnEnvironmentProviderDisconnect, + WrapWeakPersistent(this))); session->OnEnvironmentProviderCreated(); @@ -1279,7 +1286,7 @@ query->Resolve(session, std::move(metrics_recorder)); } -void XR::ReportImmersiveSupported(bool supported) { +void XRSystem::ReportImmersiveSupported(bool supported) { Document* doc = GetFrame() ? GetFrame()->GetDocument() : nullptr; if (doc && !did_log_supports_immersive_ && supported) { ukm::builders::XR_WebXR ukm_builder(ukm_source_id_); @@ -1289,8 +1296,9 @@ } } -void XR::AddedEventListener(const AtomicString& event_type, - RegisteredEventListener& registered_listener) { +void XRSystem::AddedEventListener( + const AtomicString& event_type, + RegisteredEventListener& registered_listener) { EventTargetWithInlineData::AddedEventListener(event_type, registered_listener); @@ -1308,12 +1316,12 @@ } } -void XR::ContextDestroyed() { +void XRSystem::ContextDestroyed() { Dispose(DisposeType::kContextDestroyed); } // A session is always created and returned. -XRSession* XR::CreateSession( +XRSession* XRSystem::CreateSession( device::mojom::blink::XRSessionMode mode, XRSession::EnvironmentBlendMode blend_mode, mojo::PendingReceiver<device::mojom::blink::XRSessionClient> @@ -1331,7 +1339,7 @@ return session; } -XRSession* XR::CreateSensorlessInlineSession() { +XRSession* XRSystem::CreateSensorlessInlineSession() { // TODO(https://crbug.com/944936): The blend mode could be "additive". XRSession::EnvironmentBlendMode blend_mode = XRSession::kBlendModeOpaque; return CreateSession(device::mojom::blink::XRSessionMode::kInline, blend_mode, @@ -1342,7 +1350,7 @@ true /* sensorless_session */); } -void XR::Dispose(DisposeType dispose_type) { +void XRSystem::Dispose(DisposeType dispose_type) { switch (dispose_type) { case DisposeType::kContextDestroyed: is_context_destroyed_ = true; @@ -1380,7 +1388,7 @@ DCHECK(outstanding_support_queries_.IsEmpty()); } -void XR::OnEnvironmentProviderDisconnect() { +void XRSystem::OnEnvironmentProviderDisconnect() { for (auto& callback : environment_provider_error_callbacks_) { std::move(callback).Run(); } @@ -1389,7 +1397,7 @@ environment_provider_.reset(); } -void XR::Trace(Visitor* visitor) { +void XRSystem::Trace(Visitor* visitor) { visitor->Trace(frame_provider_); visitor->Trace(sessions_); visitor->Trace(outstanding_support_queries_);
diff --git a/third_party/blink/renderer/modules/xr/xr.h b/third_party/blink/renderer/modules/xr/xr_system.h similarity index 88% rename from third_party/blink/renderer/modules/xr/xr.h rename to third_party/blink/renderer/modules/xr/xr_system.h index cbf8abd..4a1258d 100644 --- a/third_party/blink/renderer/modules/xr/xr.h +++ b/third_party/blink/renderer/modules/xr/xr_system.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 THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SYSTEM_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SYSTEM_H_ #include "device/vr/public/mojom/vr_service.mojom-blink.h" #include "mojo/public/cpp/bindings/associated_remote.h" @@ -31,43 +31,43 @@ class XRFrameProvider; class XRSessionInit; -// Implementation of the XR interface according to -// https://immersive-web.github.io/webxr/#xr-interface . This is created lazily -// via the NavigatorXR class on first access to the navigator.xr attribute, and -// disposed when the execution context is destroyed or on mojo communication +// Implementation of the XRSystem interface according to +// https://immersive-web.github.io/webxr/#xrsystem-interface . This is created +// lazily via the NavigatorXR class on first access to the navigator.xr attrib, +// and disposed when the execution context is destroyed or on mojo communication // errors with the browser/device process. // -// When the XR object is used for promises, it uses query objects to store state +// When the XRSystem is used for promises, it uses query objects to store state // including the associated ScriptPromiseResolver. These query objects are owned -// by the XR object and remain alive until the promise is resolved or rejected. +// by the XRSystem and remain alive until the promise is resolved or rejected. // (See comments below for PendingSupportsSessionQuery and // PendingRequestSessionQuery.) These query objects are destroyed and any -// outstanding promises rejected when the XR object is disposed. +// outstanding promises rejected when the XRSystem is disposed. // -// The XR object owns mojo connections with the Browser process through +// The XRSystem owns mojo connections with the Browser process through // VRService, used for capability queries and session lifetime -// management. The XR object is also the receiver for the VRServiceClient. +// management. The XRSystem is also the receiver for the VRServiceClient. // -// The XR object owns mojo connections with the Device process (either a +// The XRSystem owns mojo connections with the Device process (either a // separate utility process, or implemented as part of the Browser process, // depending on the runtime and options) through XRFrameProvider and // XREnvironmentIntegrationProvider. These are used to transport per-frame data // such as image data and input poses. These are lazily created when first // needed for a sensor-backed session (all except sensorless inline sessions), -// and destroyed when the XR object is disposed. +// and destroyed when the XRSystem is disposed. // -// The XR object keeps weak references to XRSession objects after they were +// The XRSystem keeps weak references to XRSession objects after they were // returned through a successful requestSession promise, but does not own them. -class XR final : public EventTargetWithInlineData, - public ExecutionContextLifecycleObserver, - public device::mojom::blink::VRServiceClient, - public FocusChangedObserver { +class XRSystem final : public EventTargetWithInlineData, + public ExecutionContextLifecycleObserver, + public device::mojom::blink::VRServiceClient, + public FocusChangedObserver { DEFINE_WRAPPERTYPEINFO(); - USING_GARBAGE_COLLECTED_MIXIN(XR); + USING_GARBAGE_COLLECTED_MIXIN(XRSystem); public: // TODO(crbug.com/976796): Fix lint errors. - XR(LocalFrame& frame, int64_t ukm_source_id); + XRSystem(LocalFrame& frame, int64_t ukm_source_id); DEFINE_ATTRIBUTE_EVENT_LISTENER(devicechange, kDevicechange) @@ -144,10 +144,10 @@ bool invalid_features = false; }; - // Encapsulates blink-side `XR::requestSession()` call. It is a wrapper around - // ScriptPromiseResolver that allows us to add additional logic as certain - // things related to promise's life cycle happen. Instances are owned - // by the XR object, see outstanding_request_queries_ below. + // Encapsulates blink-side `XRSystem::requestSession()` call. It is a wrapper + // around ScriptPromiseResolver that allows us to add additional logic as + // certain things related to promise's life cycle happen. Instances are owned + // by the XRSystem, see outstanding_request_queries_ below. class PendingRequestSessionQuery final : public GarbageCollected<PendingRequestSessionQuery> { public: @@ -233,10 +233,10 @@ static device::mojom::blink::XRSessionOptionsPtr XRSessionOptionsFromQuery( const PendingRequestSessionQuery& query); - // Encapsulates blink-side `XR::isSessionSupported()` call. It is a wrapper - // around ScriptPromiseResolver that allows us to add additional logic as - // certain things related to promise's life cycle happen. Instances are owned - // by the XR object, see outstanding_support_queries_ below. + // Encapsulates blink-side `XRSystem::isSessionSupported()` call. It is a + // wrapper around ScriptPromiseResolver that allows us to add additional logic + // as certain things related to promise's life cycle happen. Instances are + // owned by the XRSystem, see outstanding_support_queries_ below. class PendingSupportsSessionQuery final : public GarbageCollected<PendingSupportsSessionQuery> { public: @@ -291,8 +291,8 @@ class OverlayFullscreenEventManager : public NativeEventListener { public: OverlayFullscreenEventManager( - XR* xr, - XR::PendingRequestSessionQuery*, + XRSystem* xr, + XRSystem::PendingRequestSessionQuery*, device::mojom::blink::RequestSessionResultPtr); ~OverlayFullscreenEventManager() override; @@ -305,7 +305,7 @@ void Trace(Visitor*) override; private: - Member<XR> xr_; + Member<XRSystem> xr_; Member<PendingRequestSessionQuery> query_; device::mojom::blink::RequestSessionResultPtr result_; DISALLOW_COPY_AND_ASSIGN(OverlayFullscreenEventManager); @@ -315,7 +315,7 @@ // when ending an XR session. class OverlayFullscreenExitObserver : public NativeEventListener { public: - OverlayFullscreenExitObserver(XR* xr); + OverlayFullscreenExitObserver(XRSystem* xr); ~OverlayFullscreenExitObserver() override; // NativeEventListener @@ -326,7 +326,7 @@ void Trace(Visitor*) override; private: - Member<XR> xr_; + Member<XRSystem> xr_; Member<Element> element_; base::OnceClosure on_exited_; DISALLOW_COPY_AND_ASSIGN(OverlayFullscreenExitObserver); @@ -444,4 +444,4 @@ } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SYSTEM_H_
diff --git a/third_party/blink/renderer/modules/xr/xr.idl b/third_party/blink/renderer/modules/xr/xr_system.idl similarity index 79% rename from third_party/blink/renderer/modules/xr/xr.idl rename to third_party/blink/renderer/modules/xr/xr_system.idl index a0abb7a..31a25a0 100644 --- a/third_party/blink/renderer/modules/xr/xr.idl +++ b/third_party/blink/renderer/modules/xr/xr_system.idl
@@ -2,14 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://immersive-web.github.io/webxr/#xr-interface +// https://immersive-web.github.io/webxr/#xrsystem-interface [ SecureContext, Exposed=Window, RuntimeEnabled=WebXR -] interface XR : EventTarget { +] interface XRSystem : EventTarget { attribute EventHandler ondevicechange; [CallWith=ScriptState, DeprecateAs=XRSupportsSession, RaisesException] Promise<void> supportsSession(XRSessionMode mode); [CallWith=ScriptState, MeasureAs=XRIsSessionSupported, RaisesException] Promise<boolean> isSessionSupported(XRSessionMode mode); [CallWith=ScriptState, MeasureAs=XRRequestSession, RaisesException] Promise<XRSession> requestSession(XRSessionMode mode, optional XRSessionInit options = {}); }; + +// For backwards compatibility with previous interface name. +typedef XRSystem XR;
diff --git a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc index b395d86..d3f0c0d 100644 --- a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc +++ b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
@@ -9,9 +9,9 @@ #include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h" #include "third_party/blink/renderer/modules/webgl/webgl_framebuffer.h" #include "third_party/blink/renderer/modules/webgl/webgl_rendering_context.h" -#include "third_party/blink/renderer/modules/xr/xr.h" #include "third_party/blink/renderer/modules/xr/xr_frame_provider.h" #include "third_party/blink/renderer/modules/xr/xr_session.h" +#include "third_party/blink/renderer/modules/xr/xr_system.h" #include "third_party/blink/renderer/modules/xr/xr_view.h" #include "third_party/blink/renderer/modules/xr/xr_viewport.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h"
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 3913841..493ddb4 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1032,6 +1032,8 @@ "graphics/paint/geometry_mapper_clip_cache.h", "graphics/paint/geometry_mapper_transform_cache.cc", "graphics/paint/geometry_mapper_transform_cache.h", + "graphics/paint/graphics_layer_display_item.cc", + "graphics/paint/graphics_layer_display_item.h", "graphics/paint/hit_test_data.cc", "graphics/paint/hit_test_data.h", "graphics/paint/hit_test_display_item.cc", @@ -1190,6 +1192,7 @@ "mediastream/audio_service_audio_processor_proxy.h", "mediastream/media_constraints.cc", "mediastream/media_constraints.h", + "mediastream/media_stream_audio_deliverer.h", "mediastream/media_stream_audio_level_calculator.cc", "mediastream/media_stream_audio_level_calculator.h", "mediastream/media_stream_audio_processor_options.cc",
diff --git a/third_party/blink/renderer/platform/exported/web_crypto_algorithm.cc b/third_party/blink/renderer/platform/exported/web_crypto_algorithm.cc index 67b793f..1628116 100644 --- a/third_party/blink/renderer/platform/exported/web_crypto_algorithm.cc +++ b/third_party/blink/renderer/platform/exported/web_crypto_algorithm.cc
@@ -286,6 +286,40 @@ WebCryptoAlgorithmInfo::kUndefined, // WrapKey WebCryptoAlgorithmInfo::kUndefined // UnwrapKey }}, + {// Index 16 + // TODO(crbug.com/1032821): Ed25519 is experimental behind a flag. See + // https://chromestatus.com/feature/4913922408710144 for the status. + "ED25519", + { + WebCryptoAlgorithmInfo::kUndefined, // Encrypt + WebCryptoAlgorithmInfo::kUndefined, // Decrypt + kWebCryptoAlgorithmParamsTypeEd25519Params, // Sign + kWebCryptoAlgorithmParamsTypeEd25519Params, // Verify + WebCryptoAlgorithmInfo::kUndefined, // Digest + kWebCryptoAlgorithmParamsTypeNone, // GenerateKey + kWebCryptoAlgorithmParamsTypeNone, // ImportKey + WebCryptoAlgorithmInfo::kUndefined, // GetKeyLength + WebCryptoAlgorithmInfo::kUndefined, // DeriveBits + WebCryptoAlgorithmInfo::kUndefined, // WrapKey + WebCryptoAlgorithmInfo::kUndefined // UnwrapKey + }}, + {// Index 17 + // TODO(crbug.com/1032821): X25519 is experimental behind a flag. See + // https://chromestatus.com/feature/4913922408710144 for the status. + "X25519", + { + WebCryptoAlgorithmInfo::kUndefined, // Encrypt + WebCryptoAlgorithmInfo::kUndefined, // Decrypt + WebCryptoAlgorithmInfo::kUndefined, // Sign + WebCryptoAlgorithmInfo::kUndefined, // Verify + WebCryptoAlgorithmInfo::kUndefined, // Digest + kWebCryptoAlgorithmParamsTypeNone, // GenerateKey + kWebCryptoAlgorithmParamsTypeNone, // ImportKey + WebCryptoAlgorithmInfo::kUndefined, // GetKeyLength + kWebCryptoAlgorithmParamsTypeX25519KeyDeriveParams, // DeriveBits + WebCryptoAlgorithmInfo::kUndefined, // WrapKey + WebCryptoAlgorithmInfo::kUndefined // UnwrapKey + }}, }; // Initializing the algorithmIdToInfo table above depends on knowing the enum @@ -308,7 +342,9 @@ static_assert(kWebCryptoAlgorithmIdEcdh == 13, "ECDH id must match"); static_assert(kWebCryptoAlgorithmIdHkdf == 14, "HKDF id must match"); static_assert(kWebCryptoAlgorithmIdPbkdf2 == 15, "Pbkdf2 id must match"); -static_assert(kWebCryptoAlgorithmIdLast == 15, "last id must match"); +static_assert(kWebCryptoAlgorithmIdEd25519 == 16, "X25519 id must match"); +static_assert(kWebCryptoAlgorithmIdX25519 == 17, "Ed25519 id must match"); +static_assert(kWebCryptoAlgorithmIdLast == 17, "last id must match"); static_assert(10 == kWebCryptoOperationLast, "the parameter mapping needs to be updated"); @@ -489,6 +525,21 @@ return nullptr; } +const WebCryptoEd25519Params* WebCryptoAlgorithm::Ed25519Params() const { + DCHECK(!IsNull()); + if (ParamsType() == kWebCryptoAlgorithmParamsTypeEd25519Params) + return static_cast<WebCryptoEd25519Params*>(private_->params.get()); + return nullptr; +} + +const WebCryptoX25519KeyDeriveParams* +WebCryptoAlgorithm::X25519KeyDeriveParams() const { + DCHECK(!IsNull()); + if (ParamsType() == kWebCryptoAlgorithmParamsTypeX25519KeyDeriveParams) + return static_cast<WebCryptoX25519KeyDeriveParams*>(private_->params.get()); + return nullptr; +} + bool WebCryptoAlgorithm::IsHash(WebCryptoAlgorithmId id) { switch (id) { case kWebCryptoAlgorithmIdSha1: @@ -508,6 +559,8 @@ case kWebCryptoAlgorithmIdEcdh: case kWebCryptoAlgorithmIdHkdf: case kWebCryptoAlgorithmIdPbkdf2: + case kWebCryptoAlgorithmIdEd25519: + case kWebCryptoAlgorithmIdX25519: break; } return false; @@ -532,6 +585,8 @@ case kWebCryptoAlgorithmIdRsaPss: case kWebCryptoAlgorithmIdEcdsa: case kWebCryptoAlgorithmIdEcdh: + case kWebCryptoAlgorithmIdEd25519: + case kWebCryptoAlgorithmIdX25519: break; } return false;
diff --git a/third_party/blink/renderer/platform/graphics/compositing/README.md b/third_party/blink/renderer/platform/graphics/compositing/README.md index f8334d7..d40b6ed2 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/README.md +++ b/third_party/blink/renderer/platform/graphics/compositing/README.md
@@ -16,7 +16,7 @@ Outputs: List of `cc::Layer` objects and `cc::PropertyTree`'s. The algorithm walks through the list of `PaintChunks` in the `PaintArtifact`, -allocating new `c::Layers` if the `PaintChunk` cannot merge into an existing +allocating new `cc::Layers` if the `PaintChunk` cannot merge into an existing `cc::Layer`. The reasons why it would not be able to do so are: 1. The `PaintChunk` requires a foreign layer (see below)
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc index 00852fe4..4c1ac40 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -16,10 +16,12 @@ #include "third_party/blink/renderer/platform/geometry/geometry_as_json.h" #include "third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" +#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h" #include "third_party/blink/renderer/platform/graphics/paint/display_item.h" #include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h" #include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h" +#include "third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_flags.h" @@ -110,10 +112,20 @@ for (const auto& paint_chunk : paint_artifact->PaintChunks()) { const auto& display_item = paint_artifact->GetDisplayItemList()[paint_chunk.begin_index]; - DCHECK(display_item.IsForeignLayer()); - const auto& foreign_layer_display_item = - static_cast<const ForeignLayerDisplayItem&>(display_item); - cc::Layer* layer = foreign_layer_display_item.GetLayer(); + cc::Layer* layer = nullptr; + const LayerAsJSONClient* json_client = nullptr; + if (display_item.IsGraphicsLayerWrapper()) { + const GraphicsLayerDisplayItem& graphics_layer_display_item = + static_cast<const GraphicsLayerDisplayItem&>(display_item); + layer = graphics_layer_display_item.GetGraphicsLayer().CcLayer(); + json_client = &graphics_layer_display_item.GetGraphicsLayer(); + } else { + DCHECK(display_item.IsForeignLayer()); + const auto& foreign_layer_display_item = + static_cast<const ForeignLayerDisplayItem&>(display_item); + layer = foreign_layer_display_item.GetLayer(); + json_client = foreign_layer_display_item.GetLayerAsJSONClient(); + } // Need to retrieve the transform from |pending_layers_| so that // any decomposition is not double-reported via |layer|'s // offset_from_transform_parent and |paint_chunk|'s transform inside @@ -128,15 +140,13 @@ } } DCHECK(transform); - layers_as_json.AddLayer( - *layer, *transform, - foreign_layer_display_item.GetLayerAsJSONClient()); + layers_as_json.AddLayer(*layer, *transform, json_client); } } return layers_as_json.Finalize(); } -static scoped_refptr<cc::Layer> ForeignLayerForPaintChunk( +static scoped_refptr<cc::Layer> CcLayerForPaintChunk( const PaintArtifact& paint_artifact, const PaintChunk& paint_chunk, const FloatPoint& pending_layer_offset) { @@ -145,21 +155,33 @@ const auto& display_item = paint_artifact.GetDisplayItemList()[paint_chunk.begin_index]; - if (!display_item.IsForeignLayer()) + if (!display_item.IsForeignLayer() && + !display_item.IsGraphicsLayerWrapper()) { return nullptr; + } - // When a foreign layer's offset_to_transform_parent() changes, we don't - // call PaintArtifaceCompositor::SetNeedsUpdate() because the update won't - // change anything but cause unnecessary commit. Though - // UpdateTouchActionRects() depends on offset_to_transform_parent(), a - // foreign layer chunk doesn't have hit_test_data. + // UpdateTouchActionRects() depends on the layer's offset, but when the + // layer's offset changes, we do not call SetNeedsUpdate() (this is an + // optimization because the update would only cause an extra commit). This is + // only OK if the [Foreign|Graphics]Layer doesn't have hit test data. DCHECK(!paint_chunk.hit_test_data); - const auto& foreign_layer_display_item = - static_cast<const ForeignLayerDisplayItem&>(display_item); - auto* layer = foreign_layer_display_item.GetLayer(); - layer->SetOffsetToTransformParent(gfx::Vector2dF( - foreign_layer_display_item.Offset() + pending_layer_offset)); + cc::Layer* layer = nullptr; + FloatPoint layer_offset; + if (display_item.IsGraphicsLayerWrapper()) { + const auto& graphics_layer_display_item = + static_cast<const GraphicsLayerDisplayItem&>(display_item); + layer = graphics_layer_display_item.GetGraphicsLayer().CcLayer(); + layer_offset = FloatPoint(graphics_layer_display_item.GetGraphicsLayer() + .GetOffsetFromTransformNode()); + } else { + const auto& foreign_layer_display_item = + static_cast<const ForeignLayerDisplayItem&>(display_item); + layer = foreign_layer_display_item.GetLayer(); + layer_offset = foreign_layer_display_item.Offset(); + } + layer->SetOffsetToTransformParent( + gfx::Vector2dF(layer_offset + pending_layer_offset)); return layer; } @@ -297,12 +319,14 @@ DCHECK(paint_chunks.size()); const PaintChunk& first_paint_chunk = paint_chunks[0]; - // If the paint chunk is a foreign layer, just return that layer. - if (scoped_refptr<cc::Layer> foreign_layer = ForeignLayerForPaintChunk( - *paint_artifact, first_paint_chunk, - pending_layer.offset_of_decomposited_transforms)) { + scoped_refptr<cc::Layer> cc_layer; + // If the paint chunk is a foreign layer or placeholder for a GraphicsLayer, + // just return its cc::Layer. + if ((cc_layer = CcLayerForPaintChunk( + *paint_artifact, first_paint_chunk, + pending_layer.offset_of_decomposited_transforms))) { DCHECK_EQ(paint_chunks.size(), 1u); - return foreign_layer; + return cc_layer; } // If the paint chunk is a scroll hit test layer, lookup/create the layer. @@ -322,7 +346,7 @@ ClientForPaintChunk(first_paint_chunk); IntRect cc_combined_bounds = EnclosingIntRect(pending_layer.bounds); - auto cc_layer = content_layer_client->UpdateCcPictureLayer( + cc_layer = content_layer_client->UpdateCcPictureLayer( paint_artifact, paint_chunks, cc_combined_bounds, pending_layer.property_tree_state); if (cc_combined_bounds.IsEmpty()) @@ -848,6 +872,7 @@ const auto& first_display_item = paint_artifact.GetDisplayItemList()[chunk_it->begin_index]; requires_own_layer = first_display_item.IsForeignLayer() || + first_display_item.IsGraphicsLayerWrapper() || IsCompositedScrollHitTest(first_display_item) || IsCompositedScrollbar(first_display_item); }
diff --git a/third_party/blink/renderer/platform/graphics/paint/README.md b/third_party/blink/renderer/platform/graphics/paint/README.md index 6d367c9d..ea389f5c 100644 --- a/third_party/blink/renderer/platform/graphics/paint/README.md +++ b/third_party/blink/renderer/platform/graphics/paint/README.md
@@ -156,6 +156,13 @@ Holds a `PaintRecord` which contains the paint operations required to draw some atom of content. +#### [GraphicsLayerDisplayItem](graphics_layer_display_item.h) + +Placeholder for `GraphicsLayers` allocated by the pre-CompositeAfterPaint +compositing logic. Each one of these may or may not ultimately produce a +`cc::PictureLayer`, depending on the layer squashing mechanism. This class +becomes obsolete with CompositeAfterPaint. + #### [ForeignLayerDisplayItem](foreign_layer_display_item.h) Draws an atom of content, but using a `cc::Layer` produced by some agent outside
diff --git a/third_party/blink/renderer/platform/graphics/paint/display_item.cc b/third_party/blink/renderer/platform/graphics/paint/display_item.cc index 7960cf1c..4ae02d1 100644 --- a/third_party/blink/renderer/platform/graphics/paint/display_item.cc +++ b/third_party/blink/renderer/platform/graphics/paint/display_item.cc
@@ -125,7 +125,6 @@ DEBUG_STRING_CASE(ForeignLayerPlugin); DEBUG_STRING_CASE(ForeignLayerVideo); DEBUG_STRING_CASE(ForeignLayerRemoteFrame); - DEBUG_STRING_CASE(ForeignLayerWrapper); DEBUG_STRING_CASE(ForeignLayerContentsWrapper); DEBUG_STRING_CASE(ForeignLayerLinkHighlight); DEBUG_STRING_CASE(ForeignLayerViewportScroll); @@ -134,6 +133,13 @@ } } +static String GraphicsLayerWrapperTypeAsDebugString(DisplayItem::Type type) { + switch (type) { + DEBUG_STRING_CASE(GraphicsLayerWrapper); + DEFAULT_CASE; + } +} + WTF::String DisplayItem::TypeAsDebugString(Type type) { if (IsDrawingType(type)) return DrawingTypeAsDebugString(type); @@ -141,6 +147,9 @@ if (IsForeignLayerType(type)) return ForeignLayerTypeAsDebugString(type); + if (IsGraphicsLayerWrapperType(type)) + return GraphicsLayerWrapperTypeAsDebugString(type); + PAINT_PHASE_BASED_DEBUG_STRINGS(Clip); PAINT_PHASE_BASED_DEBUG_STRINGS(Scroll); PAINT_PHASE_BASED_DEBUG_STRINGS(SVGTransform);
diff --git a/third_party/blink/renderer/platform/graphics/paint/display_item.h b/third_party/blink/renderer/platform/graphics/paint/display_item.h index b6044ed15..dd3e7427 100644 --- a/third_party/blink/renderer/platform/graphics/paint/display_item.h +++ b/third_party/blink/renderer/platform/graphics/paint/display_item.h
@@ -102,13 +102,16 @@ kForeignLayerPlugin, kForeignLayerVideo, kForeignLayerRemoteFrame, - kForeignLayerWrapper, kForeignLayerContentsWrapper, kForeignLayerLinkHighlight, kForeignLayerViewportScroll, kForeignLayerViewportScrollbar, kForeignLayerLast = kForeignLayerViewportScrollbar, + kGraphicsLayerWrapperFirst, + kGraphicsLayerWrapper = kGraphicsLayerWrapperFirst, + kGraphicsLayerWrapperLast = kGraphicsLayerWrapper, + kClipPaintPhaseFirst, kClipPaintPhaseLast = kClipPaintPhaseFirst + kPaintPhaseMax, @@ -247,6 +250,7 @@ DEFINE_PAINT_PHASE_CONVERSION_METHOD(Drawing) DEFINE_CATEGORY_METHODS(ForeignLayer) + DEFINE_CATEGORY_METHODS(GraphicsLayerWrapper) DEFINE_PAINT_PHASE_CONVERSION_METHOD(Clip) DEFINE_PAINT_PHASE_CONVERSION_METHOD(Scroll)
diff --git a/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc b/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc index 6c41336..41f6bb8 100644 --- a/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc +++ b/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc
@@ -129,20 +129,4 @@ nullptr, properties); } -void RecordGraphicsLayerAsForeignLayer(GraphicsContext& context, - DisplayItem::Type type, - const GraphicsLayer& graphics_layer) { - // In pre-CompositeAfterPaint, the GraphicsLayer hierarchy is still built - // during CompositingUpdate, and we have to clear them here to ensure no - // extraneous layers are still attached. In future we will disable all - // those layer hierarchy code so we won't need this line. - DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); - graphics_layer.CcLayer()->RemoveAllChildren(); - - RecordForeignLayerInternal( - context, graphics_layer, type, graphics_layer.CcLayer(), - FloatPoint(graphics_layer.GetOffsetFromTransformNode()), &graphics_layer, - &graphics_layer.GetPropertyTreeState()); -} - } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h b/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h index 7c57c79..236c872 100644 --- a/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h +++ b/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h
@@ -13,7 +13,6 @@ namespace blink { class GraphicsContext; -class GraphicsLayer; class LayerAsJSONClient; // Represents foreign content (produced outside Blink) which draws to a layer. @@ -77,12 +76,6 @@ const FloatPoint& offset, const PropertyTreeState* properties = nullptr); -// Records a graphics layer into a GraphicsContext. -PLATFORM_EXPORT void RecordGraphicsLayerAsForeignLayer( - GraphicsContext& context, - DisplayItem::Type type, - const GraphicsLayer& graphics_layer); - } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_FOREIGN_LAYER_DISPLAY_ITEM_H_
diff --git a/third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.cc b/third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.cc new file mode 100644 index 0000000..c4d2b04 --- /dev/null +++ b/third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.cc
@@ -0,0 +1,65 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.h" + +#include <utility> + +#include "cc/layers/layer.h" +#include "cc/layers/picture_layer.h" +#include "third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h" +#include "third_party/blink/renderer/platform/graphics/graphics_context.h" +#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" +#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" +#include "third_party/blink/renderer/platform/wtf/assertions.h" + +namespace blink { + +GraphicsLayerDisplayItem::GraphicsLayerDisplayItem( + const GraphicsLayer& graphics_layer) + : DisplayItem(graphics_layer, kGraphicsLayerWrapper, sizeof(*this)), + graphics_layer_(graphics_layer) {} + +bool GraphicsLayerDisplayItem::Equals(const DisplayItem& other) const { + return GetType() == other.GetType() && + GetGraphicsLayer() == + static_cast<const GraphicsLayerDisplayItem&>(other) + .GetGraphicsLayer(); +} + +#if DCHECK_IS_ON() +void GraphicsLayerDisplayItem::PropertiesAsJSON(JSONObject& json) const { + DisplayItem::PropertiesAsJSON(json); + json.SetInteger("layer", graphics_layer_.CcLayer()->id()); + FloatPoint offset(graphics_layer_.GetOffsetFromTransformNode()); + json.SetDouble("offset_x", offset.X()); + json.SetDouble("offset_y", offset.Y()); +} +#endif + +void RecordGraphicsLayer(GraphicsContext& context, + const GraphicsLayer& graphics_layer) { + // In pre-CompositeAfterPaint, the GraphicsLayer hierarchy is still built + // during CompositingUpdate, and we have to clear them here to ensure no + // extraneous layers are still attached. In future we will disable all + // those layer hierarchy code so we won't need this line. + DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); + graphics_layer.CcLayer()->RemoveAllChildren(); + + PaintController& paint_controller = context.GetPaintController(); + if (paint_controller.DisplayItemConstructionIsDisabled()) + return; + + // This is like ScopedPaintChunkProperties but uses null id because graphics + // layer chunk doesn't need an id nor a client. + const PropertyTreeState& properties = graphics_layer.GetPropertyTreeState(); + PropertyTreeState previous_properties( + paint_controller.CurrentPaintChunkProperties()); + paint_controller.UpdateCurrentPaintChunkProperties(nullptr, properties); + paint_controller.CreateAndAppend<GraphicsLayerDisplayItem>(graphics_layer); + paint_controller.UpdateCurrentPaintChunkProperties(nullptr, + previous_properties); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.h b/third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.h new file mode 100644 index 0000000..2e468dd --- /dev/null +++ b/third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.h
@@ -0,0 +1,47 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_GRAPHICS_LAYER_DISPLAY_ITEM_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_GRAPHICS_LAYER_DISPLAY_ITEM_H_ + +#include "cc/layers/layer.h" +#include "third_party/blink/renderer/platform/graphics/paint/display_item.h" +#include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h" +#include "third_party/blink/renderer/platform/platform_export.h" + +namespace blink { + +class GraphicsContext; +class GraphicsLayer; + +// Before CompositeAfterPaint, this is a placeholder for a GraphicsLayer +// allocated before paint. With CompositeAfterPaint, this class will be +// obsolete and should be removed. +// +// Before SquashAfterPaint, a cc::Layer will always be allocated to draw the +// GraphicsLayer's contents. With SquashAfter Paint, that may not be true; the +// GraphicsLayer may end up getting squashed by PaintArtifactCompositor. +class PLATFORM_EXPORT GraphicsLayerDisplayItem final : public DisplayItem { + public: + GraphicsLayerDisplayItem(const GraphicsLayer&); + + const GraphicsLayer& GetGraphicsLayer() const { return graphics_layer_; } + + // DisplayItem + bool Equals(const DisplayItem&) const override; +#if DCHECK_IS_ON() + void PropertiesAsJSON(JSONObject&) const override; +#endif + + private: + const GraphicsLayer& graphics_layer_; +}; + +// Records a graphics layer into a GraphicsContext. +PLATFORM_EXPORT void RecordGraphicsLayer(GraphicsContext& context, + const GraphicsLayer& graphics_layer); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_GRAPHICS_LAYER_DISPLAY_ITEM_H_
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc b/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc index e9f6985..be12b9a 100644 --- a/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc +++ b/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc
@@ -65,8 +65,9 @@ } bool PaintChunker::IncrementDisplayItemIndex(const DisplayItem& item) { - bool item_forces_new_chunk = - item.IsForeignLayer() || item.IsScrollHitTest() || item.IsScrollbar(); + bool item_forces_new_chunk = item.IsForeignLayer() || + item.IsGraphicsLayerWrapper() || + item.IsScrollHitTest() || item.IsScrollbar(); if (item_forces_new_chunk) ForceNewChunk();
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc b/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc index 6fadf3d..f0a120f 100644 --- a/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc +++ b/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc
@@ -783,8 +783,10 @@ if (IsSkippingCache()) return; - if (DisplayItem::IsForeignLayerType(id.type)) + if (DisplayItem::IsGraphicsLayerWrapperType(id.type) || + DisplayItem::IsForeignLayerType(id.type)) { return; + } auto it = new_paint_chunk_indices_by_client_.find(&id.client); if (it != new_paint_chunk_indices_by_client_.end()) {
diff --git a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc index 1613287..9af4ae0 100644 --- a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc +++ b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
@@ -190,9 +190,12 @@ mapper.SwitchToChunk(new_chunk); auto& new_chunk_info = new_chunks_info.emplace_back(*this, mapper, it); - // Foreign layers take care of raster invalidation by themselves. - if (DisplayItem::IsForeignLayerType(new_chunk.id.type)) + // Foreign layers and GraphicsLayers take care of raster invalidation by + // themselves. + if (DisplayItem::IsGraphicsLayerWrapperType(new_chunk.id.type) || + DisplayItem::IsForeignLayerType(new_chunk.id.type)) { continue; + } if (!new_chunk.is_cacheable) { AddRasterInvalidation(new_chunk_info.bounds_in_layer, new_chunk.id.client,
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc index edee4e6..51d91c1 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
@@ -143,8 +143,6 @@ request->SetKeepalive(GetKeepalive()); request->SetPriority(Priority()); - if (request->HttpMethod() == HttpMethod()) - request->SetHttpBody(HttpBody()); request->SetCorsPreflightPolicy(CorsPreflightPolicy()); if (IsAdResource()) request->SetIsAdResource();
diff --git a/third_party/blink/public/platform/modules/mediastream/media_stream_audio_deliverer.h b/third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h similarity index 95% rename from third_party/blink/public/platform/modules/mediastream/media_stream_audio_deliverer.h rename to third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h index 6bf8506..dafb610 100644 --- a/third_party/blink/public/platform/modules/mediastream/media_stream_audio_deliverer.h +++ b/third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.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 THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_MEDIA_STREAM_AUDIO_DELIVERER_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_MEDIA_STREAM_AUDIO_DELIVERER_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_DELIVERER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_DELIVERER_H_ #include <algorithm> #include <vector> @@ -155,4 +155,4 @@ } // namespace blink -#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_MEDIA_STREAM_AUDIO_DELIVERER_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_DELIVERER_H_
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h b/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h index 24a2227..1dfc873 100644 --- a/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h +++ b/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h
@@ -12,10 +12,10 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "media/base/limits.h" -#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_deliverer.h" #include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h" #include "third_party/blink/public/platform/web_media_stream_source.h" #include "third_party/blink/public/platform/web_media_stream_track.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h" #include "third_party/blink/renderer/platform/platform_export.h"
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h b/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h index 5e1a0365..5981a2a 100644 --- a/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h +++ b/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h
@@ -13,8 +13,8 @@ #include "base/memory/weak_ptr.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" -#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_deliverer.h" #include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_track.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h" #include "third_party/blink/renderer/platform/platform_export.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 9539c55..350e05e1 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -819,7 +819,7 @@ }, { name: "IDBRelaxedDurability", - status: "experimental", + status: "stable", }, { name: "IdleDetection", @@ -1807,6 +1807,10 @@ status: "test", }, { + name: "WebCryptoCurve25519", + status: "experimental", + }, + { name: "WebGL2ComputeContext", status: "experimental", },
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 f7aac04..a736bc9 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
@@ -394,6 +394,9 @@ # HTTP structured headers 'net::structured_headers::.+', + # HTTP status codes + 'net::HTTP_.+', + # Network service. 'network::.+',
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-paint-relayout.html b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-paint-relayout.html new file mode 100644 index 0000000..0499e3e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats/float-paint-relayout.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1049973"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="width: 100px; height: 100px; background: red; overflow: auto;"> + <div id="target" style="display: none; float: left; width: 100px; height: 100px; background: green;"></div> +</div> +<script> +document.body.offsetTop; +document.getElementById('target').style.display = 'block'; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt index c9e777ec..17b7f40 100644 --- a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 200 tests; 189 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 200 tests; 198 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS idl_test validation PASS Partial interface Navigator: original interface defined @@ -18,15 +18,15 @@ PASS Navigator includes NavigatorCookies: member names are unique PASS Navigator includes NavigatorPlugins: member names are unique PASS Navigator includes NavigatorConcurrentHardware: member names are unique -FAIL XRSystem interface: existence and properties of interface object assert_own_property: self does not have own property "XRSystem" expected property "XRSystem" missing -FAIL XRSystem interface object length assert_own_property: self does not have own property "XRSystem" expected property "XRSystem" missing -FAIL XRSystem interface object name assert_own_property: self does not have own property "XRSystem" expected property "XRSystem" missing -FAIL XRSystem interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRSystem" expected property "XRSystem" missing -FAIL XRSystem interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRSystem" expected property "XRSystem" missing -FAIL XRSystem interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRSystem" expected property "XRSystem" missing -FAIL XRSystem interface: operation isSessionSupported(XRSessionMode) assert_own_property: self does not have own property "XRSystem" expected property "XRSystem" missing -FAIL XRSystem interface: operation requestSession(XRSessionMode, optional XRSessionInit) assert_own_property: self does not have own property "XRSystem" expected property "XRSystem" missing -FAIL XRSystem interface: attribute ondevicechange assert_own_property: self does not have own property "XRSystem" expected property "XRSystem" missing +PASS XRSystem interface: existence and properties of interface object +PASS XRSystem interface object length +PASS XRSystem interface object name +PASS XRSystem interface: existence and properties of interface prototype object +PASS XRSystem interface: existence and properties of interface prototype object's "constructor" property +PASS XRSystem interface: existence and properties of interface prototype object's @@unscopables property +PASS XRSystem interface: operation isSessionSupported(XRSessionMode) +PASS XRSystem interface: operation requestSession(XRSessionMode, optional XRSessionInit) +PASS XRSystem interface: attribute ondevicechange PASS XRSession interface: existence and properties of interface object PASS XRSession interface object length PASS XRSession interface object name
diff --git a/third_party/blink/web_tests/fast/layout/common-ancestor-relayout-boundary.html b/third_party/blink/web_tests/fast/layout/common-ancestor-relayout-boundary.html index 3eebd922..1162245 100644 --- a/third_party/blink/web_tests/fast/layout/common-ancestor-relayout-boundary.html +++ b/third_party/blink/web_tests/fast/layout/common-ancestor-relayout-boundary.html
@@ -6,6 +6,7 @@ width: 100px; height: 100px; overflow: hidden; + position: relative; } </style> <div id="relayout-common-ancestor"><div><div></div></div><div><div></div></div></div>
diff --git a/third_party/blink/web_tests/fast/scrolling/overflow-hidden-viewport-scrolling.html b/third_party/blink/web_tests/fast/scrolling/overflow-hidden-viewport-scrolling.html new file mode 100644 index 0000000..50accd5 --- /dev/null +++ b/third_party/blink/web_tests/fast/scrolling/overflow-hidden-viewport-scrolling.html
@@ -0,0 +1,85 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../../resources/gesture-util.js"></script> +<style> + #viewport { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + z-index: 1; + background-color: green; + } + + #spacer { + width: 200vw; + height: 200vh; + position: absolute; + left: 0; + top: 0; + z-index: -1; + background-color: red; + } + + html, body { + padding: 0px; + margin: 0px; + width: 100%; + height: 100%; + } + + html { + overflow-x: hidden; + overflow-y: hidden; + } +</style> +<div id="viewport"> + To test manually, pinch zoom into the page and scroll around. You should be + able to pan around within the green area but you should never scroll the + document (you should never see red). +</div> +<div id="spacer"></div> +<script> + const viewport = document.getElementById('viewport'); + + window.onload = () => { + if (!window.internals) + return; + + internals.setPageScaleFactor(2); + + promise_test (async (test) => { + await waitForCompositorCommit(); + + const delta = 2000; + const location = elementCenter(viewport); + await smoothScroll(delta, + location.x, + location.y, + GestureSourceType.TOUCH_INPUT, + 'down', + SPEED_INSTANT); + + assert_equals(window.scrollY, 0, "Document doesn't scroll vertically."); + assert_equals(window.visualViewport.offsetTop, 300, "VisualViewport pans vertically."); + }, "Test viewport scrolling for overflow-y: hidden."); + + promise_test (async (test) => { + await waitForCompositorCommit(); + + const delta = 2000; + const location = elementCenter(viewport); + await smoothScroll(delta, + location.x, + location.y, + GestureSourceType.TOUCH_INPUT, + 'right', + SPEED_INSTANT); + + assert_equals(window.scrollX, 0, "Document doesn't scroll horizontally."); + assert_equals(window.visualViewport.offsetLeft, 400, "VisualViewport pans horizontally."); + }, "Test viewport scrolling for overflow-x: hidden."); + } +</script>
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/overflow/overflow-delete-line-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/overflow/overflow-delete-line-expected.txt index d75ffed..cc7e03fe 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/overflow/overflow-delete-line-expected.txt +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/overflow/overflow-delete-line-expected.txt
@@ -12,19 +12,9 @@ "reason": "appeared" }, { - "object": "InlineTextBox ' '", + "object": "LayoutBlockFlow DIV id='dv'", "rect": [8, 74, 46, 36], - "reason": "disappeared" - }, - { - "object": "InlineTextBox 'Lorem'", - "rect": [8, 74, 46, 36], - "reason": "disappeared" - }, - { - "object": "InlineTextBox 'ipsum'", - "rect": [8, 74, 46, 36], - "reason": "disappeared" + "reason": "chunk disappeared" } ] }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt index e4dbf1a..4bac262 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt
@@ -18,7 +18,7 @@ }, { "object": "NGPhysicalBoxFragment LayoutInline A", - "rect": [382, 970, 44, 23], + "rect": [381, 969, 46, 25], "reason": "appeared" }, {
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/css-position/position-absolute-container-dynamic-002-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/css-position/position-absolute-container-dynamic-002-expected.txt deleted file mode 100644 index e4cff77..0000000 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/css/css-position/position-absolute-container-dynamic-002-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL #target static position responded to parent relayout assert_equals: expected 100 but got 200 -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/forms/select/menulist-update-text-popup-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/forms/select/menulist-update-text-popup-expected.txt index bbb98057..4d04c167 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/forms/select/menulist-update-text-popup-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/forms/select/menulist-update-text-popup-expected.txt
@@ -6,7 +6,7 @@ C layer at (0,0) size 31x20 LayoutBlockFlow (positioned) {DIV} at (8,50) size 31x20 - LayoutMenuList {SELECT} at (0,0) size 31x20 [bgcolor=#DDDDDD] [border: (1px solid #767676)] + LayoutFlexibleBox {SELECT} at (0,0) size 31x20 [bgcolor=#DDDDDD] [border: (1px solid #767676)] LayoutText {#text} at (0,0) size 0x0 layer at (5,1) size 9x18 LayoutBlockFlow {DIV} at (5,1) size 9x18
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout-expected.txt index eacb3b79b..ec76a2b 100644 --- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout-expected.txt
@@ -21,7 +21,7 @@ startTime : <number> type : "Layout" } -Text details for Layout: timeline-layout.js:39 +Text details for Layout: timeline-layout.js:40 Layout Properties: { data : { @@ -43,5 +43,5 @@ startTime : <number> type : "Layout" } -Text details for Layout: timeline-layout.js:39 +Text details for Layout: timeline-layout.js:40
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout.js b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout.js index 0b07c24..c5315c9 100644 --- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout.js +++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout.js
@@ -12,6 +12,7 @@ overflow: hidden; width: 100px; height: 100px; + position: relative; } </style> <body>
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-node-reference.js b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-node-reference.js index 53529d6..a041d92 100644 --- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-node-reference.js +++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-node-reference.js
@@ -13,6 +13,7 @@ overflow: hidden; width: 100px; height: 100px; + position: relative; } </style> <div id="boundary" class="relayout-boundary">
diff --git a/third_party/blink/web_tests/inspector-protocol/dom/dom-relayout-boundary.js b/third_party/blink/web_tests/inspector-protocol/dom/dom-relayout-boundary.js index 85c98c6..d4ea1ebd 100644 --- a/third_party/blink/web_tests/inspector-protocol/dom/dom-relayout-boundary.js +++ b/third_party/blink/web_tests/inspector-protocol/dom/dom-relayout-boundary.js
@@ -6,6 +6,7 @@ width: 200px; height: 40px; overflow: hidden; + position: relative; } </style> </head>
diff --git a/third_party/blink/web_tests/platform/linux/editing/caret/caret-color-014-expected.png b/third_party/blink/web_tests/platform/linux/editing/caret/caret-color-014-expected.png index 0c7c5d97..bc86545 100644 --- a/third_party/blink/web_tests/platform/linux/editing/caret/caret-color-014-expected.png +++ b/third_party/blink/web_tests/platform/linux/editing/caret/caret-color-014-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/editing/caret/caret-color-015-expected.png b/third_party/blink/web_tests/platform/linux/editing/caret/caret-color-015-expected.png index 070f97a3..b250d84 100644 --- a/third_party/blink/web_tests/platform/linux/editing/caret/caret-color-015-expected.png +++ b/third_party/blink/web_tests/platform/linux/editing/caret/caret-color-015-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/editing/selection/replaced-boundaries-3-expected.txt b/third_party/blink/web_tests/platform/linux/editing/selection/replaced-boundaries-3-expected.txt index fd697812..0ddaafd 100644 --- a/third_party/blink/web_tests/platform/linux/editing/selection/replaced-boundaries-3-expected.txt +++ b/third_party/blink/web_tests/platform/linux/editing/selection/replaced-boundaries-3-expected.txt
@@ -15,7 +15,7 @@ LayoutText {#text} at (0,0) size 22x19 text run at (0,0) width 22: "abc" LayoutBR {BR} at (22,15) size 0x0 - LayoutMenuList {SELECT} at (0,20) size 233x20 [bgcolor=#DDDDDD] [border: (1px solid #767676)] + LayoutFlexibleBox {SELECT} at (0,20) size 233x20 [bgcolor=#DDDDDD] [border: (1px solid #767676)] LayoutText {#text} at (0,0) size 0x0 layer at (13,85) size 211x18 LayoutBlockFlow {DIV} at (5,1) size 211x18
diff --git a/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-detached-expected.png b/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-detached-expected.png index 3f40e03..9e036814 100644 --- a/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-detached-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-detached-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-multiline-expected.png b/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-multiline-expected.png index b1a79e1f..630fe1d 100644 --- a/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-multiline-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-multiline-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-outline-color-expected.png b/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-outline-color-expected.png index 0b631b5..01a1ce3 100644 --- a/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-outline-color-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-outline-color-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-outline-offset-expected.png b/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-outline-offset-expected.png index f16c9c3..ee0c9696 100644 --- a/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-outline-offset-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-outline-offset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-outline-width-expected.png b/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-outline-width-expected.png index 5955278..8087b92 100644 --- a/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-outline-width-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/css/focus-ring-outline-width-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/events/reveal-link-when-focused-expected.png b/third_party/blink/web_tests/platform/linux/fast/events/reveal-link-when-focused-expected.png index 1b3a91e..82c559c 100644 --- a/third_party/blink/web_tests/platform/linux/fast/events/reveal-link-when-focused-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/events/reveal-link-when-focused-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/select/menulist-update-text-popup-expected.txt b/third_party/blink/web_tests/platform/linux/fast/forms/select/menulist-update-text-popup-expected.txt index e9753d6..e98f900 100644 --- a/third_party/blink/web_tests/platform/linux/fast/forms/select/menulist-update-text-popup-expected.txt +++ b/third_party/blink/web_tests/platform/linux/fast/forms/select/menulist-update-text-popup-expected.txt
@@ -6,7 +6,7 @@ C layer at (0,0) size 31x20 LayoutNGBlockFlow (positioned) {DIV} at (8,50) size 31x20 - LayoutMenuList {SELECT} at (0,0) size 31x20 [bgcolor=#DDDDDD] [border: (1px solid #767676)] + LayoutFlexibleBox {SELECT} at (0,0) size 31x20 [bgcolor=#DDDDDD] [border: (1px solid #767676)] LayoutText {#text} at (0,0) size 0x0 layer at (5,1) size 9x18 LayoutBlockFlow {DIV} at (5,1) size 9x18
diff --git a/third_party/blink/web_tests/platform/linux/fast/inline/inline-focus-ring-expected.png b/third_party/blink/web_tests/platform/linux/fast/inline/inline-focus-ring-expected.png index 2032eef..9853670 100644 --- a/third_party/blink/web_tests/platform/linux/fast/inline/inline-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/inline/inline-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/outline/focus-layers-expected.png b/third_party/blink/web_tests/platform/linux/paint/invalidation/outline/focus-layers-expected.png index 85cbe44..77c45c6 100644 --- a/third_party/blink/web_tests/platform/linux/paint/invalidation/outline/focus-layers-expected.png +++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/outline/focus-layers-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/overflow/overflow-delete-line-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/overflow/overflow-delete-line-expected.txt index a4eae6c..0616b790 100644 --- a/third_party/blink/web_tests/platform/linux/paint/invalidation/overflow/overflow-delete-line-expected.txt +++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/overflow/overflow-delete-line-expected.txt
@@ -12,19 +12,9 @@ "reason": "appeared" }, { - "object": "InlineTextBox ' '", + "object": "LayoutBlockFlow DIV id='dv'", "rect": [8, 74, 46, 36], - "reason": "disappeared" - }, - { - "object": "InlineTextBox 'Lorem'", - "rect": [8, 74, 46, 36], - "reason": "disappeared" - }, - { - "object": "InlineTextBox 'ipsum'", - "rect": [8, 74, 46, 36], - "reason": "disappeared" + "reason": "chunk disappeared" } ] }
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index fc040c62..8ec0a966 100644 --- a/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt index b2df0cd..2a259fe 100644 --- a/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt +++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt
@@ -18,7 +18,7 @@ }, { "object": "NGPhysicalBoxFragment LayoutInline A", - "rect": [382, 970, 44, 23], + "rect": [381, 969, 46, 25], "reason": "appeared" }, {
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/focus-rect/focus-ring-detached-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/focus-rect/focus-ring-detached-expected.png index 724205e8..1b8088e 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/focus-rect/focus-ring-detached-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/focus-rect/focus-ring-detached-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/focus-rect/focus-ring-multiline-link-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/focus-rect/focus-ring-multiline-link-expected.png index 5fc802f..a9a0eead 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/focus-rect/focus-ring-multiline-link-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/focus-rect/focus-ring-multiline-link-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/focus-rect/focus-ring-outline-color-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/focus-rect/focus-ring-outline-color-expected.png index 4e767f0266..bdd666d9 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/focus-rect/focus-ring-outline-color-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh/focus-rect/focus-ring-outline-color-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt index 9ac58da6..ed7744b 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt +++ b/third_party/blink/web_tests/platform/linux/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt
@@ -6,7 +6,7 @@ C layer at (0,0) size 31x20 LayoutNGBlockFlow (positioned) {DIV} at (8,50) size 31x20 - LayoutMenuList {SELECT} at (0,0) size 31x20 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)] + LayoutFlexibleBox {SELECT} at (0,0) size 31x20 [bgcolor=#DDDDDD] [border: (1px solid #A9A9A9)] LayoutText {#text} at (0,0) size 0x0 layer at (5,1) size 9x18 LayoutBlockFlow {DIV} at (5,1) size 9x18
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/cascade/fast/forms/month/month-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/cascade/fast/forms/month/month-appearance-basic-expected.png index 36f2c97..23f06768 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/cascade/fast/forms/month/month-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/cascade/fast/forms/month/month-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt index 5bf6a57..565213cd 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt
@@ -6,7 +6,7 @@ C layer at (0,0) size 40x18 LayoutNGBlockFlow (positioned) {DIV} at (8,50) size 40x18 - LayoutMenuList {SELECT} at (0,0) size 40x18 [bgcolor=#F8F8F8] + LayoutFlexibleBox {SELECT} at (0,0) size 40x18 [bgcolor=#F8F8F8] LayoutText {#text} at (0,0) size 0x0 layer at (8,0) size 9x18 LayoutBlockFlow {DIV} at (8,0) size 9x18
diff --git a/third_party/blink/web_tests/platform/mac/editing/caret/caret-color-014-expected.png b/third_party/blink/web_tests/platform/mac/editing/caret/caret-color-014-expected.png index 33eef9f..c66f71e2 100644 --- a/third_party/blink/web_tests/platform/mac/editing/caret/caret-color-014-expected.png +++ b/third_party/blink/web_tests/platform/mac/editing/caret/caret-color-014-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/editing/caret/caret-color-015-expected.png b/third_party/blink/web_tests/platform/mac/editing/caret/caret-color-015-expected.png index d15b4e68..1ebbd33 100644 --- a/third_party/blink/web_tests/platform/mac/editing/caret/caret-color-015-expected.png +++ b/third_party/blink/web_tests/platform/mac/editing/caret/caret-color-015-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/editing/selection/replaced-boundaries-3-expected.txt b/third_party/blink/web_tests/platform/mac/editing/selection/replaced-boundaries-3-expected.txt index 629298da..47e26eb 100644 --- a/third_party/blink/web_tests/platform/mac/editing/selection/replaced-boundaries-3-expected.txt +++ b/third_party/blink/web_tests/platform/mac/editing/selection/replaced-boundaries-3-expected.txt
@@ -15,7 +15,7 @@ LayoutText {#text} at (0,0) size 23x18 text run at (0,0) width 23: "abc" LayoutBR {BR} at (22,14) size 1x0 - LayoutMenuList {SELECT} at (0,18) size 235x19 [bgcolor=#FFFFFF] [border: (1px solid #767676)] + LayoutFlexibleBox {SELECT} at (0,18) size 235x19 [bgcolor=#FFFFFF] [border: (1px solid #767676)] LayoutText {#text} at (0,0) size 0x0 layer at (13,79) size 213x17 scrollWidth 214 LayoutBlockFlow {DIV} at (5,1) size 213x17
diff --git a/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-detached-expected.png b/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-detached-expected.png index ac98e57..99f62d9 100644 --- a/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-detached-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-detached-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-multiline-expected.png b/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-multiline-expected.png index 31295d5..099f3d02 100644 --- a/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-multiline-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-multiline-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-outline-color-expected.png b/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-outline-color-expected.png index a74c799c..91b8039 100644 --- a/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-outline-color-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-outline-color-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-outline-offset-expected.png b/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-outline-offset-expected.png index a5f7b90..b524a89 100644 --- a/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-outline-offset-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-outline-offset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-outline-width-expected.png b/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-outline-width-expected.png index 11ca9ab3..4abc3473 100644 --- a/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-outline-width-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/css/focus-ring-outline-width-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/events/reveal-link-when-focused-expected.png b/third_party/blink/web_tests/platform/mac/fast/events/reveal-link-when-focused-expected.png index 3673e2e..5171a2b 100644 --- a/third_party/blink/web_tests/platform/mac/fast/events/reveal-link-when-focused-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/events/reveal-link-when-focused-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-update-text-popup-expected.txt b/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-update-text-popup-expected.txt index 73430f6..3750646 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-update-text-popup-expected.txt +++ b/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-update-text-popup-expected.txt
@@ -6,7 +6,7 @@ C layer at (0,0) size 32x19 LayoutNGBlockFlow (positioned) {DIV} at (8,50) size 32x19 - LayoutMenuList {SELECT} at (0,0) size 32x19 [bgcolor=#FFFFFF] [border: (1px solid #767676)] + LayoutFlexibleBox {SELECT} at (0,0) size 32x19 [bgcolor=#FFFFFF] [border: (1px solid #767676)] LayoutText {#text} at (0,0) size 0x0 layer at (5,1) size 10x17 LayoutBlockFlow {DIV} at (5,1) size 10x17
diff --git a/third_party/blink/web_tests/platform/mac/fast/inline/inline-focus-ring-expected.png b/third_party/blink/web_tests/platform/mac/fast/inline/inline-focus-ring-expected.png index 984bddd..f0064dbc 100644 --- a/third_party/blink/web_tests/platform/mac/fast/inline/inline-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/inline/inline-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/outline/focus-layers-expected.png b/third_party/blink/web_tests/platform/mac/paint/invalidation/outline/focus-layers-expected.png index 3ff9aad..b59f04b 100644 --- a/third_party/blink/web_tests/platform/mac/paint/invalidation/outline/focus-layers-expected.png +++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/outline/focus-layers-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 039f99ae..206f0f0 100644 --- a/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt index 729703c..fc32521 100644 --- a/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt +++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt
@@ -18,7 +18,7 @@ }, { "object": "NGPhysicalBoxFragment LayoutInline A", - "rect": [381, 990, 49, 23], + "rect": [380, 989, 51, 25], "reason": "appeared" }, {
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/focus-rect/focus-ring-detached-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/focus-rect/focus-ring-detached-expected.png index 2cb3d3e..7b2dd42 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/focus-rect/focus-ring-detached-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/focus-rect/focus-ring-detached-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/focus-rect/focus-ring-multiline-link-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/focus-rect/focus-ring-multiline-link-expected.png index cc1d3fe..561c336 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/focus-rect/focus-ring-multiline-link-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/focus-rect/focus-ring-multiline-link-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/focus-rect/focus-ring-outline-color-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/focus-rect/focus-ring-outline-color-expected.png index de77d92..2a8c9f2 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/focus-rect/focus-ring-outline-color-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh/focus-rect/focus-ring-outline-color-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt index ee8ac49..7b666c3 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt
@@ -6,7 +6,7 @@ C layer at (0,0) size 39x18 LayoutNGBlockFlow (positioned) {DIV} at (8,50) size 39x18 - LayoutMenuList {SELECT} at (0,0) size 39x18 [bgcolor=#F8F8F8] + LayoutFlexibleBox {SELECT} at (0,0) size 39x18 [bgcolor=#F8F8F8] LayoutText {#text} at (0,0) size 0x0 layer at (8,0) size 8x18 LayoutBlockFlow {DIV} at (8,0) size 8x18
diff --git a/third_party/blink/web_tests/platform/win/editing/caret/caret-color-014-expected.png b/third_party/blink/web_tests/platform/win/editing/caret/caret-color-014-expected.png index d8b98b6f..6dd3649 100644 --- a/third_party/blink/web_tests/platform/win/editing/caret/caret-color-014-expected.png +++ b/third_party/blink/web_tests/platform/win/editing/caret/caret-color-014-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/editing/caret/caret-color-015-expected.png b/third_party/blink/web_tests/platform/win/editing/caret/caret-color-015-expected.png index d4fec29..f7d977a 100644 --- a/third_party/blink/web_tests/platform/win/editing/caret/caret-color-015-expected.png +++ b/third_party/blink/web_tests/platform/win/editing/caret/caret-color-015-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/editing/selection/replaced-boundaries-3-expected.txt b/third_party/blink/web_tests/platform/win/editing/selection/replaced-boundaries-3-expected.txt index d64e6da..4c6aa78 100644 --- a/third_party/blink/web_tests/platform/win/editing/selection/replaced-boundaries-3-expected.txt +++ b/third_party/blink/web_tests/platform/win/editing/selection/replaced-boundaries-3-expected.txt
@@ -16,7 +16,7 @@ LayoutText {#text} at (0,0) size 22x19 text run at (0,0) width 22: "abc" LayoutBR {BR} at (22,15) size 0x0 - LayoutMenuList {SELECT} at (0,20) size 235x20 [bgcolor=#FFFFFF] [border: (1px solid #767676)] + LayoutFlexibleBox {SELECT} at (0,20) size 235x20 [bgcolor=#FFFFFF] [border: (1px solid #767676)] LayoutText {#text} at (0,0) size 0x0 layer at (13,85) size 211x18 LayoutBlockFlow {DIV} at (5,1) size 211x18
diff --git a/third_party/blink/web_tests/platform/win/fast/css/focus-ring-detached-expected.png b/third_party/blink/web_tests/platform/win/fast/css/focus-ring-detached-expected.png index 1d9ea8a..95d0df9 100644 --- a/third_party/blink/web_tests/platform/win/fast/css/focus-ring-detached-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/css/focus-ring-detached-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/css/focus-ring-multiline-expected.png b/third_party/blink/web_tests/platform/win/fast/css/focus-ring-multiline-expected.png index 4ad5bbfb..28c26af 100644 --- a/third_party/blink/web_tests/platform/win/fast/css/focus-ring-multiline-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/css/focus-ring-multiline-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/css/focus-ring-outline-color-expected.png b/third_party/blink/web_tests/platform/win/fast/css/focus-ring-outline-color-expected.png index 23d466b..1843a383 100644 --- a/third_party/blink/web_tests/platform/win/fast/css/focus-ring-outline-color-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/css/focus-ring-outline-color-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/css/focus-ring-outline-offset-expected.png b/third_party/blink/web_tests/platform/win/fast/css/focus-ring-outline-offset-expected.png index 5b79e8e..63f6227 100644 --- a/third_party/blink/web_tests/platform/win/fast/css/focus-ring-outline-offset-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/css/focus-ring-outline-offset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/css/focus-ring-outline-width-expected.png b/third_party/blink/web_tests/platform/win/fast/css/focus-ring-outline-width-expected.png index 6d2863c9..71e89e6 100644 --- a/third_party/blink/web_tests/platform/win/fast/css/focus-ring-outline-width-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/css/focus-ring-outline-width-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/events/reveal-link-when-focused-expected.png b/third_party/blink/web_tests/platform/win/fast/events/reveal-link-when-focused-expected.png index 7149f78..981c875 100644 --- a/third_party/blink/web_tests/platform/win/fast/events/reveal-link-when-focused-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/events/reveal-link-when-focused-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/select/menulist-update-text-popup-expected.txt b/third_party/blink/web_tests/platform/win/fast/forms/select/menulist-update-text-popup-expected.txt index 0efb85f..8a9ea9a8 100644 --- a/third_party/blink/web_tests/platform/win/fast/forms/select/menulist-update-text-popup-expected.txt +++ b/third_party/blink/web_tests/platform/win/fast/forms/select/menulist-update-text-popup-expected.txt
@@ -6,7 +6,7 @@ C layer at (0,0) size 33x20 LayoutNGBlockFlow (positioned) {DIV} at (8,50) size 33x20 - LayoutMenuList {SELECT} at (0,0) size 33x20 [bgcolor=#FFFFFF] [border: (1px solid #767676)] + LayoutFlexibleBox {SELECT} at (0,0) size 33x20 [bgcolor=#FFFFFF] [border: (1px solid #767676)] LayoutText {#text} at (0,0) size 0x0 layer at (5,1) size 9x18 LayoutBlockFlow {DIV} at (5,1) size 9x18
diff --git a/third_party/blink/web_tests/platform/win/fast/inline/inline-focus-ring-expected.png b/third_party/blink/web_tests/platform/win/fast/inline/inline-focus-ring-expected.png index 4a4148e..f5df90a 100644 --- a/third_party/blink/web_tests/platform/win/fast/inline/inline-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/inline/inline-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/outline/focus-layers-expected.png b/third_party/blink/web_tests/platform/win/paint/invalidation/outline/focus-layers-expected.png index 48c75ef..320a265 100644 --- a/third_party/blink/web_tests/platform/win/paint/invalidation/outline/focus-layers-expected.png +++ b/third_party/blink/web_tests/platform/win/paint/invalidation/outline/focus-layers-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/blink/web_tests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index fd7df3e9..3a4e36d 100644 --- a/third_party/blink/web_tests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/blink/web_tests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt index c2ba0403..08af6b64 100644 --- a/third_party/blink/web_tests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt +++ b/third_party/blink/web_tests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.txt
@@ -18,7 +18,7 @@ }, { "object": "NGPhysicalBoxFragment LayoutInline A", - "rect": [383, 1010, 48, 23], + "rect": [382, 1009, 50, 25], "reason": "appeared" }, {
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/focus-rect/focus-ring-detached-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/focus-rect/focus-ring-detached-expected.png new file mode 100644 index 0000000..2c571709 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/focus-rect/focus-ring-detached-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/focus-rect/focus-ring-multiline-link-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/focus-rect/focus-ring-multiline-link-expected.png new file mode 100644 index 0000000..15d227f --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/focus-rect/focus-ring-multiline-link-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh/focus-rect/focus-ring-outline-color-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/focus-rect/focus-ring-outline-color-expected.png new file mode 100644 index 0000000..2b587f0 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh/focus-rect/focus-ring-outline-color-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt b/third_party/blink/web_tests/platform/win/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt index 275e1b5a..825b9c5 100644 --- a/third_party/blink/web_tests/platform/win/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt +++ b/third_party/blink/web_tests/platform/win/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-update-text-popup-expected.txt
@@ -6,7 +6,7 @@ C layer at (0,0) size 33x20 LayoutNGBlockFlow (positioned) {DIV} at (8,50) size 33x20 - LayoutMenuList {SELECT} at (0,0) size 33x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)] + LayoutFlexibleBox {SELECT} at (0,0) size 33x20 [bgcolor=#FFFFFF] [border: (1px solid #A9A9A9)] LayoutText {#text} at (0,0) size 0x0 layer at (5,1) size 9x18 LayoutBlockFlow {DIV} at (5,1) size 9x18
diff --git a/third_party/blink/web_tests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/blink/web_tests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index aab0d8d..3469af3 100644 --- a/third_party/blink/web_tests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/blink/web_tests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/controls-refresh/calendar-picker/date-picker-ax.html b/third_party/blink/web_tests/virtual/controls-refresh/calendar-picker/date-picker-ax.html new file mode 100644 index 0000000..90af4738 --- /dev/null +++ b/third_party/blink/web_tests/virtual/controls-refresh/calendar-picker/date-picker-ax.html
@@ -0,0 +1,54 @@ +<!DOCTYPE html> +<html> +<head> + <script src="../../../resources/testharness.js"></script> + <script src="../../../resources/testharnessreport.js"></script> + <script src="../../../fast/forms/resources/common.js"></script> + <script src="../../../fast/forms/resources/picker-common.js"></script> + <script src="../../../fast/forms/calendar-picker/resources/calendar-picker-common.js"></script> +</head> +<body> + +<input type="date" id="date1" value="2000-01-02"> + +<script> +async_test((t) => { + var markDirtyCounter = 0; + var focusCounter = 0; + var date1 = document.getElementById('date1'); + openPicker(date1, () => { + assert_equals(focusCounter, 2, "Expected 2 Focus events from opening popup."); + assert_equals(markDirtyCounter, 3, "Expected 3 MarkDirty events from opening popup."); + console.log('Press right arrow to adjust date'); + eventSender.keyDown('ArrowRight'); + }); + + accessibilityController.setNotificationListener(function(axnode, type) { + if (type == 'Focus') { + console.log('Received Focus event: ' + accessibilityController.focusedElement.name.replace(/,/g, '')); + focusCounter++; + } else if (type == 'MarkDirty') { + console.log('Received MarkDirty event'); + if (++markDirtyCounter == 4) { + assert_equals(date1.value, "2000-01-03", "Expected arrow key to change date"); + console.log('Open the month switcher menu.'); + setTimeout(() => { clickMonthPopupButton(); }, 0); + } else if (markDirtyCounter == 6) { + console.log('Highlighting 2000-02 in the month popup'); + setTimeout(function() { eventSender.keyDown('ArrowRight'); }, 0); + } else if (markDirtyCounter == 8) { + console.log('Pressing enter to submit month switcher menu selection'); + setTimeout(function() { eventSender.keyDown('Enter'); }, 0); + } + } + + if (focusCounter == 7 && markDirtyCounter == 10) { + assert_equals(date1.value, "2000-02-03", "Submitting month switcher should have udpated control value"); + t.done(); + } + }); +}, 'Tests that typing an arrow key and opening month switcher menu dispatches |Focus| and |MarkDirty| a11y events.'); + +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/virtual/controls-refresh/focus-rect/focus-ring-detached-expected.png b/third_party/blink/web_tests/virtual/controls-refresh/focus-rect/focus-ring-detached-expected.png deleted file mode 100644 index eb60f66ae..0000000 --- a/third_party/blink/web_tests/virtual/controls-refresh/focus-rect/focus-ring-detached-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/virtual/controls-refresh/focus-rect/focus-ring-multiline-link-expected.png b/third_party/blink/web_tests/virtual/controls-refresh/focus-rect/focus-ring-multiline-link-expected.png deleted file mode 100644 index cb4dda686..0000000 --- a/third_party/blink/web_tests/virtual/controls-refresh/focus-rect/focus-ring-multiline-link-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/virtual/controls-refresh/focus-rect/focus-ring-outline-color-expected.png b/third_party/blink/web_tests/virtual/controls-refresh/focus-rect/focus-ring-outline-color-expected.png deleted file mode 100644 index 5fa8db6..0000000 --- a/third_party/blink/web_tests/virtual/controls-refresh/focus-rect/focus-ring-outline-color-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/virtual/controls-refresh/month-picker/month-picker-ax.html b/third_party/blink/web_tests/virtual/controls-refresh/month-picker/month-picker-ax.html new file mode 100644 index 0000000..c41c188 --- /dev/null +++ b/third_party/blink/web_tests/virtual/controls-refresh/month-picker/month-picker-ax.html
@@ -0,0 +1,45 @@ +<!DOCTYPE html> +<html> +<head> + <script src="../../../resources/testharness.js"></script> + <script src="../../../resources/testharnessreport.js"></script> + <script src="../../../fast/forms/resources/common.js"></script> + <script src="../../../fast/forms/resources/picker-common.js"></script> + <script src="../../../fast/forms/calendar-picker/resources/calendar-picker-common.js"></script> +</head> + +<body> +<input type="month" id="month1" value="2000-01"> + +<script> +async_test((t) => { + var markDirtyCounter = 0; + var focusCounter = 0; + accessibilityController.setNotificationListener(function(axnode, type) { + if (type == 'Focus') { + console.log('Focused: ' + accessibilityController.focusedElement.name.replace(/,/g, '')); + focusCounter++; + } else if (type == 'MarkDirty') { + console.log('Received MarkDirty'); + markDirtyCounter++; + } + + if (focusCounter == 3 && markDirtyCounter == 1) { + assert_equals(month1.value, "2000-05", "Arrow key in month picker should have changed value"); + t.done(); + } + }); + + var month1 = document.getElementById('month1'); + function test1() { + assert_equals(focusCounter, 2, "Expected 2 Focus events from opening popup."); + assert_equals(markDirtyCounter, 1, "Expected 1 MarkDirty events from opening popup."); + eventSender.keyDown('ArrowDown'); + } + + openPicker(month1, test1); +}, 'Tests if typing an arrow key dispatches |Focus| and |MarkDirty| a11y events.'); + +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-ax.html b/third_party/blink/web_tests/virtual/controls-refresh/week-picker/week-picker-ax.html similarity index 65% rename from third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-ax.html rename to third_party/blink/web_tests/virtual/controls-refresh/week-picker/week-picker-ax.html index 1b3172f..9dfa7f4 100644 --- a/third_party/blink/web_tests/fast/forms/calendar-picker/week-picker-ax.html +++ b/third_party/blink/web_tests/virtual/controls-refresh/week-picker/week-picker-ax.html
@@ -3,8 +3,8 @@ <head> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> - <script src="../../forms/resources/picker-common.js"></script> - <script src="resources/calendar-picker-common.js"></script> + <script src="../../../fast/forms/resources/picker-common.js"></script> + <script src="../../../fast/forms/calendar-picker/resources/calendar-picker-common.js"></script> </head> <body> @@ -21,22 +21,23 @@ } else if (type == 'MarkDirty') { console.log('Received MarkDirty'); markDirtyCounter++; - if (focusCounter == 2 && markDirtyCounter == 2) { - t.done(); - } + } + + if (focusCounter == 3 && markDirtyCounter == 4) { + t.done(); } }); var week1 = document.getElementById('week1'); function test1() { - eventSender.keyDown('ArrowDown'); + assert_equals(focusCounter, 2, "Expected 2 Focus events from opening picker"); + assert_equals(markDirtyCounter, 3, "Expected 3 MarkDirty events from opening picker"); + eventSender.keyDown('ArrowDown'); } openPicker(week1, test1); }, 'Tests if typing an arrow key dispatches |Focus| and |MarkDirty| a11y events.'); - - </script> </body> </html>
diff --git a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 8afc09e..81e0853 100644 --- a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -655,6 +655,7 @@ interface IDBTransaction : EventTarget attribute @@toStringTag getter db + getter durability getter error getter mode getter objectStoreNames
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt index 7f279cb9..cc0f57e5 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -616,6 +616,7 @@ [Worker] interface IDBTransaction : EventTarget [Worker] attribute @@toStringTag [Worker] getter db +[Worker] getter durability [Worker] getter error [Worker] getter mode [Worker] getter objectStoreNames
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt index 853422d..3a92de1 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -3842,6 +3842,7 @@ interface IDBTransaction : EventTarget attribute @@toStringTag getter db + getter durability getter error getter mode getter objectStoreNames @@ -8979,14 +8980,6 @@ method constructor method iterateNext method snapshotItem -interface XR : EventTarget - attribute @@toStringTag - getter ondevicechange - method constructor - method isSessionSupported - method requestSession - method supportsSession - setter ondevicechange interface XRBoundedReferenceSpace : XRReferenceSpace attribute @@toStringTag getter boundsGeometry @@ -9111,6 +9104,14 @@ interface XRSpace : EventTarget attribute @@toStringTag method constructor +interface XRSystem : EventTarget + attribute @@toStringTag + getter ondevicechange + method constructor + method isSessionSupported + method requestSession + method supportsSession + setter ondevicechange interface XRTransientInputHitTestResult attribute @@toStringTag getter inputSource
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt index 3685b8a..fca5c384 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -611,6 +611,7 @@ [Worker] interface IDBTransaction : EventTarget [Worker] attribute @@toStringTag [Worker] getter db +[Worker] getter durability [Worker] getter error [Worker] getter mode [Worker] getter objectStoreNames
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index 32802f3..a7387dc 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -11157,14 +11157,6 @@ method constructor method iterateNext method snapshotItem -interface XR : EventTarget - attribute @@toStringTag - getter ondevicechange - method constructor - method isSessionSupported - method requestSession - method supportsSession - setter ondevicechange interface XRAnchor attribute @@toStringTag getter anchorSpace @@ -11366,6 +11358,14 @@ getter coefficients getter orientation method constructor +interface XRSystem : EventTarget + attribute @@toStringTag + getter ondevicechange + method constructor + method isSessionSupported + method requestSession + method supportsSession + setter ondevicechange interface XRTransientInputHitTestResult attribute @@toStringTag getter inputSource
diff --git a/third_party/closure_compiler/externs/automation.js b/third_party/closure_compiler/externs/automation.js index de666a44..58b2b54 100644 --- a/third_party/closure_compiler/externs/automation.js +++ b/third_party/closure_compiler/externs/automation.js
@@ -314,9 +314,11 @@ ANNOTATE_PAGE_IMAGES: 'annotatePageImages', BLUR: 'blur', CLEAR_ACCESSIBILITY_FOCUS: 'clearAccessibilityFocus', + COLLAPSE: 'collapse', CUSTOM_ACTION: 'customAction', DECREMENT: 'decrement', DO_DEFAULT: 'doDefault', + EXPAND: 'expand', FOCUS: 'focus', GET_IMAGE_DATA: 'getImageData', GET_TEXT_LOCATION: 'getTextLocation',
diff --git a/third_party/inspector_protocol/README.chromium b/third_party/inspector_protocol/README.chromium index ff550f96..70c1dd2 100644 --- a/third_party/inspector_protocol/README.chromium +++ b/third_party/inspector_protocol/README.chromium
@@ -2,7 +2,7 @@ Short Name: inspector_protocol URL: https://chromium.googlesource.com/deps/inspector_protocol/ Version: 0 -Revision: 1f2492b6768e8620ece36a784c8ecd7ae7091610 +Revision: 81ef742ba3587767fc08652d299df9e9b7051407 License: BSD License File: LICENSE Security Critical: yes
diff --git a/third_party/inspector_protocol/crdtp/json.cc b/third_party/inspector_protocol/crdtp/json.cc index 8c64313..5b935783 100644 --- a/third_party/inspector_protocol/crdtp/json.cc +++ b/third_party/inspector_protocol/crdtp/json.cc
@@ -285,7 +285,22 @@ Emit("null"); return; } + // If |value| is a scalar, emit it as an int. Taken from json_writer.cc in + // Chromium. + if (value <= std::numeric_limits<int64_t>::max() && + value >= std::numeric_limits<int64_t>::min() && + std::floor(value) == value) { + Emit(std::to_string(static_cast<int64_t>(value))); + return; + } std::string str_value = json::platform::DToStr(value); + // The following is somewhat paranoid, but also taken from json_writer.cc + // in Chromium: + // Ensure that the number has a .0 if there's no decimal or 'e'. This + // makes sure that when we read the JSON back, it's interpreted as a + // real rather than an int. + if (str_value.find_first_of(".eE") == std::string::npos) + str_value.append(".0"); // DToStr may fail to emit a 0 before the decimal dot. E.g. this is // the case in base::NumberToString in Chromium (which is based on
diff --git a/third_party/inspector_protocol/crdtp/json_test.cc b/third_party/inspector_protocol/crdtp/json_test.cc index 5afac86e..1451d96 100644 --- a/third_party/inspector_protocol/crdtp/json_test.cc +++ b/third_party/inspector_protocol/crdtp/json_test.cc
@@ -184,6 +184,32 @@ out); } +TEST(JsonStdStringWriterTest, ScalarsAreRenderedAsInt) { + // Test that Number.MIN_SAFE_INTEGER / Number.MAX_SAFE_INTEGER from Javascript + // are rendered as integers (no decimal point / rounding), even when we + // encode them from double. Javascript's Number is an IEE754 double, so + // it has 53 bits to represent integers. + std::string out; + Status status; + std::unique_ptr<ParserHandler> writer = NewJSONEncoder(&out, &status); + writer->HandleMapBegin(); + + writer->HandleString8(SpanFrom("Number.MIN_SAFE_INTEGER")); + EXPECT_EQ(-0x1fffffffffffff, -9007199254740991); // 53 bits for integers. + writer->HandleDouble(-9007199254740991); // Note HandleDouble here. + + writer->HandleString8(SpanFrom("Number.MAX_SAFE_INTEGER")); + EXPECT_EQ(0x1fffffffffffff, 9007199254740991); // 53 bits for integers. + writer->HandleDouble(9007199254740991); // Note HandleDouble here. + + writer->HandleMapEnd(); + EXPECT_TRUE(status.ok()); + EXPECT_EQ( + "{\"Number.MIN_SAFE_INTEGER\":-9007199254740991," + "\"Number.MAX_SAFE_INTEGER\":9007199254740991}", + out); +} + TEST(JsonStdStringWriterTest, RepresentingNonFiniteValuesAsNull) { // JSON can't represent +Infinity, -Infinity, or NaN. // So in practice it's mapped to null.
diff --git a/tools/gritsettings/translation_expectations.pyl b/tools/gritsettings/translation_expectations.pyl index bbed0ba..85cd78e 100644 --- a/tools/gritsettings/translation_expectations.pyl +++ b/tools/gritsettings/translation_expectations.pyl
@@ -38,7 +38,6 @@ "chrome/app/google_chrome_strings.grd", "chrome/browser/resources/chromeos/camera/src/strings/camera_strings.grd", "chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings.grd", - "chrome/browser/resources/chromeos/accessibility/switch_access/strings/switch_access_strings.grd", "chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings.grd", "chrome/browser/ui/android/strings/android_chrome_strings.grd", "chrome/credential_provider/gaiacp/gaia_resources.grd",
diff --git a/tools/mb/mb.py b/tools/mb/mb.py index 0c1c5029..3083dad 100755 --- a/tools/mb/mb.py +++ b/tools/mb/mb.py
@@ -1310,7 +1310,6 @@ vals.get('cros_passthrough', False)) is_mac = self.platform == 'darwin' is_msan = 'is_msan=true' in vals['gn_args'] - is_ios = 'target_os="ios"' in vals['gn_args'] err = '' for f in files: @@ -1320,11 +1319,6 @@ if is_android: break - # iOS has generated directories in gn data items. - # Skipping for iOS instead of listing all apps. - if is_ios: - break - # Skip a few existing violations that need to be cleaned up. Each of # these will lead to incorrect incremental builds if their directory # contents change. Do not add to this list.
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 7031260..ec38c10 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -26603,6 +26603,8 @@ <int value="3167" label="XRSessionRequestHitTestSourceForTransientInput"/> <int value="3168" label="XRDOMOverlay"/> <int value="3169" label="CssStyleSheetReplaceWithImport"/> + <int value="3170" label="CryptoAlgorithmEd25519"/> + <int value="3171" label="CryptoAlgorithmX25519"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -65019,6 +65021,7 @@ <int value="11" label="kErrorCreateMatcher_FileReadError"/> <int value="12" label="kErrorCreateMatcher_ChecksumMismatch"/> <int value="13" label="kErrorCreateMatcher_VersionMismatch"/> + <int value="14" label="kErrorRegexTooLarge"/> </enum> <enum name="UpdateEngineAttemptResult">
diff --git a/tools/metrics/histograms/expand_owners.py b/tools/metrics/histograms/expand_owners.py index 0e5ff3f..5bccb1b9 100644 --- a/tools/metrics/histograms/expand_owners.py +++ b/tools/metrics/histograms/expand_owners.py
@@ -229,6 +229,8 @@ owner_elements = [] # TODO(crbug.com/987709): An OWNERS file API would be ideal. emails_from_owners_file = _ExtractEmailAddressesFromOWNERS(path) + if not emails_from_owners_file: + raise Error('No emails could be derived from {}.'.format(path)) # A list is used to respect the order of email addresses in the OWNERS file. deduped_emails_from_owners_file = [] @@ -332,7 +334,7 @@ owners_to_add = _MakeOwners( owner.ownerDocument, path, emails_with_dom_elements) if not owners_to_add: - raise Error('No emails could be derived from {}.'.format(path)) + continue _UpdateHistogramOwners(histogram, owner, owners_to_add)
diff --git a/tools/metrics/histograms/expand_owners_unittest.py b/tools/metrics/histograms/expand_owners_unittest.py index 533a48d..25803c6 100644 --- a/tools/metrics/histograms/expand_owners_unittest.py +++ b/tools/metrics/histograms/expand_owners_unittest.py
@@ -295,7 +295,7 @@ <histograms> <histogram name="Caffeination" units="mg"> - <owner>joe@chormium.org</owner> + <owner>joe@chromium.org</owner> <owner>src/medium/medium/roast/OWNERS</owner> <summary>I like coffee.</summary> </histogram> @@ -320,7 +320,7 @@ <histograms> <histogram name="Caffeination" units="mg"> - <owner>joe@chormium.org</owner> + <owner>joe@chromium.org</owner> <owner>{}</owner> <summary>I like coffee.</summary> </histogram> @@ -333,13 +333,42 @@ r'No emails could be derived from .*empty_OWNERS\.'): expand_owners.ExpandHistogramsOWNERS(histograms_without_owners_from_file) + with self.assertRaisesRegexp( + expand_owners.Error, + r'The file at .*src/medium/medium/roast/OWNERS does not exist\.'): + expand_owners.ExpandHistogramsOWNERS(histograms_with_fake_file_path) + + def testExpandOwnersWithSameOwners(self): + """Checks that no error is raised when all owners in a file are already in <owner> elements.""" + absolute_path = _MakeOwnersFile('same_OWNERS', self.temp_dir) + src_relative_path = _GetSrcRelativePath(absolute_path) + + with open(absolute_path, 'w') as owners_file: + owners_file.write( + 'joe@chromium.org') # Write to the file so that it exists. + + histograms_string = xml.dom.minidom.parseString(""" +<histograms> + +<histogram name="Caffeination" units="mg"> + <owner>joe@chromium.org</owner> + <owner>{}</owner> + <summary>I like coffee.</summary> +</histogram> + +</histograms> +""".format(src_relative_path)) + + self.assertEqual( + expand_owners.ExpandHistogramsOWNERS(histograms_string), []) + def testExpandOwnersWithoutOWNERSPathPrefix(self): """Checks that an error is raised when the path is not well-formatted.""" histograms_without_src_prefix = xml.dom.minidom.parseString(""" <histograms> <histogram name="Caffeination" units="mg"> - <owner>joe@chormium.org</owner> + <owner>joe@chromium.org</owner> <owner>latte/OWNERS</owner> <summary>I like coffee.</summary> </histogram> @@ -358,7 +387,7 @@ <histograms> <histogram name="Caffeination" units="mg"> - <owner>joe@chormium.org</owner> + <owner>joe@chromium.org</owner> <owner>src/latte/file</owner> <summary>I like coffee.</summary> </histogram>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index fa66457..8aa3c06 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -6447,8 +6447,9 @@ </histogram> <histogram name="Apps.AppListSearchResultOpenDisplayType" - enum="AppListSearchResultDisplayType" expires_after="2020-02-16"> + enum="AppListSearchResultDisplayType" expires_after="2021-02-16"> <owner>calamity@chromium.org</owner> + <owner>src/ash/app_list/OWNERS</owner> <summary> The display type of the app list search result that was opened by the user. This is gathered per click of a search result. @@ -61513,8 +61514,9 @@ </histogram> <histogram name="History.HistoryPageView" enum="HistoryPageView" - expires_after="2020-03-01"> + expires_after="2021-03-01"> <owner>calamity@chromium.org</owner> + <owner>src/chrome/browser/resources/history/OWNERS</owner> <summary> The page of the History page shown to the user. Logged each time the user loads the History page or switches pages.
diff --git a/tools/style_variable_generator/.style.yapf b/tools/style_variable_generator/.style.yapf new file mode 100644 index 0000000..557fa7b --- /dev/null +++ b/tools/style_variable_generator/.style.yapf
@@ -0,0 +1,2 @@ +[style] +based_on_style = pep8
diff --git a/tools/style_variable_generator/OWNERS b/tools/style_variable_generator/OWNERS new file mode 100644 index 0000000..af15dc133 --- /dev/null +++ b/tools/style_variable_generator/OWNERS
@@ -0,0 +1,2 @@ +calamity@chromium.org +ortuno@chromium.org
diff --git a/tools/style_variable_generator/PRESUBMIT.py b/tools/style_variable_generator/PRESUBMIT.py new file mode 100644 index 0000000..f534a6f --- /dev/null +++ b/tools/style_variable_generator/PRESUBMIT.py
@@ -0,0 +1,20 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Presubmit script for changes affecting tools/style_variable_generator/ + +See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts +for more details about the presubmit API built into depot_tools. +""" + +WHITELIST = [r'.+_test.py$'] + + +def CheckChangeOnUpload(input_api, output_api): + return input_api.canned_checks.RunUnitTestsInDirectory( + input_api, output_api, '.', whitelist=WHITELIST) + + +def CheckChangeOnCommit(input_api, output_api): + return input_api.canned_checks.RunUnitTestsInDirectory( + input_api, output_api, '.', whitelist=WHITELIST)
diff --git a/tools/style_variable_generator/README.md b/tools/style_variable_generator/README.md new file mode 100644 index 0000000..e46fb1a --- /dev/null +++ b/tools/style_variable_generator/README.md
@@ -0,0 +1,14 @@ +# style_variable_generator + +This is a python tool that generates cross-platform style variables in order to +centralize UI constants. + +This script uses third_party/pyjson5 to read input json5 files and then +generates various output formats as needed by clients (e.g CSS Variables, +preview HTML page). + +For input format examples, see the \*_test.json5 files which contain up to date +illustrations of each feature, as well as expected outputs in the corresponding +\*_test_expected.\* files. + +Run `python style_variable_generator.py -h` for usage details.
diff --git a/tools/style_variable_generator/base_generator.py b/tools/style_variable_generator/base_generator.py new file mode 100644 index 0000000..50dc39ea --- /dev/null +++ b/tools/style_variable_generator/base_generator.py
@@ -0,0 +1,117 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +import sys +import collections +import re +import textwrap +from color import Color + +_FILE_PATH = os.path.dirname(os.path.realpath(__file__)) + +_JSON5_PATH = os.path.join(_FILE_PATH, os.pardir, os.pardir, 'third_party', + 'pyjson5', 'src') +sys.path.insert(1, _JSON5_PATH) +import json5 + +_JINJA2_PATH = os.path.join(_FILE_PATH, os.pardir, os.pardir, 'third_party') +sys.path.insert(1, _JINJA2_PATH) +import jinja2 + + +class Modes: + LIGHT = 'light' + DARK = 'dark' + ALL = [LIGHT, DARK] + + +class ModeVariables: + '''A representation of variables to generate for a single Mode. + ''' + + def __init__(self): + self.colors = collections.OrderedDict() + + def AddColor(self, name, value_str): + if name in self.colors: + raise ValueError('%s defined more than once' % name) + + try: + self.colors[name] = Color(value_str) + except Exception as err: + raise ValueError('Error parsing "%s": %s' % (value_str, err)) + + +class BaseGenerator: + '''A generic style variable generator. + + Subclasses should provide format-specific generation templates, filters and + globals to render their output. + ''' + + def __init__(self): + self._mode_variables = dict() + # The mode that colors will fallback to when not specified in a + # non-default mode. An error will be raised if a color in any mode is + # not specified in the default mode. + self._default_mode = Modes.LIGHT + + for mode in Modes.ALL: + self._mode_variables[mode] = ModeVariables() + + def AddColor(self, name, value_obj): + if isinstance(value_obj, unicode): + self._mode_variables[self._default_mode].AddColor(name, value_obj) + elif isinstance(value_obj, dict): + for mode in Modes.ALL: + if mode in value_obj: + self._mode_variables[mode].AddColor(name, value_obj[mode]) + + def AddJSONFileToModel(self, path): + with open(path, 'r') as f: + # TODO(calamity): Add allow_duplicate_keys=False once pyjson5 is + # rolled. + data = json5.loads( + f.read(), object_pairs_hook=collections.OrderedDict) + + try: + for name, value in data['colors'].items(): + if not re.match('^[a-z0-9_]+$', name): + raise ValueError( + '%s is not a valid variable name (lower case, 0-9, _)' + % name) + + self.AddColor(name, value) + except Exception as err: + raise ValueError('\n%s:\n %s' % (path, err)) + + def ApplyTemplate(self, style_generator, path_to_template, params): + current_dir = os.path.dirname(os.path.realpath(__file__)) + jinja_env = jinja2.Environment( + loader=jinja2.FileSystemLoader(current_dir), + keep_trailing_newline=True) + jinja_env.globals.update(style_generator.GetGlobals()) + jinja_env.filters.update(style_generator.GetFilters()) + template = jinja_env.get_template(path_to_template) + return template.render(params) + + def Validate(self): + def CheckIsInDefaultModel(name): + if name not in self._mode_variables[self._default_mode].colors: + raise ValueError( + "%s not defined in '%s' mode" % (name, self._default_mode)) + + # Check all colors in all models refer to colors that exist in the + # default mode. + for m in self._mode_variables.values(): + for name, value in m.colors.items(): + if value.var: + CheckIsInDefaultModel(value.var) + if value.rgb_var: + CheckIsInDefaultModel(value.rgb_var[:-4]) + + # TODO(calamity): Check for circular references. + + # TODO(crbug.com/1053372): Prune unused rgb values.
diff --git a/tools/style_variable_generator/color.py b/tools/style_variable_generator/color.py new file mode 100644 index 0000000..8dc8532 --- /dev/null +++ b/tools/style_variable_generator/color.py
@@ -0,0 +1,138 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import re +import textwrap + + +class Color: + '''A representation of a single color value. + + This color can be of the following formats: + - #RRGGBB + - rgb(r, g, b) + - rgba(r, g, b, a) + - $other_color + - rgb($other_color_rgb) + - rgba($other_color_rgb, a) + + NB: The color components that refer to other colors' RGB values must end + with '_rgb'. + ''' + + def __init__(self, value_str): + # TODO(calamity): Add opacity-only values + self.var = None + self.rgb_var = None + self.r = 0 + self.g = 0 + self.b = 0 + self.a = 1 + self.Parse(value_str) + + def _AssignRGB(self, rgb): + for v in rgb: + if not (0 <= v <= 255): + raise ValueError('RGB value out of bounds') + + (self.r, self.g, self.b) = rgb + + def _ParseRGBRef(self, rgb_ref): + match = re.match('^\$([a-z0-9_]+_rgb)$', rgb_ref) + if not match: + raise ValueError('Expected a reference to an RGB variable') + + self.rgb_var = match.group(1) + + def _ParseAlpha(self, alpha_value): + self.a = float(alpha_value) + if not (0 <= self.a <= 1): + raise ValueError('Alpha expected to be between 0 and 1') + + def Parse(self, value): + def ParseHex(value): + match = re.match('^#([0-9a-f]*)$', value) + if not match: + return False + + value = match.group(1) + if len(value) != 6: + raise ValueError('Expected #RRGGBB') + + self._AssignRGB([int(x, 16) for x in textwrap.wrap(value, 2)]) + + return True + + def ParseRGB(value): + match = re.match('^rgb\((.*)\)$', value) + if not match: + return False + + values = match.group(1).split(',') + if len(values) == 1: + self._ParseRGBRef(values[0]) + return True + + if len(values) == 3: + self._AssignRGB([int(x) for x in values]) + return True + + raise ValueError( + 'rgb() expected to have either 1 reference or 3 ints') + + def ParseRGBA(value): + match = re.match('^rgba\((.*)\)$', value) + if not match: + return False + + values = match.group(1).split(',') + if len(values) == 2: + self._ParseRGBRef(values[0]) + self._ParseAlpha(values[1]) + return True + + if len(values) == 4: + self._AssignRGB([int(x) for x in values[0:3]]) + self._ParseAlpha(values[3]) + return True + + raise ValueError('rgba() expected to have either' + '1 reference + alpha, or 3 ints + alpha') + + def ParseVariableReference(value): + match = re.match('^\$(.*)$', value) + if not match: + return False + + if value.endswith('_rgb'): + raise ValueError( + 'color reference cannot resolve to an rgb reference') + + self.var = match.group(1) + return True + + parsers = [ + ParseHex, + ParseRGB, + ParseRGBA, + ParseVariableReference, + ] + + parsed = False + for p in parsers: + parsed = p(value) + if parsed: + break + + if not parsed: + raise ValueError('Malformed color value') + + def __repr__(self): + if self.var: + return 'var(--%s)' % self.var + + if self.rgb_var: + return 'rgba(var(--%s), %g)' % (self.rgb_var, self.a) + + return 'rgba(%d, %d, %d, %g)' % (self.r, self.g, self.b, self.a)
diff --git a/tools/style_variable_generator/color_test.py b/tools/style_variable_generator/color_test.py new file mode 100644 index 0000000..6860079 --- /dev/null +++ b/tools/style_variable_generator/color_test.py
@@ -0,0 +1,80 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from color import Color +import unittest + + +class ColorTest(unittest.TestCase): + def testHexColors(self): + c = Color('#0102ff') + self.assertEqual(c.r, 1) + self.assertEqual(c.g, 2) + self.assertEqual(c.b, 255) + self.assertEqual(c.a, 1) + + def testRGBColors(self): + c = Color('rgb(100, 200, 123)') + self.assertEqual(c.r, 100) + self.assertEqual(c.g, 200) + self.assertEqual(c.b, 123) + self.assertEqual(c.a, 1) + + c = Color('rgb($some_color_rgb)') + self.assertEqual(c.rgb_var, 'some_color_rgb') + self.assertEqual(c.a, 1) + + def testRGBAColors(self): + c = Color('rgba(100, 200, 123, 0.5)') + self.assertEqual(c.r, 100) + self.assertEqual(c.g, 200) + self.assertEqual(c.b, 123) + self.assertEqual(c.a, 0.5) + + c = Color('rgba($some_color_400_rgb, 0.1)') + self.assertEqual(c.rgb_var, 'some_color_400_rgb') + self.assertEqual(c.a, 0.1) + + def testReferenceColor(self): + c = Color('$some_color') + self.assertEqual(c.var, 'some_color') + + def testMalformedColors(self): + with self.assertRaises(ValueError): + # #RRGGBBAA not supported. + Color('#11223311') + + with self.assertRaises(ValueError): + # #RGB not supported. + Color('#fff') + + with self.assertRaises(ValueError): + Color('rgb($non_rgb_var)') + + with self.assertRaises(ValueError): + Color('rgba($non_rgb_var, 0.4)') + + with self.assertRaises(ValueError): + # Invalid alpha. + Color('rgba(1, 2, 4, 2.5)') + + with self.assertRaises(ValueError): + # Invalid alpha. + Color('rgba($non_rgb_var, -1)') + + with self.assertRaises(ValueError): + # Invalid rgb values. + Color('rgb(-1, 5, 5)') + + with self.assertRaises(ValueError): + # Invalid rgb values. + Color('rgb(0, 256, 5)') + + with self.assertRaises(ValueError): + # Color reference points to rgb reference. + Color('$some_color_rgb') + + +if __name__ == '__main__': + unittest.main()
diff --git a/tools/style_variable_generator/colors_test.json5 b/tools/style_variable_generator/colors_test.json5 new file mode 100644 index 0000000..2317aec --- /dev/null +++ b/tools/style_variable_generator/colors_test.json5
@@ -0,0 +1,12 @@ +{ + "colors": { + "google_grey_900": "#202124", + "cros_default_text_color": { + "light": "$google_grey_900", + "dark": "rgb(255, 255, 255)", + }, + "cros_toggle_color": { + "light": "rgba($cros_default_text_color_rgb, 0.1)" + } + }, +}
diff --git a/tools/style_variable_generator/colors_test_expected.css b/tools/style_variable_generator/colors_test_expected.css new file mode 100644 index 0000000..3ebd6b5 --- /dev/null +++ b/tools/style_variable_generator/colors_test_expected.css
@@ -0,0 +1,19 @@ +html { + --google-grey-900-rgb: 32, 33, 36; + --google-grey-900: rgb(var(--google-grey-900-rgb)); + + --cros-default-text-color-rgb: var(--google-grey-900-rgb); + --cros-default-text-color: rgb(var(--cros-default-text-color-rgb)); + + --cros-toggle-color-rgb: var(--cros-default-text-color-rgb); + --cros-toggle-color: rgba(var(--cros-toggle-color-rgb), 0.1); + +} + +@media (prefers-color-scheme: dark) { + html { + --cros-default-text-color-rgb: 255, 255, 255; + --cros-default-text-color: rgb(var(--cros-default-text-color-rgb)); + + } +}
diff --git a/tools/style_variable_generator/css_generator.py b/tools/style_variable_generator/css_generator.py new file mode 100644 index 0000000..b18f5a2 --- /dev/null +++ b/tools/style_variable_generator/css_generator.py
@@ -0,0 +1,69 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from base_generator import Color, Modes, BaseGenerator + + +class CSSStyleGenerator(BaseGenerator): + '''Generator for CSS Variables''' + + def Render(self): + self.Validate() + return self.ApplyTemplate(self, 'css_generator.tmpl', + self.GetParameters()) + + def GetParameters(self): + return { + 'light_variables': self._mode_variables[Modes.LIGHT], + 'dark_variables': self._mode_variables[Modes.DARK], + } + + def GetFilters(self): + return { + 'to_var_name': self._ToVarName, + 'css_color': self._CssColor, + 'css_color_rgb': self._CssColorRGB, + } + + def GetGlobals(self): + return { + 'css_color_from_rgb_var': self._CssColorFromRGBVar, + } + + def _ToVarName(self, var_name): + return '--%s' % var_name.replace('_', '-') + + def _CssColor(self, c): + '''Returns the CSS color representation of |c|''' + assert (isinstance(c, Color)) + if c.var: + return 'var(%s)' % self._ToVarName(c.var) + + if c.rgb_var: + if c.a != 1: + return 'rgba(var(%s), %g)' % (self._ToVarName(c.rgb_var), c.a) + else: + return 'rgb(var(%s))' % self._ToVarName(c.rgb_var) + + if c.a != 1: + return 'rgba(%d, %d, %d, %g)' % (c.r, c.g, c.b, c.a) + else: + return 'rgb(%d, %d, %d)' % (c.r, c.g, c.b) + + def _CssColorRGB(self, c): + '''Returns the CSS rgb representation of |c|''' + if c.var: + return 'var(%s-rgb)' % self._ToVarName(c.var) + + if c.rgb_var: + return 'var(%s)' % self._ToVarName(c.rgb_var) + + return '%d, %d, %d' % (c.r, c.g, c.b) + + def _CssColorFromRGBVar(self, name, alpha): + '''Returns the CSS color representation given a color name and alpha''' + if alpha != 1: + return 'rgba(var(%s-rgb), %g)' % (self._ToVarName(name), alpha) + else: + return 'rgb(var(%s-rgb))' % self._ToVarName(name)
diff --git a/tools/style_variable_generator/css_generator.tmpl b/tools/style_variable_generator/css_generator.tmpl new file mode 100644 index 0000000..8ecebe4 --- /dev/null +++ b/tools/style_variable_generator/css_generator.tmpl
@@ -0,0 +1,17 @@ +html { +{%- for var_name, color in light_variables.colors.items() %} + {{var_name | to_var_name}}-rgb: {{color | css_color_rgb}}; + {{var_name | to_var_name}}: {{css_color_from_rgb_var(var_name, color.a)}}; +{% endfor %} +} + +{% if dark_variables.colors -%} +@media (prefers-color-scheme: dark) { + html { +{%- for var_name, color in dark_variables.colors.items() %} + {{var_name | to_var_name}}-rgb: {{color | css_color_rgb}}; + {{var_name | to_var_name}}: {{css_color_from_rgb_var(var_name, color.a)}}; +{% endfor %} + } +} +{%- endif %}
diff --git a/tools/style_variable_generator/css_generator_test.py b/tools/style_variable_generator/css_generator_test.py new file mode 100644 index 0000000..65ad7877 --- /dev/null +++ b/tools/style_variable_generator/css_generator_test.py
@@ -0,0 +1,24 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from css_generator import CSSStyleGenerator +import unittest + + +class CSSStyleGeneratorTest(unittest.TestCase): + def setUp(self): + self.generator = CSSStyleGenerator() + + def assertEqualToFile(self, value, filename): + with open(filename) as f: + self.assertEqual(value, f.read()) + + def testColorTestJSON(self): + self.generator.AddJSONFileToModel('colors_test.json5') + self.assertEqualToFile(self.generator.Render(), + 'colors_test_expected.css') + + +if __name__ == '__main__': + unittest.main()
diff --git a/tools/style_variable_generator/style_variable_generator.py b/tools/style_variable_generator/style_variable_generator.py new file mode 100644 index 0000000..1f645c4 --- /dev/null +++ b/tools/style_variable_generator/style_variable_generator.py
@@ -0,0 +1,40 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import argparse +import sys +from css_generator import CSSStyleGenerator + + +def main(): + parser = argparse.ArgumentParser( + description='Generate style variables from JSON5 color file.') + + parser.add_argument( + '--generator', + choices=['CSS'], + required=True, + help='type of file to generate') + parser.add_argument('--out-file', help='file to write output to') + parser.add_argument('targets', nargs='+', help='source json5 color files') + + args = parser.parse_args() + + if args.generator == 'CSS': + style_generator = CSSStyleGenerator() + + for t in args.targets: + style_generator.AddJSONFileToModel(t) + + if args.out_file: + with open(args.out_file, 'w') as f: + f.write(style_generator.Render()) + else: + print(style_generator.Render()) + + return 0 + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index ba1d4005..1535a154d 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -142,6 +142,7 @@ <item id="image_annotation" hash_code="107881858" type="0" content_hash_code="96203979" os_list="linux,windows" file_path="services/image_annotation/annotator.cc"/> <item id="indexed_db_internals_handler" hash_code="131180348" type="0" content_hash_code="59026406" os_list="linux,windows" file_path="content/browser/indexed_db/indexed_db_internals_ui.cc"/> <item id="interest_feed_send" hash_code="76717919" type="0" content_hash_code="6240898" os_list="linux,windows" file_path="components/feed/core/feed_networking_host.cc"/> + <item id="interest_feedv2_send" hash_code="85742023" type="0" content_hash_code="11750132" os_list="linux,windows" file_path="components/feed/core/v2/feed_network_impl.cc"/> <item id="intranet_redirect_detector" hash_code="21785164" type="0" content_hash_code="62025595" os_list="linux,windows" file_path="chrome/browser/intranet_redirect_detector.cc"/> <item id="invalidation_service" hash_code="72354423" type="0" deprecated="2020-01-23" content_hash_code="78425687" file_path=""/> <item id="isolated_prerender_loader" hash_code="2181152" type="0" content_hash_code="113933667" os_list="linux,windows" file_path="chrome/browser/prerender/isolated/isolated_prerender_url_loader.cc"/>
diff --git a/ui/accessibility/ax_enum_util.cc b/ui/accessibility/ax_enum_util.cc index 0367582..a344eb01 100644 --- a/ui/accessibility/ax_enum_util.cc +++ b/ui/accessibility/ax_enum_util.cc
@@ -1129,12 +1129,16 @@ return "blur"; case ax::mojom::Action::kClearAccessibilityFocus: return "clearAccessibilityFocus"; + case ax::mojom::Action::kCollapse: + return "collapse"; case ax::mojom::Action::kCustomAction: return "customAction"; case ax::mojom::Action::kDecrement: return "decrement"; case ax::mojom::Action::kDoDefault: return "doDefault"; + case ax::mojom::Action::kExpand: + return "expand"; case ax::mojom::Action::kFocus: return "focus"; case ax::mojom::Action::kGetImageData: @@ -1201,12 +1205,16 @@ return ax::mojom::Action::kBlur; if (0 == strcmp(action, "clearAccessibilityFocus")) return ax::mojom::Action::kClearAccessibilityFocus; + if (0 == strcmp(action, "collapse")) + return ax::mojom::Action::kCollapse; if (0 == strcmp(action, "customAction")) return ax::mojom::Action::kCustomAction; if (0 == strcmp(action, "decrement")) return ax::mojom::Action::kDecrement; if (0 == strcmp(action, "doDefault")) return ax::mojom::Action::kDoDefault; + if (0 == strcmp(action, "expand")) + return ax::mojom::Action::kExpand; if (0 == strcmp(action, "focus")) return ax::mojom::Action::kFocus; if (0 == strcmp(action, "getImageData"))
diff --git a/ui/accessibility/ax_enums.mojom b/ui/accessibility/ax_enums.mojom index 090ff895..a77bfae 100644 --- a/ui/accessibility/ax_enums.mojom +++ b/ui/accessibility/ax_enums.mojom
@@ -350,6 +350,9 @@ // exposed to the open web. See kSetAccessibilityFocus, below. kClearAccessibilityFocus, + // Collapse the collapsible node. + kCollapse, + kCustomAction, // Decrement a slider or range control by one step value. @@ -358,6 +361,9 @@ // Do the default action for an object, typically this means "click". kDoDefault, + // Expand the expandable node. + kExpand, + kFocus, // Return the content of this image object in the image_data attribute.
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc index 15e5849..e0a5e549 100644 --- a/ui/accessibility/ax_node.cc +++ b/ui/accessibility/ax_node.cc
@@ -734,6 +734,19 @@ } } +base::Optional<int> AXNode::GetHierarchicalLevel() const { + int hierarchical_level = + GetIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel); + + // According to the WAI_ARIA spec, a defined hierarchical level value is + // greater than 0. + // https://www.w3.org/TR/wai-aria-1.1/#aria-level + if (hierarchical_level > 0) + return base::Optional<int>(hierarchical_level); + + return base::nullopt; +} + bool AXNode::IsOrderedSetItem() const { return ui::IsItemLike(data().role); } @@ -806,7 +819,8 @@ case ax::mojom::Role::kList: return item_role == ax::mojom::Role::kListItem; case ax::mojom::Role::kGroup: - return item_role == ax::mojom::Role::kListItem || + return item_role == ax::mojom::Role::kComment || + item_role == ax::mojom::Role::kListItem || item_role == ax::mojom::Role::kMenuItem || item_role == ax::mojom::Role::kMenuItemRadio || item_role == ax::mojom::Role::kTreeItem;
diff --git a/ui/accessibility/ax_node.h b/ui/accessibility/ax_node.h index df8ba0b..6a5f7ed 100644 --- a/ui/accessibility/ax_node.h +++ b/ui/accessibility/ax_node.h
@@ -264,6 +264,9 @@ return data().GetHtmlAttribute(attribute, value); } + // Return the hierarchical level if supported. + base::Optional<int> GetHierarchicalLevel() const; + // PosInSet and SetSize public methods. bool IsOrderedSetItem() const; bool IsOrderedSet() const;
diff --git a/ui/accessibility/ax_node_data.cc b/ui/accessibility/ax_node_data.cc index 0609b7b..3ad412f2 100644 --- a/ui/accessibility/ax_node_data.cc +++ b/ui/accessibility/ax_node_data.cc
@@ -663,9 +663,11 @@ } case ax::mojom::Action::kClearAccessibilityFocus: + case ax::mojom::Action::kCollapse: case ax::mojom::Action::kCustomAction: case ax::mojom::Action::kDecrement: case ax::mojom::Action::kDoDefault: + case ax::mojom::Action::kExpand: case ax::mojom::Action::kGetImageData: case ax::mojom::Action::kHitTest: case ax::mojom::Action::kIncrement:
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc index e7e7c6f..7844c04 100644 --- a/ui/accessibility/ax_tree.cc +++ b/ui/accessibility/ax_tree.cc
@@ -565,6 +565,84 @@ const AXTree& tree; }; +struct AXTree::NodeSetSizePosInSetInfo { + NodeSetSizePosInSetInfo() = default; + ~NodeSetSizePosInSetInfo() = default; + + int32_t pos_in_set = 0; + int32_t set_size = 0; + base::Optional<int> lowest_hierarchical_level; +}; + +struct AXTree::OrderedSetContent { + explicit OrderedSetContent(const AXNode* ordered_set = nullptr) + : ordered_set_(ordered_set) {} + ~OrderedSetContent() = default; + + std::vector<const AXNode*> set_items_; + + // Some ordered set items may not be associated with an ordered set. + const AXNode* ordered_set_; +}; + +struct AXTree::OrderedSetItemsMap { + OrderedSetItemsMap() = default; + ~OrderedSetItemsMap() = default; + + // Check if a particular hierarchical level exists in this map. + bool HierarchicalLevelExists(base::Optional<int> level) { + if (items_map_.find(level) == items_map_.end()) + return false; + return true; + } + + // Add the OrderedSetContent to the corresponding hierarchical level in the + // map. + void Add(base::Optional<int> level, + const OrderedSetContent& ordered_set_content) { + if (!HierarchicalLevelExists(level)) + items_map_[level] = std::vector<OrderedSetContent>(); + + items_map_[level].push_back(ordered_set_content); + } + + // Add an ordered set item to the OrderedSetItemsMap given its hierarchical + // level. We always want to append the item to the last OrderedSetContent of + // that hierarchical level, due to the following: + // - The last OrderedSetContent on any level of the items map is in progress + // of being populated. + // - All other OrderedSetContent other than the last one on a level + // represents a complete ordered set and should not be modified. + void AddItemToBack(base::Optional<int> level, const AXNode* item) { + if (!HierarchicalLevelExists(level)) + return; + + std::vector<OrderedSetContent>& sets_list = items_map_[level]; + if (!sets_list.empty()) { + OrderedSetContent& ordered_set_content = sets_list.back(); + ordered_set_content.set_items_.push_back(item); + } + } + + // Retrieve the first OrderedSetContent of the OrderedSetItemsMap. + OrderedSetContent* GetFirstOrderedSetContent() { + if (items_map_.empty()) + return nullptr; + + std::vector<OrderedSetContent>& sets_list = items_map_.begin()->second; + if (sets_list.empty()) + return nullptr; + + return &(sets_list.front()); + } + + // Clears all the content in the map. + void Clear() { items_map_.clear(); } + + // Maps a hierarchical level to a list of OrderedSetContent. + std::map<base::Optional<int32_t>, std::vector<OrderedSetContent>> items_map_; +}; + AXTree::AXTree() { AXNodeData root; root.id = AXNode::kInvalidAXID; @@ -979,8 +1057,8 @@ } } - // Clear list_info_map_ - ordered_set_info_map_.clear(); + // Clears |node_set_size_pos_in_set_info_map_| + node_set_size_pos_in_set_info_map_.clear(); std::vector<AXTreeObserver::Change> changes; changes.reserve(update.nodes.size()); @@ -1831,50 +1909,71 @@ return return_value; } -void AXTree::PopulateOrderedSetItems( +void AXTree::PopulateOrderedSetItemsMap( const AXNode& original_node, const AXNode* ordered_set, - std::vector<const AXNode*>& items_to_be_populated) const { + OrderedSetItemsMap& items_map_to_be_populated) const { // Ignored nodes are not a part of ordered sets. if (original_node.IsIgnored()) return; - // Default hierarchical_level is 0, which represents that no hierarchical - // level was detected on |original_node|. - int original_node_min_level = original_node.GetIntAttribute( - ax::mojom::IntAttribute::kHierarchicalLevel); + // Not all ordered set containers support hierarchical level, but their set + // items may support hierarchical level. For example, container <tree> does + // not support level, but <treeitem> supports level. For ordered sets like + // this, the set container (e.g. <tree>) will take on the min of the levels + // of its direct children(e.g. <treeitem>), if the children's levels are + // defined. + base::Optional<int> ordered_set_min_level = + ordered_set->GetHierarchicalLevel(); - // If we are calling this function on the ordered set container itself, that - // is |original_node| is ordered set, then set |original_node|'s hierarchical - // level to be the min level of |original_node|'s direct children, if the - // child's level is defined. - if (&original_node == ordered_set) { - for (AXNode::UnignoredChildIterator itr = - original_node.UnignoredChildrenBegin(); - itr != original_node.UnignoredChildrenEnd(); ++itr) { - int32_t child_level = - itr->GetIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel); - if (child_level > 0) - original_node_min_level = - original_node_min_level > 0 - ? std::min(child_level, original_node_min_level) - : child_level; + for (AXNode::UnignoredChildIterator child = + ordered_set->UnignoredChildrenBegin(); + child != ordered_set->UnignoredChildrenEnd(); ++child) { + base::Optional<int> child_level = child->GetHierarchicalLevel(); + if (child_level) { + ordered_set_min_level = ordered_set_min_level + ? std::min(child_level, ordered_set_min_level) + : child_level; } } - RecursivelyPopulateOrderedSetItems(original_node, ordered_set, ordered_set, - original_node_min_level, - items_to_be_populated); + RecursivelyPopulateOrderedSetItemsMap(original_node, ordered_set, ordered_set, + ordered_set_min_level, base::nullopt, + items_map_to_be_populated); + + // If after |RecursivelyPopulateOrderedSetItemsMap| call, the corresponding + // level (i.e. ordered_set_min_level) does not exist in + // |items_map_to_be_populated|, and |original_node| equals |ordered_set|, we + // know |original_node| is an empty ordered set and contains no set items. + // However, |original_node| may still have set size attribute, so we still + // want to add this empty set (i.e. original_node/ordered_set) to + // |items_map_to_be_populated|. + if (&original_node == ordered_set && + !items_map_to_be_populated.HierarchicalLevelExists(ordered_set_min_level)) + items_map_to_be_populated.Add(ordered_set_min_level, + OrderedSetContent(&original_node)); } -void AXTree::RecursivelyPopulateOrderedSetItems( +void AXTree::RecursivelyPopulateOrderedSetItemsMap( const AXNode& original_node, const AXNode* ordered_set, const AXNode* local_parent, - int32_t original_node_min_level, - std::vector<const AXNode*>& items_to_be_populated) const { - // Stop searching recursively on node |local_parent| if it turns out to be an - // ordered set whose role matches that of the top level ordered set. + base::Optional<int> ordered_set_min_level, + base::Optional<int> prev_level, + OrderedSetItemsMap& items_map_to_be_populated) const { + // For optimization purpose, we want to only populate set items that are + // direct descendants of |ordered_set|, since we will only be calculating + // PosInSet & SetSize of items of that level. So we skip items on deeper + // levels by stop searching recursively on node |local_parent| that turns out + // to be an ordered set whose role matches that of |ordered_set|. However, + // when we encounter a flattened structure such as the following: + // <div role="tree"> + // <div role="treeitem" aria-level="1"></div> + // <div role="treeitem" aria-level="2"></div> + // <div role="treeitem" aria-level="3"></div> + // </div> + // This optimization won't apply, we will end up populating items from all + // levels. if (ordered_set->data().role == local_parent->data().role && ordered_set != local_parent) return; @@ -1895,7 +1994,9 @@ continue; } - // Add child to |items_to_be_populated| if role matches with the role of + base::Optional<int> curr_level = child->GetHierarchicalLevel(); + + // Add child to |items_map_to_be_populated| if role matches with the role of // |ordered_set|. If role of node is kRadioButton, don't add items of other // roles, even if item role matches the role of |ordered_set|. if (child->data().role == ax::mojom::Role::kComment || @@ -1903,56 +2004,66 @@ child->data().role == ax::mojom::Role::kRadioButton) || (original_node.data().role != ax::mojom::Role::kRadioButton && child->SetRoleMatchesItemRole(ordered_set))) { - int child_level = - child->GetIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel); - - // If the hierarchical level of |child| and the level of |original_node| - // differ, we do not add child to |items_to_be_populated| and we do not - // recurse into |child| and populate its order set item descendants. - // Additionally, as an exception, we always add tab items to the set, - // because according to WAI-ARIA spec, tab does not support hierarchical - // level, while tab's set container tablist supports hierarchical level. - // Due to this, we always assume sibling tabs are always on the same - // level, and always add tab child item to |items_to_be_populated|. + // According to WAI-ARIA spec, some ordered set items do not support + // hierarchical level while its ordered set container does. For example, + // <tab> does not support level, while <tablist> supports level. // https://www.w3.org/WAI/PF/aria/roles#tab // https://www.w3.org/WAI/PF/aria/roles#tablist - if (child_level != original_node_min_level && - child->data().role != ax::mojom::Role::kTab) { - if (child_level < original_node_min_level && - original_node.GetUnignoredParent() == child->GetUnignoredParent()) { - // For a flattened structure, where |original_node| and |child| share - // the same parent, if a decrease in level occurs after - // |original_node| has been examined (i.e. |original_node|'s index - // comes before that of |child|), we stop adding to this set, and stop - // from populating |child|'s other siblings to |items_to_be_populated| - // as well. - if (original_node.GetUnignoredIndexInParent() < - child->GetUnignoredIndexInParent()) - break; + // For this special case, when we add set items (e.g. tab) to + // |items_map_to_be_populated|, set item is placed at the same level as + // its container (e.g. tablist) in |items_map_to_be_populated|. + if (!curr_level && child->GetUnignoredParent() == ordered_set) + curr_level = ordered_set_min_level; - // For a flattened structure, where |original_node| and |child| share - // the same parent, if a decrease in level has been detected before - // |original_node| has been examined (i.e. |original_node|'s index - // comes after that of |child|), then everything previously added to - // items actually belongs to a different set. Clear the items set. - items_to_be_populated.clear(); - } - continue; + // We only add child to |items_map_to_be_populated| if the child set item + // is at the same hierarchical level as |ordered_set|'s level. + if (!items_map_to_be_populated.HierarchicalLevelExists(curr_level)) { + const AXNode* child_ordered_set = + (child->SetRoleMatchesItemRole(ordered_set) && + ordered_set_min_level == curr_level) + ? ordered_set + : nullptr; + items_map_to_be_populated.Add(curr_level, + OrderedSetContent(child_ordered_set)); } - // We only add child to |items_to_be_populated| if the child set item is - // at the same hierarchical level as |original_node|'s level. - items_to_be_populated.push_back(child); + items_map_to_be_populated.AddItemToBack(curr_level, child); } // Recurse if there is a generic container, ignored, or unknown. if (child->IsIgnored() || child->data().role == ax::mojom::Role::kGenericContainer || child->data().role == ax::mojom::Role::kUnknown) { - RecursivelyPopulateOrderedSetItems(original_node, ordered_set, child, - original_node_min_level, - items_to_be_populated); + RecursivelyPopulateOrderedSetItemsMap(original_node, ordered_set, child, + ordered_set_min_level, curr_level, + items_map_to_be_populated); } + + // If |curr_level| goes up one level from |prev_level|, which indicates + // the ordered set of |prev_level| is closed, we add a new OrderedSetContent + // on the previous level of |items_map_to_be_populated| to signify this. + // Consider the example below: + // <div role="tree"> + // <div role="treeitem" aria-level="1"></div> + // <!--- set1-level2 --> + // <div role="treeitem" aria-level="2"></div> + // <div role="treeitem" aria-level="2"></div> <--|prev_level| + // <div role="treeitem" aria-level="1" id="item2-level1"> <--|curr_level| + // </div> + // <!--- set2-level2 --> + // <div role="treeitem" aria-level="2"></div> + // <div role="treeitem" aria-level="2"></div> + // </div> + // |prev_level| is on the last item of "set1-level2" and |curr_level| is on + // "item2-level1". Since |curr_level| is up one level from |prev_level|, we + // already completed adding all items from "set1-level2" to + // |items_map_to_be_populated|. So we close up "set1-level2" by adding a new + // OrderedSetContent to level 2. When |curr_level| ends up on the items of + // "set2-level2" next, it has a fresh new set to be populated. + if (child->SetRoleMatchesItemRole(ordered_set) && curr_level < prev_level) + items_map_to_be_populated.Add(prev_level, OrderedSetContent()); + + prev_level = curr_level; } } @@ -1962,143 +2073,162 @@ void AXTree::ComputeSetSizePosInSetAndCache(const AXNode& node, const AXNode* ordered_set) { DCHECK(ordered_set); - std::vector<const AXNode*> items; - // Find all items within ordered_set and add to vector. - PopulateOrderedSetItems(node, ordered_set, items); + + // Set items role::kComment and role::kRadioButton are special cases and do + // not necessarily need to be contained in an ordered set. + if (node.data().role != ax::mojom::Role::kComment && + node.data().role != ax::mojom::Role::kRadioButton && + !node.SetRoleMatchesItemRole(ordered_set) && !IsSetLike(node.data().role)) + return; + + OrderedSetItemsMap items_map_to_be_populated; + + // Find all items within ordered_set and add to |items_map_to_be_populated|. + PopulateOrderedSetItemsMap(node, ordered_set, items_map_to_be_populated); // If ordered_set role is kPopUpButton and it wraps a kMenuListPopUp, then we // would like it to inherit the SetSize from the kMenuListPopUp it wraps. To // do this, we treat the kMenuListPopUp as the ordered_set and eventually // assign its SetSize value to the kPopUpButton. - if ((node.data().role == ax::mojom::Role::kPopUpButton) && - (items.size() != 0)) { + if (node.data().role == ax::mojom::Role::kPopUpButton) { // kPopUpButtons are only allowed to contain one kMenuListPopUp. // The single element is guaranteed to be a kMenuListPopUp because that is // the only item role that matches the ordered set role of kPopUpButton. // Please see AXNode::SetRoleMatchesItemRole for more details. - DCHECK(items.size() == 1); - const AXNode* menu_list_popup = items[0]; - items.clear(); - PopulateOrderedSetItems(node, menu_list_popup, items); - } - - // Keep track of the number of elements ordered_set has. - int32_t num_elements = 0; - // Necessary for calculating set_size. - int32_t largest_assigned_set_size = 0; - - // Compute pos_in_set_values. - for (size_t i = 0; i < items.size(); ++i) { - const AXNode* item = items[i]; - ordered_set_info_map_[item->id()] = OrderedSetInfo(); - int32_t pos_in_set_value = 0; - int hierarchical_level = - item->GetIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel); - - pos_in_set_value = num_elements + 1; - - // Check if item has a valid kPosInSet assignment, which takes precedence - // over previous assignment. Invalid assignments are decreasing or - // duplicates, and should be ignored. - pos_in_set_value = - std::max(pos_in_set_value, - item->GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); - - // If level is specified, use author-provided value, if present. - if (hierarchical_level != 0 && - item->HasIntAttribute(ax::mojom::IntAttribute::kPosInSet)) { - pos_in_set_value = - item->GetIntAttribute(ax::mojom::IntAttribute::kPosInSet); - } - - // Assign pos_in_set and update role counts. - ordered_set_info_map_[item->id()].pos_in_set = pos_in_set_value; - num_elements = pos_in_set_value; - - // Check if kSetSize is assigned and update if it's the largest assigned - // kSetSize. - if (item->HasIntAttribute(ax::mojom::IntAttribute::kSetSize)) - largest_assigned_set_size = - std::max(largest_assigned_set_size, - item->GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); - } - - // Compute set_size value. - // The SetSize of an ordered set (and all of its items) is the maximum of the - // following candidate values: - // 1. The number of elements in the ordered set. - // 2. The Largest assigned SetSize in the ordered set. - // 3. The SetSize assigned within the ordered set. - - // Set to 0 if ordered_set has no kSetSize attribute. - int32_t ordered_set_candidate = - ordered_set->GetIntAttribute(ax::mojom::IntAttribute::kSetSize); - - int32_t set_size_value = std::max( - std::max(num_elements, largest_assigned_set_size), ordered_set_candidate); - - // Assign set_size to ordered_set. - // Must meet one of two conditions: - // 1. Node role matches ordered set role. - // 2. The node that calculations were called on is the ordered_set. - if (node.SetRoleMatchesItemRole(ordered_set) || ordered_set == &node) { - auto ordered_set_info_result = - ordered_set_info_map_.find(ordered_set->id()); - int hierarchical_level = - node.GetIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel); - // If ordered_set is not in the cache, assign it a new set_size. - if (ordered_set_info_result == ordered_set_info_map_.end()) { - ordered_set_info_map_[ordered_set->id()] = OrderedSetInfo(); - ordered_set_info_map_[ordered_set->id()].set_size = set_size_value; - ordered_set_info_map_[ordered_set->id()].lowest_hierarchical_level = - hierarchical_level; - } else { - OrderedSetInfo ordered_set_info = ordered_set_info_result->second; - if (ordered_set_info.lowest_hierarchical_level > hierarchical_level) { - ordered_set_info.set_size = set_size_value; - ordered_set_info.lowest_hierarchical_level = hierarchical_level; + OrderedSetContent* set_content = + items_map_to_be_populated.GetFirstOrderedSetContent(); + if (set_content && set_content->set_items_.size() == 1) { + const AXNode* menu_list_popup = set_content->set_items_.front(); + if (menu_list_popup->data().role == ax::mojom::Role::kMenuListPopup) { + items_map_to_be_populated.Clear(); + PopulateOrderedSetItemsMap(node, menu_list_popup, + items_map_to_be_populated); + set_content = items_map_to_be_populated.GetFirstOrderedSetContent(); + // Replace |set_content|'s ordered set container with |node| + // (Role::kPopUpButton), which acts as the set container for nodes with + // Role::kMenuListOptions (children of |menu_list_popup|). + if (set_content) + set_content->ordered_set_ = &node; } } } - // Assign set_size to items. - for (size_t j = 0; j < items.size(); ++j) { - const AXNode* item = items[j]; - int hierarchical_level = - item->GetIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel); - // If level is specified, use author-provided value, if present. - if (hierarchical_level != 0 && - item->HasIntAttribute(ax::mojom::IntAttribute::kSetSize)) - ordered_set_info_map_[item->id()].set_size = - item->GetIntAttribute(ax::mojom::IntAttribute::kSetSize); - else - ordered_set_info_map_[item->id()].set_size = set_size_value; + // Iterate over all items from OrderedSetItemsMap to compute and cache each + // ordered set item's PosInSet and SetSize and corresponding ordered set + // container's SetSize. + for (auto element : items_map_to_be_populated.items_map_) { + for (const OrderedSetContent& ordered_set_content : element.second) { + ComputeSetSizePosInSetAndCacheHelper(ordered_set_content); + } } } -// Returns the pos_in_set of item. Looks in ordered_set_info_map_ for cached -// value. Calculates pos_in_set and set_size for item (and all other items in -// the same ordered set) if no value is present in the cache. -// This function is guaranteed to be only called on nodes that can hold -// pos_in_set values, minimizing the size of the cache. +void AXTree::ComputeSetSizePosInSetAndCacheHelper( + const OrderedSetContent& ordered_set_content) { + // Keep track of number of items in the set. + int32_t num_elements = 0; + // Keep track of largest ordered set item's |aria-setsize| attribute value. + int32_t max_item_set_size_from_attribute = 0; + + for (const AXNode* item : ordered_set_content.set_items_) { + // |item|'s PosInSet value is the maximum of accumulated number of + // elements count and the value from its |aria-posinset| attribute. + int32_t pos_in_set_value = + std::max(num_elements + 1, + item->GetIntAttribute(ax::mojom::IntAttribute::kPosInSet)); + + // For |item| that has defined hierarchical level and |aria-posinset| + // attribute, the attribute value takes precedence. + // Note: According to WAI-ARIA spec, items that support + // |aria-posinset| do not necessarily support hierarchical level. + if (item->GetHierarchicalLevel() && + item->HasIntAttribute(ax::mojom::IntAttribute::kPosInSet)) + pos_in_set_value = + item->GetIntAttribute(ax::mojom::IntAttribute::kPosInSet); + + num_elements = pos_in_set_value; + + // Cache computed PosInSet value for |item|. + node_set_size_pos_in_set_info_map_[item->id()] = NodeSetSizePosInSetInfo(); + node_set_size_pos_in_set_info_map_[item->id()].pos_in_set = + pos_in_set_value; + + // Track the largest set size for this OrderedSetContent. + max_item_set_size_from_attribute = + std::max(max_item_set_size_from_attribute, + item->GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + } // End of iterating over each item in |ordered_set_content|. + + // The SetSize of an ordered set (and all of its items) is the maximum of + // the following values: + // 1. The number of elements in the ordered set. + // 2. The largest item set size from |aria-setsize| attribute. + // 3. The ordered set container's |aria-setsize| attribute value. + int32_t set_size_value = + std::max(num_elements, max_item_set_size_from_attribute); + + // Cache the hierarchical level and set size of |ordered_set_content|'s set + // container, if the container exists. + if (const AXNode* ordered_set = ordered_set_content.ordered_set_) { + set_size_value = std::max( + set_size_value, + ordered_set->GetIntAttribute(ax::mojom::IntAttribute::kSetSize)); + + // Cache |ordered_set|'s hierarchical level. + base::Optional<int> ordered_set_level = ordered_set->GetHierarchicalLevel(); + if (node_set_size_pos_in_set_info_map_.find(ordered_set->id()) == + node_set_size_pos_in_set_info_map_.end()) { + node_set_size_pos_in_set_info_map_[ordered_set->id()] = + NodeSetSizePosInSetInfo(); + node_set_size_pos_in_set_info_map_[ordered_set->id()] + .lowest_hierarchical_level = ordered_set_level; + } else if (node_set_size_pos_in_set_info_map_[ordered_set->id()] + .lowest_hierarchical_level > ordered_set_level) { + node_set_size_pos_in_set_info_map_[ordered_set->id()] + .lowest_hierarchical_level = ordered_set_level; + } + // Cache |ordered_set|'s set size. + node_set_size_pos_in_set_info_map_[ordered_set->id()].set_size = + set_size_value; + } + + // Cache the set size of |ordered_set_content|'s set items. + for (const AXNode* item : ordered_set_content.set_items_) { + // If item's hierarchical level and |aria-setsize| attribute are specified, + // the item's |aria-setsize| value takes precedence. + if (item->GetHierarchicalLevel() && + item->HasIntAttribute(ax::mojom::IntAttribute::kSetSize)) + node_set_size_pos_in_set_info_map_[item->id()].set_size = + item->GetIntAttribute(ax::mojom::IntAttribute::kSetSize); + else + node_set_size_pos_in_set_info_map_[item->id()].set_size = set_size_value; + } // End of iterating over each item in |ordered_set_content|. +} + +// Returns the pos_in_set of item. Looks in |node_set_size_pos_in_set_info_map_| +// for cached value. Calculates pos_in_set and set_size for item (and all other +// items in the same ordered set) if no value is present in the cache. This +// function is guaranteed to be only called on nodes that can hold pos_in_set +// values, minimizing the size of the cache. int32_t AXTree::GetPosInSet(const AXNode& node, const AXNode* ordered_set) { // If item's id is not in the cache, compute it. - if (ordered_set_info_map_.find(node.id()) == ordered_set_info_map_.end()) + if (node_set_size_pos_in_set_info_map_.find(node.id()) == + node_set_size_pos_in_set_info_map_.end()) ComputeSetSizePosInSetAndCache(node, ordered_set); - return ordered_set_info_map_[node.id()].pos_in_set; + return node_set_size_pos_in_set_info_map_[node.id()].pos_in_set; } // Returns the set_size of node. node could be an ordered set or an item. -// Looks in ordered_set_info_map_ for cached value. Calculates pos_inset_set -// and set_size for all nodes in same ordered set if no value is present in the -// cache. -// This function is guaranteed to be only called on nodes that can hold -// set_size values, minimizing the size of the cache. +// Looks in |node_set_size_pos_in_set_info_map_| for cached value. Calculates +// pos_in_set and set_size for all nodes in same ordered set if no value is +// present in the cache. This function is guaranteed to be only called on nodes +// that can hold set_size values, minimizing the size of the cache. int32_t AXTree::GetSetSize(const AXNode& node, const AXNode* ordered_set) { // If node's id is not in the cache, compute it. - if (ordered_set_info_map_.find(node.id()) == ordered_set_info_map_.end()) + if (node_set_size_pos_in_set_info_map_.find(node.id()) == + node_set_size_pos_in_set_info_map_.end()) ComputeSetSizePosInSetAndCache(node, ordered_set); - return ordered_set_info_map_[node.id()].set_size; + return node_set_size_pos_in_set_info_map_[node.id()].set_size; } AXTree::Selection AXTree::GetUnignoredSelection() const {
diff --git a/ui/accessibility/ax_tree.h b/ui/accessibility/ax_tree.h index 3544570..3bbbe0c 100644 --- a/ui/accessibility/ax_tree.h +++ b/ui/accessibility/ax_tree.h
@@ -142,15 +142,15 @@ // conflict with positive-numbered node IDs from tree sources. int32_t GetNextNegativeInternalNodeId(); - // Returns the pos_in_set of node. Looks in ordered_set_info_map_ for cached - // value. Calculates pos_in_set and set_size for node (and all other nodes in - // the same ordered set) if no value is present in the cache. + // Returns the pos_in_set of node. Looks in node_set_size_pos_in_set_info_map_ + // for cached value. Calculates pos_in_set and set_size for node (and all + // other nodes in the same ordered set) if no value is present in the cache. // This function is guaranteed to be only called on nodes that can hold // pos_in_set values, minimizing the size of the cache. int32_t GetPosInSet(const AXNode& node, const AXNode* ordered_set) override; - // Returns the set_size of node. Looks in ordered_set_info_map_ for cached - // value. Calculates pos_inset_set and set_size for node (and all other nodes - // in the same ordered set) if no value is present in the cache. + // Returns the set_size of node. Looks in node_set_size_pos_in_set_info_map_ + // for cached value. Calculates pos_inset_set and set_size for node (and all + // other nodes in the same ordered set) if no value is present in the cache. // This function is guaranteed to be only called on nodes that can hold // set_size values, minimizing the size of the cache. int32_t GetSetSize(const AXNode& node, const AXNode* ordered_set) override; @@ -323,43 +323,53 @@ bool enable_extra_mac_nodes_ = false; // Contains pos_in_set and set_size data for an AXNode. - struct OrderedSetInfo { - int32_t pos_in_set; - int32_t set_size; - int32_t lowest_hierarchical_level; - OrderedSetInfo() : pos_in_set(0), set_size(0) {} - ~OrderedSetInfo() {} - }; + struct NodeSetSizePosInSetInfo; - // Populates ordered set items vector with all items associated with + // Represents the content of an ordered set which includes the ordered set + // items and the ordered set container if it exists. + struct OrderedSetContent; + + // Maps a particular hierarchical level to a list of OrderedSetContents. + // Represents all ordered set items/container on a particular hierarchical + // level. + struct OrderedSetItemsMap; + + // Populates |items_map_to_be_populated| with all items associated with // |original_node| and within |ordered_set|. Only items whose roles match the // role of the |ordered_set| will be added. - void PopulateOrderedSetItems( + void PopulateOrderedSetItemsMap( const AXNode& original_node, const AXNode* ordered_set, - std::vector<const AXNode*>& items_to_be_populated) const; + OrderedSetItemsMap& items_map_to_be_populated) const; - // Helper function for recursively populating ordered sets items vector with + // Helper function for recursively populating ordered sets items map with // all items associated with |original_node| and |ordered_set|. |local_parent| // tracks the recursively passed in child nodes of |ordered_set|. - void RecursivelyPopulateOrderedSetItems( + void RecursivelyPopulateOrderedSetItemsMap( const AXNode& original_node, const AXNode* ordered_set, const AXNode* local_parent, - int32_t original_node_min_level, - std::vector<const AXNode*>& items_to_be_populated) const; + base::Optional<int> ordered_set_min_level, + base::Optional<int> prev_level, + OrderedSetItemsMap& items_map_to_be_populated) const; - // Helper for GetPosInSet and GetSetSize. Computes the pos_in_set and set_size - // values of all items in ordered_set and caches those values. + // Computes the pos_in_set and set_size values of all items in ordered_set and + // caches those values. Called by GetPosInSet and GetSetSize. void ComputeSetSizePosInSetAndCache(const AXNode& node, const AXNode* ordered_set); + // Helper for ComputeSetSizePosInSetAndCache. Computes and caches the + // pos_in_set and set_size values for a given OrderedSetContent. + void ComputeSetSizePosInSetAndCacheHelper( + const OrderedSetContent& ordered_set_content); + // Map from node ID to OrderedSetInfo. // Item-like and ordered-set-like objects will map to populated OrderedSetInfo // objects. // All other objects will map to default-constructed OrderedSetInfo objects. // Invalidated every time the tree is updated. - mutable std::unordered_map<int32_t, OrderedSetInfo> ordered_set_info_map_; + mutable std::unordered_map<int32_t, NodeSetSizePosInSetInfo> + node_set_size_pos_in_set_info_map_; // AXTree owns pointers so copying is non-trivial. DISALLOW_COPY_AND_ASSIGN(AXTree);
diff --git a/ui/android/java/res/color/chip_background_color.xml b/ui/android/java/res/color/chip_background_color.xml index 22f701e..59d3918 100644 --- a/ui/android/java/res/color/chip_background_color.xml +++ b/ui/android/java/res/color/chip_background_color.xml
@@ -17,5 +17,14 @@ <item android:alpha="@dimen/default_focused_alpha" android:color="@color/modern_grey_800" android:state_focused="true" /> + <item android:alpha="@dimen/chip_background_selected_hover_alpha" + android:color="@color/filled_button_bg_color" + android:state_focused="true" + android:state_hovered="true" /> + <item android:alpha="@dimen/chip_background_selected_hover_focused_alpha" + android:color="@color/filled_button_bg_color" + android:state_focused="true" + android:state_hovered="true" + android:state_selected="true" /> <item android:color="@android:color/transparent" /> </selector>
diff --git a/ui/android/java/res/color/chip_text_color.xml b/ui/android/java/res/color/chip_text_color.xml index a0cd575a..2e0a1dd 100644 --- a/ui/android/java/res/color/chip_text_color.xml +++ b/ui/android/java/res/color/chip_text_color.xml
@@ -9,7 +9,7 @@ android:color="@color/chip_text_color_selected" android:state_selected="true" android:state_enabled="false"/> <item android:alpha="@dimen/default_disabled_alpha" - android:color="@color/chip_text_color_default" android:state_enabled="false" /> + android:color="@color/default_chip_assistive_text_color" android:state_enabled="false" /> <item android:color="@color/chip_text_color_selected" android:state_selected="true" /> - <item android:color="@color/chip_text_color_default" /> + <item android:color="@color/default_chip_assistive_text_color" /> </selector>
diff --git a/ui/android/java/res/color/chip_text_color_secondary.xml b/ui/android/java/res/color/chip_text_color_secondary.xml index cfc719b..7483e90 100644 --- a/ui/android/java/res/color/chip_text_color_secondary.xml +++ b/ui/android/java/res/color/chip_text_color_secondary.xml
@@ -9,7 +9,7 @@ android:color="@color/chip_text_color_selected" android:state_selected="true" android:state_enabled="false" /> <item android:alpha="@dimen/default_disabled_alpha" - android:color="@color/chip_text_color_secondary_default" android:state_enabled="false" /> + android:color="@color/default_chip_assistive_text_color_secondary" android:state_enabled="false" /> <item android:color="@color/chip_text_color_selected" android:state_selected="true" /> - <item android:color="@color/chip_text_color_secondary_default" /> + <item android:color="@color/default_chip_assistive_text_color_secondary" /> </selector>
diff --git a/ui/android/java/res/values-night/colors.xml b/ui/android/java/res/values-night/colors.xml index 1cbc75f..416b09d 100644 --- a/ui/android/java/res/values-night/colors.xml +++ b/ui/android/java/res/values-night/colors.xml
@@ -44,6 +44,7 @@ <color name="chip_text_color_selected">@color/default_text_color_dark</color> <color name="chip_background_color_disabled">@color/modern_grey_300_alpha_38</color> <color name="chip_ripple_color_default">@android:color/white</color> + <color name="default_chip_outline_color">@color/default_chip_outline_color_dark</color> <!-- CircularProgressView colors --> <color name="circular_progress_inner_background_color_small">@color/modern_blue_300</color>
diff --git a/ui/android/java/res/values/colors.xml b/ui/android/java/res/values/colors.xml index 2ee63933..5f451ef 100644 --- a/ui/android/java/res/values/colors.xml +++ b/ui/android/java/res/values/colors.xml
@@ -88,11 +88,12 @@ <color name="ripple_color_blue">@color/modern_blue_600</color> <!-- Chip colors --> - <color name="chip_text_color_default">@color/default_text_color</color> + <color name="default_chip_assistive_text_color">@color/default_text_color</color> <color name="chip_text_color_selected">@color/modern_blue_700</color> - <color name="chip_text_color_secondary_default">@color/default_text_color_secondary</color> + <color name="default_chip_assistive_text_color_secondary">@color/default_text_color_secondary</color> <color name="chip_background_color_disabled">@color/modern_grey_100_alpha_38</color> <color name="chip_ripple_color_default">@color/modern_grey_800</color> + <color name="default_chip_outline_color" tools:ignore="UnusedResources">@color/default_chip_outline_color_light</color> <!-- CircularProgressView colors --> <color name="circular_progress_inner_background_color_small" tools:ignore="UnusedResources">@color/modern_grey_300</color>
diff --git a/ui/android/java/res/values/dimens.xml b/ui/android/java/res/values/dimens.xml index 0016766..2bdd147f 100644 --- a/ui/android/java/res/values/dimens.xml +++ b/ui/android/java/res/values/dimens.xml
@@ -39,6 +39,8 @@ <dimen name="chip_bg_vertical_inset">8dp</dimen> <item name="chip_background_selected_focused_alpha" format="float" type="dimen">0.12</item> <item name="chip_background_selected_alpha" format="float" type="dimen">0.06</item> + <item name="chip_background_selected_hover_alpha" format="float" type="dimen">0.10</item> + <item name="chip_background_selected_hover_focused_alpha" format="float" type="dimen">0.12</item> <dimen name="chip_icon_size">20dp</dimen> <!-- Dropdown default measures -->
diff --git a/ui/android/java/res/values/semantic_colors.xml b/ui/android/java/res/values/semantic_colors.xml index ee4d5e2..49f6f01 100644 --- a/ui/android/java/res/values/semantic_colors.xml +++ b/ui/android/java/res/values/semantic_colors.xml
@@ -59,6 +59,10 @@ <color name="divider_bg_color_dark">@color/modern_grey_300</color> <color name="divider_bg_color_light">@color/white_alpha_12</color> + <!-- Chip Colors --> + <color name="default_chip_outline_color_light">@color/modern_grey_300</color> + <color name="default_chip_outline_color_dark">@color/modern_grey_700</color> + <!-- Colors used for Widgets (checkboxes, switches, buttons, etc)--> <color name="control_active_color_light" tools:ignore="UnusedResources">@color/modern_blue_600</color> <color name="control_active_color_dark" tools:ignore="UnusedResources">@color/modern_blue_300</color>
diff --git a/ui/base/ui_base_features.cc b/ui/base/ui_base_features.cc index 441bfd9..52d6c6f 100644 --- a/ui/base/ui_base_features.cc +++ b/ui/base/ui_base_features.cc
@@ -79,7 +79,7 @@ // Enables compositor threaded scrollbar scrolling by mapping pointer events to // gesture events. const base::Feature kCompositorThreadedScrollbarScrolling = { - "CompositorThreadedScrollbarScrolling", base::FEATURE_DISABLED_BY_DEFAULT}; + "CompositorThreadedScrollbarScrolling", base::FEATURE_ENABLED_BY_DEFAULT}; // Enables the use of a touch fling curve that is based on the behavior of // native apps on Windows.
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table.js b/ui/file_manager/file_manager/foreground/js/ui/file_table.js index 409b6f6..bd93767 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_table.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
@@ -1147,9 +1147,7 @@ const oldThumbnails = box.querySelectorAll('.thumbnail'); for (let i = 0; i < oldThumbnails.length; i++) { - if (box.contains(oldThumbnails[i])) { - box.removeChild(oldThumbnails[i]); - } + box.removeChild(oldThumbnails[i]); } box.appendChild(thumbnail);
diff --git a/ui/file_manager/file_manager/foreground/js/ui/multi_menu.js b/ui/file_manager/file_manager/foreground/js/ui/multi_menu.js index 352e74b..36d30ee 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/multi_menu.js +++ b/ui/file_manager/file_manager/foreground/js/ui/multi_menu.js
@@ -489,6 +489,9 @@ return; } + // Track element for which menu was opened so that command events are + // dispatched to the correct element. + this.menu.contextElement = this; this.menu.show(opt_mousePos); this.setAttribute('menu-shown', '');
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js index 0c02d24..76228df 100644 --- a/ui/file_manager/integration_tests/file_manager/quick_view.js +++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -5,6 +5,23 @@ (() => { /** + * The name of the UMA emitted to track how Quick View is opened. + * @const {string} + */ + const QuickViewUmaWayToOpenHistogramName = 'FileBrowser.QuickView.WayToOpen'; + + /** + * The UMA's enumeration values (must be consistent with enums.xml, + * previously histograms.xml). + * @enum {number} + */ + const QuickViewUmaWayToOpenHistogramValues = { + CONTEXT_MENU: 0, + SPACE_KEY: 1, + SELECTION_MENU: 2, + }; + + /** * Waits for Quick View dialog to be closed. * * @param {string} appId Files app windowId. @@ -67,6 +84,41 @@ } /** + * Opens the Quick View dialog by right clicking on the file |name| and + * using the "Get Info" command from the context menu. + * + * @param {string} appId Files app windowId. + * @param {string} name File name. + */ + async function openQuickViewViaContextMenu(appId, name) { + // Right-click the file in the file-list. + const query = '#file-list [file-name="' + name + '"]'; + await remoteCall.waitAndRightClick(appId, query); + + // Wait because WebUI Menu ignores the following click if it happens in + // <200ms from the previous click. + await wait(300); + + // Click the file-list context menu "Get info" command. + const getInfoMenuItem = '#file-context-menu:not([hidden]) ' + + ' [command="#get-info"]:not([hidden])'; + await remoteCall.waitAndClickElement(appId, getInfoMenuItem); + + // Check: the Quick View dialog should be shown. + const caller = getCaller(); + await repeatUntil(async () => { + const query = ['#quick-view', '#dialog[open]']; + const elements = await remoteCall.callRemoteTestUtil( + 'deepQueryAllElements', appId, [query, ['display']]); + const haveElements = Array.isArray(elements) && elements.length !== 0; + if (!haveElements || elements[0].styles.display !== 'block') { + return pending(caller, 'Waiting for Quick View to open.'); + } + return true; + }); + } + + /** * Opens the Quick View dialog with given file |names|. The files must be * present and check-selected in the Files app file list. * @@ -216,39 +268,14 @@ const appId = await setupAndWaitUntilReady( RootPath.DOWNLOADS, BASIC_LOCAL_ENTRY_SET, []); - // Select hello.txt in the file list. + // Select the file in the file list. chrome.test.assertTrue( !!await remoteCall.callRemoteTestUtil( 'selectFile', appId, [ENTRIES.hello.nameText]), 'selectFile failed'); - // Right-click the file in the file-list. - const query = '#file-list [file-name="hello.txt"]'; - chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil( - 'fakeMouseRightClick', appId, [query])); - - // Wait because WebUI Menu ignores the following click if it happens in - // <200ms from the previous click. - await wait(300); - - // Click the file-list context menu "Get info" command. - const getInfoMenuItem = '#file-context-menu:not([hidden]) ' + - ' [command="#get-info"]:not([hidden])'; - chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil( - 'fakeMouseClick', appId, [getInfoMenuItem])); - - // Check: the Quick View dialog should be shown. - const caller = getCaller(); - await repeatUntil(async () => { - const query = ['#quick-view', '#dialog[open]']; - const elements = await remoteCall.callRemoteTestUtil( - 'deepQueryAllElements', appId, [query, ['display']]); - const haveElements = Array.isArray(elements) && elements.length !== 0; - if (!haveElements || elements[0].styles.display !== 'block') { - return pending(caller, 'Waiting for Quick View to open.'); - } - return true; - }); + // Check: clicking the context menu "Get Info" should open Quick View. + await openQuickViewViaContextMenu(appId, ENTRIES.hello.nameText); }; /** @@ -264,33 +291,8 @@ const ctrlA = ['#file-list', 'a', true, false, false]; await remoteCall.fakeKeyDown(appId, ...ctrlA); - // Right-click the file in the file-list. - const query = '#file-list [file-name="hello.txt"]'; - chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil( - 'fakeMouseRightClick', appId, [query])); - - // Wait because WebUI Menu ignores the following click if it happens in - // <200ms from the previous click. - await wait(300); - - // Click the file-list context menu "Get info" command. - const getInfoMenuItem = '#file-context-menu:not([hidden]) ' + - ' [command="#get-info"]:not([hidden])'; - chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil( - 'fakeMouseClick', appId, [getInfoMenuItem])); - - // Check: the Quick View dialog should be shown. - const caller = getCaller(); - await repeatUntil(async () => { - const query = ['#quick-view', '#dialog[open]']; - const elements = await remoteCall.callRemoteTestUtil( - 'deepQueryAllElements', appId, [query, ['display']]); - const haveElements = Array.isArray(elements) && elements.length !== 0; - if (!haveElements || elements[0].styles.display !== 'block') { - return pending(caller, 'Waiting for Quick View to open.'); - } - return true; - }); + // Check: clicking the context menu "Get Info" should open Quick View. + await openQuickViewViaContextMenu(appId, ENTRIES.hello.nameText); }; /** @@ -2452,4 +2454,266 @@ const quickViewDeleteButton = ['#quick-view', '#delete-button[hidden]']; await remoteCall.waitForElement(appId, quickViewDeleteButton); }; + + /** + * Tests that the correct WayToOpen UMA histogram is recorded when opening + * a single file via Quick View using "Get Info" from the context menu. + */ + testcase.openQuickViewUmaViaContextMenu = async () => { + // Open Files app on Downloads containing BASIC_LOCAL_ENTRY_SET. + const appId = await setupAndWaitUntilReady( + RootPath.DOWNLOADS, BASIC_LOCAL_ENTRY_SET, []); + + // Record the UMA value's bucket count before we use the menu option. + const contextMenuUMAValueBeforeOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.CONTEXT_MENU); + + const selectionMenuUMAValueBeforeOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.SELECTION_MENU); + + // Open Quick View via the entry context menu. + await openQuickViewViaContextMenu(appId, ENTRIES.hello.nameText); + + // Check: the context menu histogram should increment by 1. + const contextMenuUMAValueAfterOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.CONTEXT_MENU); + + const selectionMenuUMAValueAfterOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.SELECTION_MENU); + + chrome.test.assertEq( + contextMenuUMAValueAfterOpening, contextMenuUMAValueBeforeOpening + 1); + chrome.test.assertEq( + selectionMenuUMAValueAfterOpening, selectionMenuUMAValueBeforeOpening); + }; + + /** + * Tests that the correct WayToOpen UMA histogram is recorded when using + * Quick View in check-select mode using "Get Info" from the context + * menu. + */ + testcase.openQuickViewUmaForCheckSelectViaContextMenu = async () => { + // Open Files app on Downloads containing BASIC_LOCAL_ENTRY_SET. + const appId = await setupAndWaitUntilReady( + RootPath.DOWNLOADS, BASIC_LOCAL_ENTRY_SET, []); + + // Record the UMA value's bucket count before we use the menu option. + const contextMenuUMAValueBeforeOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.CONTEXT_MENU); + + const selectionMenuUMAValueBeforeOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.SELECTION_MENU); + + // Ctrl+A to select all files in the file-list. + const ctrlA = ['#file-list', 'a', true, false, false]; + await remoteCall.fakeKeyDown(appId, ...ctrlA); + + // Open Quick View using the context menu. + await openQuickViewViaContextMenu(appId, ENTRIES.hello.nameText); + + // Check: the context menu histogram should increment by 1. + const contextMenuUMAValueAfterOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.CONTEXT_MENU); + + const selectionMenuUMAValueAfterOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.SELECTION_MENU); + + chrome.test.assertEq( + contextMenuUMAValueAfterOpening, contextMenuUMAValueBeforeOpening + 1); + chrome.test.assertEq( + selectionMenuUMAValueAfterOpening, selectionMenuUMAValueBeforeOpening); + }; + + /** + * Tests that the correct WayToOpen UMA histogram is recorded when using + * Quick View in check-select mode using "Get Info" from the Selection + * menu. + */ + testcase.openQuickViewUmaViaSelectionMenu = async () => { + // Open Files app on Downloads containing BASIC_LOCAL_ENTRY_SET. + const appId = await setupAndWaitUntilReady( + RootPath.DOWNLOADS, BASIC_LOCAL_ENTRY_SET, []); + + // Ctrl+A to select all files in the file-list. + const ctrlA = ['#file-list', 'a', true, false, false]; + await remoteCall.fakeKeyDown(appId, ...ctrlA); + + // Wait until the selection menu is visible. + function checkElementsDisplayFlex(elements) { + chrome.test.assertTrue(Array.isArray(elements)); + if (elements.length == 0 || elements[0].styles.display !== 'flex') { + return pending(caller, 'Waiting for Selection Menu to be visible.'); + } + } + + await repeatUntil(async () => { + const elements = ['#selection-menu-button']; + return checkElementsDisplayFlex(await remoteCall.callRemoteTestUtil( + 'deepQueryAllElements', appId, [elements, ['display']])); + }); + + // Record the UMA value's bucket count before we use the menu option. + const contextMenuUMAValueBeforeOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.CONTEXT_MENU); + + const selectionMenuUMAValueBeforeOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.SELECTION_MENU); + + // Click the Selection Menu button. Using fakeMouseClick causes + // the focus to switch from file-list such that crbug.com/1046997 + // cannot be tested, use simulateUiClick() instead. + await remoteCall.simulateUiClick( + appId, '#selection-menu-button:not([hidden])'); + + // Wait because WebUI Menu ignores the following click if it happens in + // <200ms from the previous click. + await wait(300); + + // Click the file-list context menu "Get info" command. + await remoteCall.simulateUiClick( + appId, + '#file-context-menu:not([hidden]) [command="#get-info"]:not([hidden])'); + + // Check: the Quick View dialog should be shown. + const caller = getCaller(); + await repeatUntil(async () => { + const query = ['#quick-view', '#dialog[open]']; + const elements = await remoteCall.callRemoteTestUtil( + 'deepQueryAllElements', appId, [query, ['display']]); + const haveElements = Array.isArray(elements) && elements.length !== 0; + if (!haveElements || elements[0].styles.display !== 'block') { + return pending(caller, 'Waiting for Quick View to open.'); + } + return true; + }); + + // Check: the context menu histogram should increment by 1. + const contextMenuUMAValueAfterOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.CONTEXT_MENU); + + const selectionMenuUMAValueAfterOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.SELECTION_MENU); + + chrome.test.assertEq( + contextMenuUMAValueAfterOpening, contextMenuUMAValueBeforeOpening); + chrome.test.assertEq( + selectionMenuUMAValueAfterOpening, + selectionMenuUMAValueBeforeOpening + 1); + }; + + /** + * Tests that the correct WayToOpen UMA histogram is recorded when using + * Quick View in check-select mode using "Get Info" from the context + * menu opened via keyboard tabbing (not mouse). + */ + testcase.openQuickViewUmaViaSelectionMenuKeyboard = async () => { + const caller = getCaller(); + + // Open Files app on Downloads containing BASIC_LOCAL_ENTRY_SET. + const appId = await setupAndWaitUntilReady( + RootPath.DOWNLOADS, BASIC_LOCAL_ENTRY_SET, []); + + // Ctrl+A to select all files in the file-list. + const ctrlA = ['#file-list', 'a', true, false, false]; + await remoteCall.fakeKeyDown(appId, ...ctrlA); + + // Wait until the selection menu is visible. + function checkElementsDisplayFlex(elements) { + chrome.test.assertTrue(Array.isArray(elements)); + if (elements.length == 0 || elements[0].styles.display !== 'flex') { + return pending(caller, 'Waiting for Selection Menu to be visible.'); + } + } + + await repeatUntil(async () => { + const elements = ['#selection-menu-button']; + return checkElementsDisplayFlex(await remoteCall.callRemoteTestUtil( + 'deepQueryAllElements', appId, [elements, ['display']])); + }); + + // Record the UMA value's bucket count before we use the menu option. + const contextMenuUMAValueBeforeOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.CONTEXT_MENU); + + const selectionMenuUMAValueBeforeOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.SELECTION_MENU); + + // Tab to the Selection Menu button. + await repeatUntil(async () => { + const result = await sendTestMessage({name: 'dispatchTabKey'}); + chrome.test.assertEq( + result, 'tabKeyDispatched', 'Tab key dispatch failure'); + + const element = + await remoteCall.callRemoteTestUtil('getActiveElement', appId, []); + + if (element && element.attributes['id'] === 'selection-menu-button') { + return true; + } + return pending( + caller, 'Waiting for selection-menu-button to become active'); + }); + + // Key down to the "Get Info" command. + await repeatUntil(async () => { + const keyDown = + ['#selection-menu-button', 'ArrowDown', false, false, false]; + chrome.test.assertTrue( + await remoteCall.callRemoteTestUtil('fakeKeyDown', appId, keyDown)); + + const element = + await remoteCall.callRemoteTestUtil('getActiveElement', appId, []); + + if (element && element.attributes['command'] === '#get-info') { + return true; + } + return pending(caller, 'Waiting for get-info command to become active'); + }); + + // Select the "Get Info" command using the Enter key. + const keyEnter = ['#selection-menu-button', 'Enter', false, false, false]; + chrome.test.assertTrue( + await remoteCall.callRemoteTestUtil('fakeKeyDown', appId, keyEnter)); + + // Check: the Quick View dialog should be shown. + await repeatUntil(async () => { + const query = ['#quick-view', '#dialog[open]']; + const elements = await remoteCall.callRemoteTestUtil( + 'deepQueryAllElements', appId, [query, ['display']]); + const haveElements = Array.isArray(elements) && elements.length !== 0; + if (!haveElements || elements[0].styles.display !== 'block') { + return pending(caller, 'Waiting for Quick View to open.'); + } + return true; + }); + + // Check: the context menu histogram should increment by 1. + const contextMenuUMAValueAfterOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.CONTEXT_MENU); + + const selectionMenuUMAValueAfterOpening = await getHistogramCount( + QuickViewUmaWayToOpenHistogramName, + QuickViewUmaWayToOpenHistogramValues.SELECTION_MENU); + + chrome.test.assertEq( + contextMenuUMAValueAfterOpening, contextMenuUMAValueBeforeOpening); + chrome.test.assertEq( + selectionMenuUMAValueAfterOpening, + selectionMenuUMAValueBeforeOpening + 1); + }; })();
diff --git a/ui/ozone/platform/drm/gpu/drm_framebuffer.cc b/ui/ozone/platform/drm/gpu/drm_framebuffer.cc index 55e85eda..772786b4 100644 --- a/ui/ozone/platform/drm/gpu/drm_framebuffer.cc +++ b/ui/ozone/platform/drm/gpu/drm_framebuffer.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "ui/gfx/buffer_format_util.h" #include "ui/gfx/linux/drm_util_linux.h" #include "ui/gfx/linux/gbm_buffer.h" #include "ui/ozone/platform/drm/common/drm_util.h" @@ -28,8 +29,18 @@ modifiers[i] = params.modifier; } + const auto fourcc_format = GetBufferFormatFromFourCCFormat(params.format); + const uint32_t opaque_format = + GetFourCCFormatForOpaqueFramebuffer(fourcc_format); + // Intel Display Controller won't support AR/B30 framebuffers, only XR/B30, + // but that doesn't matter because anyway those two bits of alpha are useless; + // use the opaque directly in this case. + const bool force_opaque = AlphaBitsForBufferFormat(fourcc_format) == 2; + + const auto drm_format = force_opaque ? opaque_format : params.format; + uint32_t framebuffer_id = 0; - if (!drm_device->AddFramebuffer2(params.width, params.height, params.format, + if (!drm_device->AddFramebuffer2(params.width, params.height, drm_format, params.handles, params.strides, params.offsets, modifiers, &framebuffer_id, params.flags)) { @@ -37,10 +48,8 @@ return nullptr; } - uint32_t opaque_format = GetFourCCFormatForOpaqueFramebuffer( - GetBufferFormatFromFourCCFormat(params.format)); uint32_t opaque_framebuffer_id = 0; - if (opaque_format != params.format && + if (opaque_format != drm_format && !drm_device->AddFramebuffer2(params.width, params.height, opaque_format, params.handles, params.strides, params.offsets, modifiers, @@ -51,9 +60,9 @@ } return base::MakeRefCounted<DrmFramebuffer>( - std::move(drm_device), framebuffer_id, params.format, - opaque_framebuffer_id, opaque_format, params.modifier, - params.preferred_modifiers, gfx::Size(params.width, params.height)); + std::move(drm_device), framebuffer_id, drm_format, opaque_framebuffer_id, + opaque_format, params.modifier, params.preferred_modifiers, + gfx::Size(params.width, params.height)); } // static
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc index d80c24cc..efe4556 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
@@ -18,7 +18,9 @@ #include "ui/display/types/gamma_ramp_rgb_entry.h" #include "ui/gfx/gpu_fence.h" #include "ui/gfx/gpu_fence_handle.h" +#include "ui/gfx/linux/drm_util_linux.h" #include "ui/gfx/linux/gbm_buffer.h" +#include "ui/ozone/platform/drm/common/drm_util.h" #include "ui/ozone/platform/drm/gpu/crtc_controller.h" #include "ui/ozone/platform/drm/gpu/drm_framebuffer.h" #include "ui/ozone/platform/drm/gpu/drm_gpu_util.h" @@ -937,6 +939,29 @@ property_names_, use_atomic_)); } +// Verifies that formats with 2 bits of alpha decay to opaques for AddFB2(). +TEST_P(HardwareDisplayPlaneManagerTest, ForceOpaqueFormatsForAddFramebuffer) { + InitializeDrmState(/*crtc_count=*/3, /*planes_per_crtc=*/1); + + struct { + uint32_t input_fourcc; // FourCC presented to AddFramebuffer. + uint32_t used_fourcc; // FourCC expected to be used in AddFramebuffer. + } kFourCCFormats[] = { + {DRM_FORMAT_ABGR2101010, DRM_FORMAT_XBGR2101010}, + // TODO(mcasas): use AR30 when the CLs in crrev.com/c/2068722 have landed. + {DRM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB2101010}, + }; + + for (const auto& format_pair : kFourCCFormats) { + scoped_refptr<ui::DrmFramebuffer> drm_fb = + CreateBufferWithFormat(kDefaultBufferSize, format_pair.input_fourcc); + + EXPECT_EQ(drm_fb->framebuffer_pixel_format(), format_pair.used_fourcc); + EXPECT_EQ(drm_fb->opaque_framebuffer_pixel_format(), + format_pair.used_fourcc); + } +} + INSTANTIATE_TEST_SUITE_P(All, HardwareDisplayPlaneManagerTest, testing::Values(false, true));
diff --git a/ui/ozone/platform/drm/gpu/mock_gbm_device.cc b/ui/ozone/platform/drm/gpu/mock_gbm_device.cc index 354d830d..ef45c47 100644 --- a/ui/ozone/platform/drm/gpu/mock_gbm_device.cc +++ b/ui/ozone/platform/drm/gpu/mock_gbm_device.cc
@@ -121,6 +121,8 @@ switch (format) { case DRM_FORMAT_XRGB8888: case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_ABGR2101010: bytes_per_pixel = 4; break; case DRM_FORMAT_NV12:
diff --git a/ui/strings/translations/ui_strings_en-GB.xtb b/ui/strings/translations/ui_strings_en-GB.xtb index f83f38c..12404efe 100644 --- a/ui/strings/translations/ui_strings_en-GB.xtb +++ b/ui/strings/translations/ui_strings_en-GB.xtb
@@ -102,7 +102,7 @@ <translation id="3842239759367498783">Continue reading from your mobile device <ph name="TITLE" /></translation> <translation id="385051799172605136">Back</translation> <translation id="3889424535448813030">Right Arrow</translation> -<translation id="3892641579809465218">Internal Display</translation> +<translation id="3892641579809465218">Built-in display</translation> <translation id="3897092660631435901">Menu</translation> <translation id="3909791450649380159">Cu&t</translation> <translation id="3990502903496589789">Right Edge</translation> @@ -253,4 +253,4 @@ <translation id="932327136139879170">Home</translation> <translation id="944069440740578670">Unread notifications</translation> <translation id="974545358917229949">Displaying <ph name="RESULT_COUNT" /> results for <ph name="QUERY" /></translation> -</translationbundle> \ No newline at end of file +</translationbundle>
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd index 2ce4a26..1a6d683f 100644 --- a/ui/strings/ui_strings.grd +++ b/ui/strings/ui_strings.grd
@@ -1019,7 +1019,7 @@ Unknown Display </message> <message name="IDS_DISPLAY_NAME_INTERNAL" desc="The name used for internal displays, which is shown in the display settings."> - Internal Display + Built-in display </message> <!-- Crostini app context menu item names, dialog message and button strings -->
diff --git a/ui/strings/ui_strings_grd/IDS_DISPLAY_NAME_INTERNAL.png.sha1 b/ui/strings/ui_strings_grd/IDS_DISPLAY_NAME_INTERNAL.png.sha1 new file mode 100644 index 0000000..b57ef8ea --- /dev/null +++ b/ui/strings/ui_strings_grd/IDS_DISPLAY_NAME_INTERNAL.png.sha1
@@ -0,0 +1 @@ +7fc580944eb5da2b860990438606d22fd6f90311 \ No newline at end of file
diff --git a/ui/views/border.cc b/ui/views/border.cc index c0fc682..3561fcf3 100644 --- a/ui/views/border.cc +++ b/ui/views/border.cc
@@ -168,7 +168,9 @@ ExtraInsetsBorder::ExtraInsetsBorder(std::unique_ptr<Border> border, const gfx::Insets& insets) - : border_(std::move(border)), extra_insets_(insets) {} + : Border(border->color()), + border_(std::move(border)), + extra_insets_(insets) {} void ExtraInsetsBorder::Paint(const View& view, gfx::Canvas* canvas) { border_->Paint(view, canvas);
diff --git a/ui/views/border_unittest.cc b/ui/views/border_unittest.cc index 5439d485c..77232b0 100644 --- a/ui/views/border_unittest.cc +++ b/ui/views/border_unittest.cc
@@ -230,7 +230,7 @@ } TEST_F(BorderTest, EmptyBorder) { - const gfx::Insets kInsets(1, 2, 3, 4); + constexpr gfx::Insets kInsets(1, 2, 3, 4); std::unique_ptr<Border> border(CreateEmptyBorder( kInsets.top(), kInsets.left(), kInsets.bottom(), kInsets.right())); @@ -245,8 +245,8 @@ } TEST_F(BorderTest, SolidSidedBorder) { - const SkColor kBorderColor = SK_ColorMAGENTA; - const gfx::Insets kInsets(1, 2, 3, 4); + constexpr SkColor kBorderColor = SK_ColorMAGENTA; + constexpr gfx::Insets kInsets(1, 2, 3, 4); std::unique_ptr<Border> border( CreateSolidSidedBorder(kInsets.top(), kInsets.left(), kInsets.bottom(), @@ -263,12 +263,12 @@ bounds.Inset(border->GetInsets()); ASSERT_EQ(1u, mock->draw_paint_calls().size()); - EXPECT_EQ(kBorderColor, mock->draw_paint_calls()[0].getColor()); + EXPECT_EQ(kBorderColor, mock->draw_paint_calls().front().getColor()); EXPECT_EQ(gfx::RectF(bounds), gfx::SkRectToRectF(mock->last_clip_bounds())); } TEST_F(BorderTest, BorderPainter) { - const gfx::Insets kInsets(1, 2, 3, 4); + constexpr gfx::Insets kInsets(1, 2, 3, 4); std::unique_ptr<MockPainter> painter(new MockPainter()); MockPainter* painter_ptr = painter.get(); @@ -284,4 +284,39 @@ EXPECT_EQ(view_->size(), painter_ptr->given_size()); } +TEST_F(BorderTest, ExtraInsetsBorder) { + constexpr SkColor kBorderColor = SK_ColorMAGENTA; + constexpr int kOriginalInset = 3; + std::unique_ptr<Border> border = + CreateSolidBorder(kOriginalInset, kBorderColor); + constexpr gfx::Insets kOriginalInsets(kOriginalInset); + EXPECT_EQ(kOriginalInsets.size(), border->GetMinimumSize()); + EXPECT_EQ(kOriginalInsets, border->GetInsets()); + EXPECT_EQ(kBorderColor, border->color()); + + constexpr int kExtraInset = 2; + constexpr gfx::Insets kExtraInsets(kExtraInset); + std::unique_ptr<Border> extra_insets_border = + CreatePaddedBorder(std::move(border), kExtraInsets); + constexpr gfx::Insets kTotalInsets(kOriginalInset + kExtraInset); + EXPECT_EQ(kTotalInsets.size(), extra_insets_border->GetMinimumSize()); + EXPECT_EQ(kTotalInsets, extra_insets_border->GetInsets()); + EXPECT_EQ(kBorderColor, extra_insets_border->color()); + + extra_insets_border->Paint(*view_, canvas_.get()); + + std::unique_ptr<MockCanvas> mock = DrawIntoMockCanvas(); + std::vector<MockCanvas::DrawRectCall> draw_rect_calls = + mock->draw_rect_calls(); + + gfx::Rect bounds = view_->GetLocalBounds(); + // We only use the wrapped border's insets for painting the border. The extra + // insets of the ExtraInsetsBorder are applied within the wrapped border. + bounds.Inset(extra_insets_border->GetInsets() - gfx::Insets(kExtraInset)); + + ASSERT_EQ(1u, mock->draw_paint_calls().size()); + EXPECT_EQ(kBorderColor, mock->draw_paint_calls().front().getColor()); + EXPECT_EQ(gfx::RectF(bounds), gfx::SkRectToRectF(mock->last_clip_bounds())); +} + } // namespace views
diff --git a/ui/views/controls/button/image_button_factory.cc b/ui/views/controls/button/image_button_factory.cc index a7977b8..17134c64 100644 --- a/ui/views/controls/button/image_button_factory.cc +++ b/ui/views/controls/button/image_button_factory.cc
@@ -13,8 +13,39 @@ #include "ui/views/layout/layout_provider.h" #include "ui/views/painter.h" +namespace { + +class ColorTrackingVectorImageButton : public views::ImageButton { + public: + ColorTrackingVectorImageButton(views::ButtonListener* listener, + const gfx::VectorIcon& icon) + : ImageButton(listener), icon_(icon) {} + + // views::ImageButton: + void OnThemeChanged() override { + ImageButton::OnThemeChanged(); + const SkColor color = GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_DefaultIconColor); + views::SetImageFromVectorIconWithColor(this, icon_, color); + } + + private: + const gfx::VectorIcon& icon_; +}; + +} // namespace + namespace views { +std::unique_ptr<ImageButton> CreateVectorImageButtonWithNativeTheme( + ButtonListener* listener, + const gfx::VectorIcon& icon) { + auto button = + std::make_unique<ColorTrackingVectorImageButton>(listener, icon); + ConfigureVectorImageButton(button.get()); + return button; +} + std::unique_ptr<ImageButton> CreateVectorImageButton(ButtonListener* listener) { auto button = std::make_unique<ImageButton>(listener); ConfigureVectorImageButton(button.get()); @@ -37,13 +68,6 @@ LayoutProvider::Get()->GetInsetsMetric(INSETS_VECTOR_IMAGE_BUTTON))); } -void SetImageFromVectorIcon(ImageButton* button, const gfx::VectorIcon& icon) { - SetImageFromVectorIconWithColor( - button, icon, - ui::NativeTheme::GetInstanceForNativeUi()->GetSystemColor( - ui::NativeTheme::kColorId_DefaultIconColor)); -} - void SetImageFromVectorIcon(ImageButton* button, const gfx::VectorIcon& icon, SkColor related_text_color) {
diff --git a/ui/views/controls/button/image_button_factory.h b/ui/views/controls/button/image_button_factory.h index 4423812..a267048 100644 --- a/ui/views/controls/button/image_button_factory.h +++ b/ui/views/controls/button/image_button_factory.h
@@ -19,6 +19,12 @@ class ImageButton; class ToggleImageButton; +// Creates an ImageButton with an ink drop and a centered image built from a +// vector icon that tracks color changes in NativeTheme. +VIEWS_EXPORT std::unique_ptr<ImageButton> +CreateVectorImageButtonWithNativeTheme(ButtonListener* listener, + const gfx::VectorIcon& icon); + // Creates an ImageButton with an ink drop and a centered image in preparation // for applying a vector icon with SetImageFromVectorIcon below. VIEWS_EXPORT std::unique_ptr<ImageButton> CreateVectorImageButton( @@ -35,11 +41,6 @@ VIEWS_EXPORT void ConfigureVectorImageButton(ImageButton* button); // Sets images on |button| for STATE_NORMAL and STATE_DISABLED from the given -// vector icon using the default color from the current NativeTheme. -VIEWS_EXPORT void SetImageFromVectorIcon(ImageButton* button, - const gfx::VectorIcon& icon); - -// Sets images on |button| for STATE_NORMAL and STATE_DISABLED from the given // vector icon and color. |related_text_color| is normally the main text color // used in the parent view, and the actual color used is derived from that. Call // again to update the button if |related_text_color| is changing.
diff --git a/ui/views/controls/button/image_button_factory_unittest.cc b/ui/views/controls/button/image_button_factory_unittest.cc index 6d022452d..db907074 100644 --- a/ui/views/controls/button/image_button_factory_unittest.cc +++ b/ui/views/controls/button/image_button_factory_unittest.cc
@@ -33,11 +33,53 @@ button->GetInkDropBaseColor()); } -TEST_F(ImageButtonFactoryTest, SetImageFromVectorIcon_Default) { - auto button = CreateVectorImageButton(nullptr); - SetImageFromVectorIcon(button.get(), vector_icons::kCloseRoundedIcon); - EXPECT_EQ(button->GetNativeTheme()->GetSystemColor( +class ImageButtonFactoryWidgetTest : public ViewsTestBase { + public: + ImageButtonFactoryWidgetTest() = default; + ~ImageButtonFactoryWidgetTest() override = default; + + void SetUp() override { + ViewsTestBase::SetUp(); + + // Create a widget so that buttons can get access to their NativeTheme + // instance. + widget_ = std::make_unique<Widget>(); + Widget::InitParams params = + CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS); + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.bounds = gfx::Rect(0, 0, 650, 650); + widget_->Init(std::move(params)); + widget_->Show(); + } + + void TearDown() override { + button_.reset(); + widget_.reset(); + ViewsTestBase::TearDown(); + } + + ImageButton* AddImageButton(std::unique_ptr<ImageButton> button) { + button_ = std::move(button); + widget_->SetContentsView(button_.get()); + return button_.get(); + } + + protected: + Widget* widget() { return widget_.get(); } + ImageButton* button() { return button_.get(); } + + private: + std::unique_ptr<Widget> widget_; + std::unique_ptr<ImageButton> button_; + + DISALLOW_COPY_AND_ASSIGN(ImageButtonFactoryWidgetTest); +}; + +TEST_F(ImageButtonFactoryWidgetTest, CreateVectorImageButtonWithNativeTheme) { + AddImageButton(CreateVectorImageButtonWithNativeTheme( + nullptr, vector_icons::kCloseRoundedIcon)); + EXPECT_EQ(button()->GetNativeTheme()->GetSystemColor( ui::NativeTheme::kColorId_DefaultIconColor), - button->GetInkDropBaseColor()); + button()->GetInkDropBaseColor()); } } // namespace views
diff --git a/ui/views/controls/button/label_button_label.cc b/ui/views/controls/button/label_button_label.cc index 81c7c3d..7e40c80e 100644 --- a/ui/views/controls/button/label_button_label.cc +++ b/ui/views/controls/button/label_button_label.cc
@@ -13,14 +13,12 @@ void LabelButtonLabel::SetDisabledColor(SkColor color) { requested_disabled_color_ = color; - disabled_color_set_ = true; if (!GetEnabled()) Label::SetEnabledColor(color); } void LabelButtonLabel::SetEnabledColor(SkColor color) { requested_enabled_color_ = color; - enabled_color_set_ = true; if (GetEnabled()) Label::SetEnabledColor(color); } @@ -35,9 +33,9 @@ } void LabelButtonLabel::SetColorForEnableState() { - if (GetEnabled() ? enabled_color_set_ : disabled_color_set_) { - Label::SetEnabledColor(GetEnabled() ? requested_enabled_color_ - : requested_disabled_color_); + if (GetEnabled() ? requested_enabled_color_ : requested_disabled_color_) { + Label::SetEnabledColor(GetEnabled() ? *requested_enabled_color_ + : *requested_disabled_color_); } else { int style = GetEnabled() ? style::STYLE_PRIMARY : style::STYLE_DISABLED; Label::SetEnabledColor(style::GetColor(*this, GetTextContext(), style));
diff --git a/ui/views/controls/button/label_button_label.h b/ui/views/controls/button/label_button_label.h index 088811e..49d88b6 100644 --- a/ui/views/controls/button/label_button_label.h +++ b/ui/views/controls/button/label_button_label.h
@@ -7,8 +7,10 @@ #include "base/bind.h" #include "base/macros.h" +#include "base/optional.h" #include "base/strings/string16.h" #include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/color_palette.h" #include "ui/views/controls/label.h" #include "ui/views/views_export.h" @@ -36,10 +38,8 @@ void OnEnabledChanged(); void SetColorForEnableState(); - SkColor requested_disabled_color_ = SK_ColorRED; - SkColor requested_enabled_color_ = SK_ColorRED; - bool disabled_color_set_ = false; - bool enabled_color_set_ = false; + base::Optional<SkColor> requested_disabled_color_; + base::Optional<SkColor> requested_enabled_color_; PropertyChangedSubscription enabled_changed_subscription_ = AddEnabledChangedCallback( base::BindRepeating(&LabelButtonLabel::OnEnabledChanged,
diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc index 59cd610..59639cba0 100644 --- a/ui/views/controls/label.cc +++ b/ui/views/controls/label.cc
@@ -955,19 +955,7 @@ full_text_->SetCursorEnabled(false); full_text_->SetWordWrapBehavior(gfx::TRUNCATE_LONG_WORDS); - elide_behavior_ = gfx::ELIDE_TAIL; - stored_selection_range_ = gfx::Range::InvalidRange(); - enabled_color_set_ = background_color_set_ = false; - selection_text_color_set_ = selection_background_color_set_ = false; - subpixel_rendering_enabled_ = true; - auto_color_readability_enabled_ = true; - multi_line_ = false; - max_lines_ = 0; UpdateColorsFromTheme(); - handles_tooltips_ = true; - collapse_when_hidden_ = false; - fixed_width_ = 0; - max_width_ = 0; SetText(text); // Only selectable labels will get requests to show the context menu, due to
diff --git a/ui/views/controls/label.h b/ui/views/controls/label.h index d6e1ad6..4cb533c 100644 --- a/ui/views/controls/label.h +++ b/ui/views/controls/label.h
@@ -11,6 +11,7 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "ui/base/models/simple_menu_model.h" +#include "ui/gfx/color_palette.h" #include "ui/gfx/render_text.h" #include "ui/gfx/text_constants.h" #include "ui/views/context_menu_controller.h" @@ -384,34 +385,34 @@ // Persists the current selection range between the calls to // ClearDisplayText() and MaybeBuildDisplayText(). Holds an InvalidRange when // not in use. - mutable gfx::Range stored_selection_range_; + mutable gfx::Range stored_selection_range_ = gfx::Range::InvalidRange(); - SkColor requested_enabled_color_ = SK_ColorRED; - SkColor actual_enabled_color_ = SK_ColorRED; - SkColor background_color_ = SK_ColorRED; - SkColor requested_selection_text_color_ = SK_ColorRED; - SkColor actual_selection_text_color_ = SK_ColorRED; - SkColor selection_background_color_ = SK_ColorRED; + SkColor requested_enabled_color_ = gfx::kPlaceholderColor; + SkColor actual_enabled_color_ = gfx::kPlaceholderColor; + SkColor background_color_ = gfx::kPlaceholderColor; + SkColor requested_selection_text_color_ = gfx::kPlaceholderColor; + SkColor actual_selection_text_color_ = gfx::kPlaceholderColor; + SkColor selection_background_color_ = gfx::kPlaceholderColor; // Set to true once the corresponding setter is invoked. - bool enabled_color_set_; - bool background_color_set_; - bool selection_text_color_set_; - bool selection_background_color_set_; + bool enabled_color_set_ = false; + bool background_color_set_ = false; + bool selection_text_color_set_ = false; + bool selection_background_color_set_ = false; - gfx::ElideBehavior elide_behavior_; + gfx::ElideBehavior elide_behavior_ = gfx::ELIDE_TAIL; - bool subpixel_rendering_enabled_; - bool auto_color_readability_enabled_; + bool subpixel_rendering_enabled_ = true; + bool auto_color_readability_enabled_ = true; // TODO(mukai): remove |multi_line_| when all RenderText can render multiline. - bool multi_line_; - int max_lines_; + bool multi_line_ = false; + int max_lines_ = 0; base::string16 tooltip_text_; - bool handles_tooltips_; + bool handles_tooltips_ = true; // Whether to collapse the label when it's not visible. - bool collapse_when_hidden_; - int fixed_width_; - int max_width_; + bool collapse_when_hidden_ = false; + int fixed_width_ = 0; + int max_width_ = 0; std::unique_ptr<SelectionController> selection_controller_;
diff --git a/ui/views/examples/examples_main.cc b/ui/views/examples/examples_main.cc index 2d9d46d..cb5c6812 100644 --- a/ui/views/examples/examples_main.cc +++ b/ui/views/examples/examples_main.cc
@@ -95,6 +95,10 @@ // values from TestTimeouts. This ensures they're properly initialized. TestTimeouts::Initialize(); + // Viz depends on the task environment to correctly tear down. + base::test::TaskEnvironment task_environment( + base::test::TaskEnvironment::MainThreadType::UI); + // The ContextFactory must exist before any Compositors are created. viz::HostFrameSinkManager host_frame_sink_manager; viz::ServerSharedBitmapManager shared_bitmap_manager; @@ -105,9 +109,6 @@ &host_frame_sink_manager, &frame_sink_manager); context_factory->set_use_test_surface(false); - base::test::TaskEnvironment task_environment( - base::test::TaskEnvironment::MainThreadType::UI); - base::i18n::InitializeICU(); ui::RegisterPathProvider();
diff --git a/url/BUILD.gn b/url/BUILD.gn index 5d6b897..197d31a 100644 --- a/url/BUILD.gn +++ b/url/BUILD.gn
@@ -265,6 +265,7 @@ ":gurl_jni_headers", "//base:base_java", "//base:base_java_test_support", + "//base:jni_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/junit",
diff --git a/url/android/java/src/org/chromium/url/GURL.java b/url/android/java/src/org/chromium/url/GURL.java index 4ff64797..b26d012 100644 --- a/url/android/java/src/org/chromium/url/GURL.java +++ b/url/android/java/src/org/chromium/url/GURL.java
@@ -5,7 +5,11 @@ package org.chromium.url; import android.os.SystemClock; +import android.text.TextUtils; +import androidx.annotation.Nullable; + +import org.chromium.base.Log; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.MainDex; @@ -27,6 +31,10 @@ @JNINamespace("url") @MainDex public class GURL { + private static final String TAG = "GURL"; + /* package */ static final int SERIALIZER_VERSION = 1; + /* package */ static final char SERIALIZER_DELIMITER = '\0'; + // TODO(https://crbug.com/1039841): Right now we return a new String with each request for a // GURL component other than the spec itself. Should we cache return Strings (as // WeakReference?) so that callers can share String memory? @@ -46,6 +54,12 @@ * @param uri The string URI representation to parse into a GURL. */ public GURL(String uri) { + // Avoid a jni hop (and initializing the native library) for empty GURLs. + if (TextUtils.isEmpty(uri)) { + mSpec = ""; + mParsed = Parsed.createEmpty(); + return; + } ensureNativeInitializedForGURL(); GURLJni.get().init(uri, this); } @@ -207,6 +221,64 @@ return mSpec.equals(((GURL) other).mSpec); } + /** + * Serialize a GURL to a String, to be used with {@link GURL#deserialize(String)}. + * + * Note that a serialized GURL should only be used internally to Chrome, and should *never* be + * used if coming from an untrusted source. + * + * @return A serialzed GURL. + */ + public final String serialize() { + StringBuilder builder = new StringBuilder(); + builder.append(SERIALIZER_VERSION).append(SERIALIZER_DELIMITER); + builder.append(mIsValid).append(SERIALIZER_DELIMITER); + builder.append(mParsed.serialize()).append(SERIALIZER_DELIMITER); + builder.append(mSpec); + String serialization = builder.toString(); + return Integer.toString(serialization.length()) + SERIALIZER_DELIMITER + serialization; + } + + /** + * Deserialize a GURL serialized with {@link GURL#serialize()}. + * + * This function should *never* be used on a String coming from an untrusted source. + * + * @return The deserialized GURL (or null if the input is empty). + */ + public static GURL deserialize(@Nullable String gurl) { + try { + if (TextUtils.isEmpty(gurl)) return emptyGURL(); + String[] tokens = gurl.split(Character.toString(SERIALIZER_DELIMITER)); + + // First token MUST always be the length of the serialized data. + String length = tokens[0]; + if (gurl.length() != Integer.parseInt(length) + length.length() + 1) { + throw new IllegalArgumentException("Serialized GURL had the wrong length."); + } + + // Last token MUST always be the original spec - just re-parse the GURL on version + // changes. + String spec = tokens[tokens.length - 1]; + // Special case for empty spec - it won't get its own token. + if (gurl.endsWith(Character.toString(SERIALIZER_DELIMITER))) spec = ""; + + // Second token MUST always be the version number. + int version = Integer.parseInt(tokens[1]); + if (version != SERIALIZER_VERSION) return new GURL(spec); + + boolean isValid = Boolean.parseBoolean(tokens[2]); + Parsed parsed = Parsed.deserialize(tokens, 3); + GURL result = new GURL(); + result.init(spec, isValid, parsed); + return result; + } catch (Exception e) { + // This is unexpected, maybe the storage got corrupted somehow? + Log.w(TAG, "Exception while deserializing a GURL: " + gurl, e); + return emptyGURL(); + } + } + @NativeMethods interface Natives { /**
diff --git a/url/android/java/src/org/chromium/url/Parsed.java b/url/android/java/src/org/chromium/url/Parsed.java index f03f025..f78f8bdf 100644 --- a/url/android/java/src/org/chromium/url/Parsed.java +++ b/url/android/java/src/org/chromium/url/Parsed.java
@@ -34,6 +34,10 @@ private final Parsed mInnerUrl; private final boolean mPotentiallyDanglingMarkup; + /* packaged */ static Parsed createEmpty() { + return new Parsed(0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, false, null); + } + @CalledByNative private Parsed(int schemeBegin, int schemeLength, int usernameBegin, int usernameLength, int passwordBegin, int passwordLength, int hostBegin, int hostLength, int portBegin, @@ -70,6 +74,60 @@ mRefBegin, mRefLength, mPotentiallyDanglingMarkup, inner); } + /* package */ String serialize() { + StringBuilder builder = new StringBuilder(); + builder.append(mSchemeBegin).append(GURL.SERIALIZER_DELIMITER); + builder.append(mSchemeLength).append(GURL.SERIALIZER_DELIMITER); + builder.append(mUsernameBegin).append(GURL.SERIALIZER_DELIMITER); + builder.append(mUsernameLength).append(GURL.SERIALIZER_DELIMITER); + builder.append(mPasswordBegin).append(GURL.SERIALIZER_DELIMITER); + builder.append(mPasswordLength).append(GURL.SERIALIZER_DELIMITER); + builder.append(mHostBegin).append(GURL.SERIALIZER_DELIMITER); + builder.append(mHostLength).append(GURL.SERIALIZER_DELIMITER); + builder.append(mPortBegin).append(GURL.SERIALIZER_DELIMITER); + builder.append(mPortLength).append(GURL.SERIALIZER_DELIMITER); + builder.append(mPathBegin).append(GURL.SERIALIZER_DELIMITER); + builder.append(mPathLength).append(GURL.SERIALIZER_DELIMITER); + builder.append(mQueryBegin).append(GURL.SERIALIZER_DELIMITER); + builder.append(mQueryLength).append(GURL.SERIALIZER_DELIMITER); + builder.append(mRefBegin).append(GURL.SERIALIZER_DELIMITER); + builder.append(mRefLength).append(GURL.SERIALIZER_DELIMITER); + builder.append(mPotentiallyDanglingMarkup).append(GURL.SERIALIZER_DELIMITER); + builder.append(mInnerUrl != null); + if (mInnerUrl != null) { + builder.append(GURL.SERIALIZER_DELIMITER).append(mInnerUrl.serialize()); + } + return builder.toString(); + } + + /* package */ static Parsed deserialize(String[] tokens, int startIndex) { + int schemeBegin = Integer.parseInt(tokens[startIndex++]); + int schemeLength = Integer.parseInt(tokens[startIndex++]); + int usernameBegin = Integer.parseInt(tokens[startIndex++]); + int usernameLength = Integer.parseInt(tokens[startIndex++]); + int passwordBegin = Integer.parseInt(tokens[startIndex++]); + int passwordLength = Integer.parseInt(tokens[startIndex++]); + int hostBegin = Integer.parseInt(tokens[startIndex++]); + int hostLength = Integer.parseInt(tokens[startIndex++]); + int portBegin = Integer.parseInt(tokens[startIndex++]); + int portLength = Integer.parseInt(tokens[startIndex++]); + int pathBegin = Integer.parseInt(tokens[startIndex++]); + int pathLength = Integer.parseInt(tokens[startIndex++]); + int queryBegin = Integer.parseInt(tokens[startIndex++]); + int queryLength = Integer.parseInt(tokens[startIndex++]); + int refBegin = Integer.parseInt(tokens[startIndex++]); + int refLength = Integer.parseInt(tokens[startIndex++]); + boolean potentiallyDanglingMarkup = Boolean.parseBoolean(tokens[startIndex++]); + Parsed innerParsed = null; + if (Boolean.parseBoolean(tokens[startIndex++])) { + innerParsed = Parsed.deserialize(tokens, startIndex); + } + return new Parsed(schemeBegin, schemeLength, usernameBegin, usernameLength, passwordBegin, + passwordLength, hostBegin, hostLength, portBegin, portLength, pathBegin, pathLength, + queryBegin, queryLength, refBegin, refLength, potentiallyDanglingMarkup, + innerParsed); + } + @NativeMethods interface Natives { /**
diff --git a/url/android/native_java_unittests/src/org/chromium/url/GURLJavaTest.java b/url/android/native_java_unittests/src/org/chromium/url/GURLJavaTest.java index db6c3a8..87661b692 100644 --- a/url/android/native_java_unittests/src/org/chromium/url/GURLJavaTest.java +++ b/url/android/native_java_unittests/src/org/chromium/url/GURLJavaTest.java
@@ -4,7 +4,12 @@ package org.chromium.url; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doThrow; + import org.junit.Assert; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNativeJavaTest; @@ -17,14 +22,35 @@ * correctly. */ public class GURLJavaTest { + @Mock + GURL.Natives mGURLMocks; + @CalledByNative - private GURLJavaTest() {} + private GURLJavaTest() { + MockitoAnnotations.initMocks(this); + } @CalledByNative public GURL createGURL(String uri) { return new GURL(uri); } + private void deepAssertEquals(GURL expected, GURL actual) { + Assert.assertEquals(expected, actual); + Assert.assertEquals(expected.getScheme(), actual.getScheme()); + Assert.assertEquals(expected.getUsername(), actual.getUsername()); + Assert.assertEquals(expected.getPassword(), actual.getPassword()); + Assert.assertEquals(expected.getHost(), actual.getHost()); + Assert.assertEquals(expected.getPort(), actual.getPort()); + Assert.assertEquals(expected.getPath(), actual.getPath()); + Assert.assertEquals(expected.getQuery(), actual.getQuery()); + Assert.assertEquals(expected.getRef(), actual.getRef()); + } + + private String prependLengthToSerialization(String serialization) { + return Integer.toString(serialization.length()) + GURL.SERIALIZER_DELIMITER + serialization; + } + // Equivalent of GURLTest.Components @CalledByNativeJavaTest @SuppressWarnings(value = "AuthLeak") @@ -61,6 +87,10 @@ // Equivalent of GURLTest.Empty @CalledByNativeJavaTest public void testEmpty() { + GURLJni.TEST_HOOKS.setInstanceForTesting(mGURLMocks); + doThrow(new RuntimeException("Should not need to parse empty URL")) + .when(mGURLMocks) + .init(any(), any()); GURL url = new GURL(""); Assert.assertFalse(url.isValid()); Assert.assertEquals("", url.getSpec()); @@ -73,6 +103,7 @@ Assert.assertEquals("", url.getPath()); Assert.assertEquals("", url.getQuery()); Assert.assertEquals("", url.getRef()); + GURLJni.TEST_HOOKS.setInstanceForTesting(null); } // Test that GURL and URI return the correct Origin. @@ -106,4 +137,117 @@ Assert.assertEquals("", url.getQuery()); Assert.assertEquals("", url.getRef()); } + + @CalledByNativeJavaTest + @SuppressWarnings(value = "AuthLeak") + public void testSerialization() { + GURL cases[] = { + // Common Standard URLs. + new GURL("https://www.google.com"), + new GURL("https://www.google.com/"), + new GURL("https://www.google.com/maps.htm"), + new GURL("https://www.google.com/maps/"), + new GURL("https://www.google.com/index.html"), + new GURL("https://www.google.com/index.html?q=maps"), + new GURL("https://www.google.com/index.html#maps/"), + new GURL("https://foo:bar@www.google.com/maps.htm"), + new GURL("https://www.google.com/maps/au/index.html"), + new GURL("https://www.google.com/maps/au/north"), + new GURL("https://www.google.com/maps/au/north/"), + new GURL("https://www.google.com/maps/au/index.html?q=maps#fragment/"), + new GURL("http://www.google.com:8000/maps/au/index.html?q=maps#fragment/"), + new GURL("https://www.google.com/maps/au/north/?q=maps#fragment"), + new GURL("https://www.google.com/maps/au/north?q=maps#fragment"), + // Less common standard URLs. + new GURL("filesystem:http://www.google.com/temporary/bar.html?baz=22"), + new GURL("file:///temporary/bar.html?baz=22"), + new GURL("ftp://foo/test/index.html"), + new GURL("gopher://foo/test/index.html"), + new GURL("ws://foo/test/index.html"), + // Non-standard, + new GURL("chrome://foo/bar.html"), + new GURL("httpa://foo/test/index.html"), + new GURL("blob:https://foo.bar/test/index.html"), + new GURL("about:blank"), + new GURL("data:foobar"), + new GURL("scheme:opaque_data"), + // Invalid URLs. + new GURL("foobar"), + // URLs containing the delimiter + new GURL("https://www.google.ca/" + GURL.SERIALIZER_DELIMITER + ",foo"), + new GURL("https://www.foo" + GURL.SERIALIZER_DELIMITER + "bar.com"), + }; + + GURLJni.TEST_HOOKS.setInstanceForTesting(mGURLMocks); + doThrow(new RuntimeException("Should not re-initialize for deserialization when the " + + "version hasn't changed.")) + .when(mGURLMocks) + .init(any(), any()); + for (GURL url : cases) { + GURL out = GURL.deserialize(url.serialize()); + deepAssertEquals(url, out); + } + GURLJni.TEST_HOOKS.setInstanceForTesting(null); + } + + /** + * Tests that we re-parse the URL from the spec, which must always be the last token in the + * serialization, if the serialization version differs. + */ + @CalledByNativeJavaTest + public void testSerializationWithVersionSkew() { + GURL url = new GURL("https://www.google.com"); + String serialization = (GURL.SERIALIZER_VERSION + 1) + + ",0,0,0,0,foo,https://url.bad,blah,0,".replace(',', GURL.SERIALIZER_DELIMITER) + + url.getSpec(); + serialization = prependLengthToSerialization(serialization); + GURL out = GURL.deserialize(serialization); + deepAssertEquals(url, out); + } + + /** + * Tests that fields that aren't visible to java code are correctly serialized. + */ + @CalledByNativeJavaTest + public void testSerializationOfPrivateFields() { + String serialization = GURL.SERIALIZER_VERSION + + ",true," + // Outer Parsed. + + "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,false,true," + // Inner Parsed. + + "17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,true,false," + + "chrome://foo/bar.html"; + serialization = serialization.replace(',', GURL.SERIALIZER_DELIMITER); + serialization = prependLengthToSerialization(serialization); + GURL url = GURL.deserialize(serialization); + Assert.assertEquals(url.serialize(), serialization); + } + + /** + * Tests serialized GURL truncated by storage. + */ + @CalledByNativeJavaTest + public void testTruncatedDeserialization() { + String serialization = "123,1,true,1,2,3,4,5,6,7,8,9,10"; + serialization = serialization.replace(',', GURL.SERIALIZER_DELIMITER); + GURL url = GURL.deserialize(serialization); + Assert.assertEquals(url, GURL.emptyGURL()); + } + + /** + * Tests serialized GURL truncated by storage. + */ + @CalledByNativeJavaTest + public void testCorruptedSerializations() { + String serialization = new GURL("https://www.google.ca").serialize(); + // Replace the scheme length (5) with an extra delimiter. + String corruptedParsed = serialization.replace('5', GURL.SERIALIZER_DELIMITER); + GURL url = GURL.deserialize(corruptedParsed); + Assert.assertEquals(GURL.emptyGURL(), url); + + String corruptedVersion = + serialization.replaceFirst(Integer.toString(GURL.SERIALIZER_VERSION), "x"); + url = GURL.deserialize(corruptedVersion); + Assert.assertEquals(GURL.emptyGURL(), url); + } }
diff --git a/weblayer/browser/content_browser_client_impl.cc b/weblayer/browser/content_browser_client_impl.cc index 2745211..942c91a 100644 --- a/weblayer/browser/content_browser_client_impl.cc +++ b/weblayer/browser/content_browser_client_impl.cc
@@ -7,10 +7,13 @@ #include <utility> #include "base/command_line.h" +#include "base/containers/flat_set.h" #include "base/files/file.h" #include "base/files/file_util.h" +#include "base/no_destructor.h" #include "base/path_service.h" #include "base/stl_util.h" +#include "base/strings/string_piece.h" #include "build/build_config.h" #include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/captive_portal/core/buildflags.h" @@ -28,6 +31,7 @@ #include "content/public/browser/network_service_instance.h" #include "content/public/common/content_switches.h" #include "content/public/common/service_names.mojom.h" +#include "content/public/common/url_constants.h" #include "content/public/common/user_agent.h" #include "content/public/common/web_preferences.h" #include "content/public/common/window_container_type.mojom.h" @@ -41,6 +45,7 @@ #include "third_party/blink/public/common/user_agent/user_agent_metadata.h" #include "url/gurl.h" #include "url/origin.h" +#include "url/url_constants.h" #include "weblayer/browser/browser_main_parts_impl.h" #include "weblayer/browser/browser_process.h" #include "weblayer/browser/feature_list_creator.h" @@ -143,6 +148,26 @@ std::make_unique<weblayer::WebLayerSecurityBlockingPageFactory>()); } +#if defined(OS_ANDROID) +// Returns true if |scheme| identifies one that is handled/known by WebLayer. +bool IsHandledScheme(base::StringPiece scheme) { + DCHECK_EQ(scheme, base::ToLowerASCII(scheme)); + static const base::NoDestructor<base::flat_set<base::StringPiece>> + kKnownSchemes(base::flat_set<base::StringPiece>({ + content::kChromeDevToolsScheme, content::kChromeUIScheme, + content::kChromeUIUntrustedScheme, url::kAboutScheme, + url::kBlobScheme, url::kDataScheme, url::kFileScheme, + url::kFileSystemScheme, url::kHttpScheme, url::kHttpsScheme, + url::kJavaScriptScheme, +#if BUILDFLAG(ENABLE_WEBSOCKETS) + url::kWsScheme, url::kWssScheme, +#endif // BUILDFLAG(ENABLE_WEBSOCKETS) + url::kContentScheme, + })); + return kKnownSchemes->contains(scheme); +} +#endif // defined(OS_ANDROID) + } // namespace namespace weblayer { @@ -553,6 +578,9 @@ if (web_contents == nullptr) return true; + if (gurl.is_valid() && IsHandledScheme(gurl.scheme())) + return true; + JNIEnv* env = base::android::AttachCurrentThread(); base::string16 url = base::UTF8ToUTF16(gurl.possibly_invalid_spec());
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationHandler.java b/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationHandler.java index cb72ae62..171d8d02 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationHandler.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationHandler.java
@@ -13,9 +13,6 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - /** * A class that handles navigations that should be transformed to intents. Logic taken primarly from * //android_webview's AwContentsClient.java:sendBrowsingIntent(), with some additional logic @@ -25,25 +22,12 @@ public class ExternalNavigationHandler { private static final String TAG = "ExternalNavHandler"; - static final Pattern BROWSER_URI_SCHEMA = - Pattern.compile("(?i)" // switch on case insensitive matching - + "(" // begin group for schema - + "(?:http|https|file)://" - + "|(?:inline|data|about|chrome|javascript):" - + ")" - + ".*"); - @CalledByNative private static boolean shouldOverrideUrlLoading(TabImpl tab, String url, boolean hasUserGesture, boolean isRedirect, boolean isMainFrame) { - // Check for regular URIs that WebLayer supports by itself. // TODO(blundell): Port over WebViewBrowserActivity's // isSpecializedHandlerAvailable() check that checks whether there's an app for handling // the scheme? - Matcher m = BROWSER_URI_SCHEMA.matcher(url); - if (m.matches()) { - return false; - } if (!hasUserGesture && !isRedirect) { Log.w(TAG, "Denied starting an intent without a user gesture, URI %s", url);